From 9eb60712989a0fae7fcc9dede444f5a2a2257b3e Mon Sep 17 00:00:00 2001 From: des Date: Mon, 21 Dec 1998 19:41:50 +0000 Subject: Implement and document file list retrieval. --- lib/libfetch/common.c | 44 +++++++++++++++++++++++++++++++++++++++++++- lib/libfetch/common.h | 6 ++++-- lib/libfetch/fetch.3 | 43 +++++++++++++++++++++++++++++++++++++++++-- lib/libfetch/fetch.c | 39 ++++++++++++++++++++++++++++++++++++++- lib/libfetch/fetch.h | 12 +++++++++++- lib/libfetch/file.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- lib/libfetch/ftp.c | 13 ++++++++++++- lib/libfetch/http.c | 12 +++++++++++- 8 files changed, 207 insertions(+), 13 deletions(-) diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index a04cb0b..e3dab8d 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: common.c,v 1.3 1998/12/16 10:24:52 des Exp $ + * $Id: common.c,v 1.4 1998/12/18 14:32:48 des Exp $ */ #include @@ -240,3 +240,45 @@ _fetch_connect(char *host, int port, int verbose) return sd; } + + +/*** Directory-related utility functions *************************************/ + +int +_fetch_add_entry(struct url_ent **p, int *size, int *len, + char *name, struct url_stat *stat) +{ + struct url_ent *tmp; + + if (*p == NULL) { +#define INITIAL_SIZE 8 + if ((*p = malloc(INITIAL_SIZE * sizeof **p)) == NULL) { + errno = ENOMEM; + _fetch_syserr(); + return -1; + } + *size = INITIAL_SIZE; + *len = 0; +#undef INITIAL_SIZE + } + + if (*len >= *size - 1) { + tmp = realloc(*p, *size * 2 * sizeof **p); + if (tmp == NULL) { + errno = ENOMEM; + _fetch_syserr(); + return -1; + } + *size *= 2; + *p = tmp; + } + + tmp = *p + *len; + snprintf(tmp->name, MAXPATHLEN, "%s", name); + bcopy(stat, &tmp->stat, sizeof *stat); + + (*len)++; + (++tmp)->name[0] = 0; + + return 0; +} diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h index eb34033..0a11548 100644 --- a/lib/libfetch/common.h +++ b/lib/libfetch/common.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: common.h,v 1.3 1998/12/16 10:24:53 des Exp $ + * $Id: common.h,v 1.4 1998/12/18 14:32:48 des Exp $ */ #ifndef _COMMON_H_INCLUDED @@ -42,7 +42,9 @@ void _fetch_seterr(struct fetcherr *, int); void _fetch_syserr(void); int _fetch_info(char *fmt, ...); int _fetch_connect(char *, int, int); - +int _fetch_add_entry(struct url_ent **p, int *size, int *len, + char *name, struct url_stat *stat); + #define _ftp_seterr(n) _fetch_seterr(_ftp_errlist, n) #define _http_seterr(n) _fetch_seterr(_http_errlist, n) #define _netdb_seterr(n) _fetch_seterr(_netdb_errlist, n) diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3 index 0c6aa7d..16dec55 100644 --- a/lib/libfetch/fetch.3 +++ b/lib/libfetch/fetch.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: fetch.3,v 1.5 1998/12/16 10:24:54 des Exp $ +.\" $Id: fetch.3,v 1.6 1998/12/16 15:29:03 des Exp $ .\" .Dd July 1, 1998 .Dt FETCH 3 @@ -31,19 +31,24 @@ .Nm fetchGetURL , .Nm fetchPutURL , .Nm fetchStatURL , +.Nm fetchListURL , .Nm fetchParseURL , .Nm fetchGet , .Nm fetchPut , .Nm fetchStat , +.Nm fetchList , .Nm fetchGetFile , .Nm fetchPutFile , .Nm fetchStatFile , +.Nm fetchListFile , .Nm fetchGetHTTP , .Nm fetchPutHTTP , .Nm fetchStatHTTP , +.Nm fetchListHTTP , .Nm fetchGetFTP , .Nm fetchPutFTP .Nm fetchStatFTP +.Nm fetchListFTP , .Nd file transfer library .Sh SYNOPSIS .Fd #include @@ -55,6 +60,8 @@ .Fn fetchPutURL "char *URL" "char *flags" .Ft int .Fn fetchStatURL "char *URL" "struct url_stat *us" "char *flags" +.Ft struct url_ent * +.Fn fetchListURL "char *URL" "char *flags" .Ft struct url * .Fn fetchParseURL "char *URL" "char *flags" .Ft FILE * @@ -63,24 +70,32 @@ .Fn fetchPut "struct url *URL" "char *flags" .Ft int .Fn fetchStat "struct url *URL" "struct url_stat *us" "char *flags" +.Ft struct url_ent * +.Fn fetchList "struct url *" "char *flags" .Ft FILE * .Fn fetchGetFile "struct url *u" "char *flags" .Ft FILE * .Fn fetchPutFile "struct url *u" "char *flags" .Ft int .Fn fetchStatFile "struct url *URL" "struct url_stat *us" "char *flags" +.Ft struct url_ent * +.Fn fetchListFile "struct url *" "char *flags" .Ft FILE * .Fn fetchGetHTTP "struct url *u" "char *flags" .Ft FILE * .Fn fetchPutHTTP "struct url *u" "char *flags" .Ft int .Fn fetchStatHTTP "struct url *URL" "struct url_stat *us" "char *flags" +.Ft struct url_ent * +.Fn fetchListHTTP "struct url *" "char *flags" .Ft FILE * .Fn fetchGetFTP "struct url *u" "char *flags" .Ft FILE * .Fn fetchPutFTP "struct url *u" "char *flags" .Ft int .Fn fetchStatFTP "struct url *URL" "struct url_stat *us" "char *flags" +.Ft struct url_ent * +.Fn fetchListFTP "struct url *" "char *flags" .Sh DESCRIPTION .Pp These functions implement a high-level library for retrieving and @@ -113,6 +128,28 @@ struct url_stat { }; .Ed .Pp +.Fn fetchListURL +attempts to list the contents of the directory pointed to by the URL +provided. If successful, it returns a malloced array of +.Fa url_ent +structures. The +.Fa url_ent +structure is defined as follows in +.Aq Pa fetch.h : +.Bd -literal +struct url_ent { + char name[MAXPATHLEN]; + struct url_stat stat; +}; +.Ed +.Pp +The list is terminated by an entry with an empty name. +.Pp +The pointer returned by +.Fn fetchListURL +should be freed using +.Fn free . +.Pp .Fn fetchParseURL takes a URL in the form of a null-terminated string and splits it into its components function according to the Common Internet Scheme Syntax @@ -331,7 +368,9 @@ This manual page was written by Some parts of the library are not yet implemented. The most notable examples of this are .Fn fetchPutHTTP , -.Fn fetchStatHTTP +.Fn fetchStatHTTP , +.Fn fetchListHTTP , +.Fn fetchListFTP , and FTP proxy support. .Pp There's no way to select a proxy at run-time other than setting the diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c index 1dba89e..d8d2443 100644 --- a/lib/libfetch/fetch.c +++ b/lib/libfetch/fetch.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fetch.c,v 1.6 1998/11/06 22:14:08 des Exp $ + * $Id: fetch.c,v 1.7 1998/12/16 10:24:54 des Exp $ */ #include @@ -119,6 +119,25 @@ fetchStat(struct url *URL, struct url_stat *us, char *flags) } /* + * Select the appropriate protocol for the URL scheme, and return a + * list of files in the directory pointed to by the URL. + */ +struct url_ent * +fetchList(struct url *URL, char *flags) +{ + if (strcasecmp(URL->scheme, "file") == 0) + return fetchListFile(URL, flags); + else if (strcasecmp(URL->scheme, "http") == 0) + return fetchListHTTP(URL, flags); + else if (strcasecmp(URL->scheme, "ftp") == 0) + return fetchListFTP(URL, flags); + else { + _url_seterr(URL_BAD_SCHEME); + return NULL; + } +} + +/* * Attempt to parse the given URL; if successful, call fetchGet(). */ FILE * @@ -174,6 +193,24 @@ fetchStatURL(char *URL, struct url_stat *us, char *flags) } /* + * Attempt to parse the given URL; if successful, call fetchList(). + */ +struct url_ent * +fetchListURL(char *URL, char *flags) +{ + struct url *u; + struct url_ent *ue; + + if ((u = fetchParseURL(URL)) == NULL) + return NULL; + + ue = fetchList(u, flags); + + free(u); + return ue; +} + +/* * Split an URL into components. URL syntax is: * method:[//[user[:pwd]@]host[:port]]/[document] * This almost, but not quite, RFC1738 URL syntax. diff --git a/lib/libfetch/fetch.h b/lib/libfetch/fetch.h index 6ec7d67..2e33245 100644 --- a/lib/libfetch/fetch.h +++ b/lib/libfetch/fetch.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fetch.h,v 1.6 1998/11/06 22:14:08 des Exp $ + * $Id: fetch.h,v 1.7 1998/12/16 10:24:55 des Exp $ */ #ifndef _FETCH_H_INCLUDED @@ -54,30 +54,40 @@ struct url_stat { time_t mtime; }; +struct url_ent { + char name[MAXPATHLEN]; + struct url_stat stat; +}; + /* FILE-specific functions */ FILE *fetchGetFile(struct url *, char *); FILE *fetchPutFile(struct url *, char *); int fetchStatFile(struct url *, struct url_stat *, char *); +struct url_ent *fetchListFile(struct url *, char *); /* HTTP-specific functions */ char *fetchContentType(FILE *); FILE *fetchGetHTTP(struct url *, char *); FILE *fetchPutHTTP(struct url *, char *); int fetchStatHTTP(struct url *, struct url_stat *, char *); +struct url_ent *fetchListHTTP(struct url *, char *); /* FTP-specific functions */ FILE *fetchGetFTP(struct url *, char *); FILE *fetchPutFTP(struct url *, char *); int fetchStatFTP(struct url *, struct url_stat *, char *); +struct url_ent *fetchListFTP(struct url *, char *); /* Generic functions */ struct url *fetchParseURL(char *); FILE *fetchGetURL(char *, char *); FILE *fetchPutURL(char *, char *); int fetchStatURL(char *, struct url_stat *, char *); +struct url_ent *fetchListURL(char *, char *); FILE *fetchGet(struct url *, char *); FILE *fetchPut(struct url *, char *); int fetchStat(struct url *, struct url_stat *, char *); +struct url_ent *fetchList(struct url *, char *); /* Last error code */ extern int fetchLastErrCode; diff --git a/lib/libfetch/file.c b/lib/libfetch/file.c index fb10f8a..15cb043 100644 --- a/lib/libfetch/file.c +++ b/lib/libfetch/file.c @@ -25,11 +25,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: file.c,v 1.2 1998/11/06 22:14:08 des Exp $ + * $Id: file.c,v 1.3 1998/12/16 10:24:55 des Exp $ */ #include #include + +#include #include #include @@ -63,12 +65,12 @@ fetchPutFile(struct url *u, char *flags) return f; } -int -fetchStatFile(struct url *u, struct url_stat *us, char *flags) +static int +_fetch_stat_file(char *fn, struct url_stat *us) { struct stat sb; - if (stat(u->doc, &sb) == -1) { + if (stat(fn, &sb) == -1) { _fetch_syserr(); return -1; } @@ -77,3 +79,44 @@ fetchStatFile(struct url *u, struct url_stat *us, char *flags) us->mtime = sb.st_mtime; return 0; } + +int +fetchStatFile(struct url *u, struct url_stat *us, char *flags) +{ + return _fetch_stat_file(u->doc, us); +} + +struct url_ent * +fetchListFile(struct url *u, char *flags) +{ + DIR *dir; + struct dirent *de; + struct url_stat us; + struct url_ent *ue; + int size, len; + char fn[MAXPATHLEN], *p; + int l; + + if ((dir = opendir(u->doc)) == NULL) { + _fetch_syserr(); + return NULL; + } + + ue = NULL; + strncpy(fn, u->doc, sizeof fn - 2); + fn[sizeof fn - 2] = 0; + strcat(fn, "/"); + p = strchr(fn, 0); + l = sizeof fn - strlen(fn) - 1; + + while ((de = readdir(dir)) != NULL) { + strncpy(p, de->d_name, l - 1); + p[l - 1] = 0; + if (_fetch_stat_file(fn, &us) == -1) + /* should I return a partial result, or abort? */ + break; + _fetch_add_entry(&ue, &size, &len, de->d_name, &us); + } + + return ue; +} diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index 22993ee7..10e27b4 100644 --- a/lib/libfetch/ftp.c +++ b/lib/libfetch/ftp.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ftp.c,v 1.10 1998/12/16 15:29:03 des Exp $ + * $Id: ftp.c,v 1.11 1998/12/18 14:32:48 des Exp $ */ /* @@ -507,3 +507,14 @@ ouch: _ftp_seterr(e); return -1; } + +/* + * List a directory + */ +extern void warnx(char *, ...); +struct url_ent * +fetchListFTP(struct url *url, char *flags) +{ + warnx("fetchListFTP(): not implemented"); + return NULL; +} diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 5c49ec5..0d5804a 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: http.c,v 1.9 1998/12/16 11:44:31 des Exp $ + * $Id: http.c,v 1.10 1998/12/18 14:32:48 des Exp $ */ /* @@ -459,3 +459,13 @@ fetchStatHTTP(struct url *url, struct url_stat *us, char *flags) warnx("fetchStatHTTP(): not implemented"); return -1; } + +/* + * List a directory + */ +struct url_ent * +fetchListHTTP(struct url *url, char *flags) +{ + warnx("fetchListHTTP(): not implemented"); + return NULL; +} -- cgit v1.1