diff options
author | joerg <joerg> | 2008-04-05 02:42:13 +0000 |
---|---|---|
committer | joerg <joerg> | 2008-04-05 02:42:13 +0000 |
commit | ece61d76f151de7b97919cd729fea46d150a21ce (patch) | |
tree | 8d2bc0f20a24dc5247789f1fbfecb62b22cd6b33 /net/libfetch | |
parent | ad772b6f0dfb4e8ed1235ce7b4bb16f76a050d50 (diff) | |
download | pkgsrc-ece61d76f151de7b97919cd729fea46d150a21ce.tar.gz |
Add somewhat ugly, but working directory listening code for FTP.
Note that using glob patterns that match directories can result in
recursive expansion, e.g. with tnftpd.
Diffstat (limited to 'net/libfetch')
-rw-r--r-- | net/libfetch/files/common.h | 4 | ||||
-rw-r--r-- | net/libfetch/files/ftp.c | 87 | ||||
-rw-r--r-- | net/libfetch/files/http.c | 6 |
3 files changed, 72 insertions, 25 deletions
diff --git a/net/libfetch/files/common.h b/net/libfetch/files/common.h index fbdfbbb4483..0ae1f1a1400 100644 --- a/net/libfetch/files/common.h +++ b/net/libfetch/files/common.h @@ -1,4 +1,4 @@ -/* $NetBSD: common.h,v 1.4 2008/04/02 15:33:14 joerg Exp $ */ +/* $NetBSD: common.h,v 1.5 2008/04/05 02:42:13 joerg Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * All rights reserved. @@ -117,7 +117,7 @@ fetchIO *fetchIO_unopen(void *, ssize_t (*)(void *, void *, size_t), */ fetchIO *http_request(struct url *, const char *, struct url_stat *, struct url *, const char *); -fetchIO *ftp_request(struct url *, const char *, +fetchIO *ftp_request(struct url *, const char *, const char *, struct url_stat *, struct url *, const char *); diff --git a/net/libfetch/files/ftp.c b/net/libfetch/files/ftp.c index 179bb0db255..59de42f2d67 100644 --- a/net/libfetch/files/ftp.c +++ b/net/libfetch/files/ftp.c @@ -1,4 +1,4 @@ -/* $NetBSD: ftp.c,v 1.12 2008/04/04 22:37:28 joerg Exp $ */ +/* $NetBSD: ftp.c,v 1.13 2008/04/05 02:42:13 joerg Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * All rights reserved. @@ -210,11 +210,11 @@ ftp_cmd(conn_t *conn, const char *fmt, ...) * Return a pointer to the filename part of a path */ static const char * -ftp_filename(const char *file, int *len, int *type) +ftp_filename(const char *file, int *len, int *type, int subdir) { const char *s; - if ((s = strrchr(file, '/')) == NULL) + if ((s = strrchr(file, '/')) == NULL || subdir) s = file; else s = s + 1; @@ -266,14 +266,16 @@ ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen) * file. */ static int -ftp_cwd(conn_t *conn, const char *file) +ftp_cwd(conn_t *conn, const char *file, int subdir) { const char *beg, *end; char pwd[PATH_MAX]; int e, i, len; /* If no slashes in name, no need to change dirs. */ - if ((end = strrchr(file, '/')) == NULL) + if (subdir) + end = file + strlen(file); + else if ((end = strrchr(file, '/')) == NULL) return (0); if ((e = ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY || (e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) { @@ -288,6 +290,8 @@ ftp_cwd(conn_t *conn, const char *file) if (pwd[i] != file[i]) break; /* Keep going up a dir until we have a matching prefix. */ + if (strcmp(pwd, "/") == 0) + break; if (pwd[i] == '\0' && (file[i - 1] == '/' || file[i] == '/')) break; if ((e = ftp_cmd(conn, "CDUP")) != FTP_FILE_ACTION_OK || @@ -403,7 +407,7 @@ ftp_stat(conn_t *conn, const char *file, struct url_stat *us) us->size = -1; us->atime = us->mtime = 0; - filename = ftp_filename(file, &filenamelen, &type); + filename = ftp_filename(file, &filenamelen, &type, 0); if ((e = ftp_mode_type(conn, 0, type)) != FTP_OK) { ftp_seterr(e); @@ -591,7 +595,7 @@ ftp_setup(conn_t *cconn, conn_t *dconn, int mode) * Transfer file */ static fetchIO * -ftp_transfer(conn_t *conn, const char *oper, const char *file, +ftp_transfer(conn_t *conn, const char *oper, const char *file, const char *op_arg, int mode, off_t offset, const char *flags) { struct sockaddr_storage sa; @@ -617,7 +621,7 @@ ftp_transfer(conn_t *conn, const char *oper, const char *file, strncasecmp(s, "no", 2) != 0); /* isolate filename */ - filename = ftp_filename(file, &filenamelen, &type); + filename = ftp_filename(file, &filenamelen, &type, op_arg != NULL); /* set transfer mode and data type */ if ((e = ftp_mode_type(conn, 0, type)) != FTP_OK) @@ -752,7 +756,11 @@ ftp_transfer(conn_t *conn, const char *oper, const char *file, /* make the server initiate the transfer */ if (verbose) fetch_info("initiating transfer"); - e = ftp_cmd(conn, "%s %.*s", oper, filenamelen, filename); + if (op_arg) + e = ftp_cmd(conn, "%s%s%s", oper, *op_arg ? " " : "", op_arg); + else + e = ftp_cmd(conn, "%s %.*s", oper, + filenamelen, filename); if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) goto ouch; @@ -848,7 +856,11 @@ ftp_transfer(conn_t *conn, const char *oper, const char *file, /* make the server initiate the transfer */ if (verbose) fetch_info("initiating transfer"); - e = ftp_cmd(conn, "%s %.*s", oper, filenamelen, filename); + if (op_arg) + e = ftp_cmd(conn, "%s%s%s", oper, *op_arg ? " " : "", op_arg); + else + e = ftp_cmd(conn, "%s %.*s", oper, + filenamelen, filename); if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) goto ouch; @@ -1077,8 +1089,8 @@ ftp_get_proxy(struct url * url, const char *flags) * Process an FTP request */ fetchIO * -ftp_request(struct url *url, const char *op, struct url_stat *us, - struct url *purl, const char *flags) +ftp_request(struct url *url, const char *op, const char *op_arg, + struct url_stat *us, struct url *purl, const char *flags) { conn_t *conn; int oflag; @@ -1103,7 +1115,7 @@ ftp_request(struct url *url, const char *op, struct url_stat *us, return (NULL); /* change directory */ - if (ftp_cwd(conn, url->doc) == -1) + if (ftp_cwd(conn, url->doc, op_arg != NULL) == -1) return (NULL); /* stat file */ @@ -1121,7 +1133,7 @@ ftp_request(struct url *url, const char *op, struct url_stat *us, oflag = O_RDONLY; /* initiate the transfer */ - return (ftp_transfer(conn, op, url->doc, oflag, url->offset, flags)); + return (ftp_transfer(conn, op, url->doc, op_arg, oflag, url->offset, flags)); } /* @@ -1130,7 +1142,7 @@ ftp_request(struct url *url, const char *op, struct url_stat *us, fetchIO * fetchXGetFTP(struct url *url, struct url_stat *us, const char *flags) { - return (ftp_request(url, "RETR", us, ftp_get_proxy(url, flags), flags)); + return (ftp_request(url, "RETR", NULL, us, ftp_get_proxy(url, flags), flags)); } /* @@ -1148,7 +1160,7 @@ fetchGetFTP(struct url *url, const char *flags) fetchIO * fetchPutFTP(struct url *url, const char *flags) { - return (ftp_request(url, CHECK_FLAG('a') ? "APPE" : "STOR", NULL, + return (ftp_request(url, CHECK_FLAG('a') ? "APPE" : "STOR", NULL, NULL, ftp_get_proxy(url, flags), flags)); } @@ -1160,7 +1172,7 @@ fetchStatFTP(struct url *url, struct url_stat *us, const char *flags) { fetchIO *f; - f = ftp_request(url, "STAT", us, ftp_get_proxy(url, flags), flags); + f = ftp_request(url, "STAT", NULL, us, ftp_get_proxy(url, flags), flags); if (f == NULL) return (-1); fetchIO_close(f); @@ -1173,7 +1185,43 @@ fetchStatFTP(struct url *url, struct url_stat *us, const char *flags) struct url_ent * fetchFilteredListFTP(struct url *url, const char *pattern, const char *flags) { - fprintf(stderr, "fetchFilteredListFTP(): not implemented\n"); + struct url_ent *ue; + fetchIO *f; + char buf[2 * PATH_MAX], *eol, *eos; + ssize_t len; + size_t cur_off; + + /* XXX What about proxies? */ + f = ftp_request(url, "NLST", pattern, NULL, ftp_get_proxy(url, flags), flags); + if (f == NULL) + return NULL; + + ue = NULL; + cur_off = 0; + while ((len = fetchIO_read(f, buf + cur_off, sizeof(buf) - cur_off)) > 0) { + cur_off += len; + while ((eol = memchr(buf, '\n', cur_off)) != NULL) { + if (len == eol - buf) + break; + if (eol != buf) { + if (eol[-1] == '\r') + eos = eol - 1; + else + eos = eol; + fwrite(buf, eos - buf, 1, stdout); + puts(""); + cur_off -= eol - buf + 1; + memmove(buf, eol + 1, cur_off); + } + } + } + if (cur_off != 0 || len < 0) { + /* Not RFC conform, bail out. */ + fetchIO_close(f); + free(ue); + return NULL; + } + fetchIO_close(f); return (NULL); } @@ -1183,6 +1231,5 @@ fetchFilteredListFTP(struct url *url, const char *pattern, const char *flags) struct url_ent * fetchListFTP(struct url *url, const char *flags) { - fprintf(stderr, "fetchListFTP(): not implemented\n"); - return (NULL); + return fetchFilteredList(url, "", flags); } diff --git a/net/libfetch/files/http.c b/net/libfetch/files/http.c index 84c1e9e99b5..e1929af5964 100644 --- a/net/libfetch/files/http.c +++ b/net/libfetch/files/http.c @@ -1,4 +1,4 @@ -/* $NetBSD: http.c,v 1.10 2008/04/04 22:37:28 joerg Exp $ */ +/* $NetBSD: http.c,v 1.11 2008/04/05 02:42:13 joerg Exp $ */ /*- * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav * All rights reserved. @@ -780,9 +780,9 @@ http_request(struct url *URL, const char *op, struct url_stat *us, /* were we redirected to an FTP URL? */ if (purl == NULL && strcmp(url->scheme, SCHEME_FTP) == 0) { if (strcmp(op, "GET") == 0) - return (ftp_request(url, "RETR", us, purl, flags)); + return (ftp_request(url, "RETR", NULL, us, purl, flags)); else if (strcmp(op, "HEAD") == 0) - return (ftp_request(url, "STAT", us, purl, flags)); + return (ftp_request(url, "STAT", NULL, us, purl, flags)); } /* connect to server or proxy */ |