lib: added libfetch
This commit is contained in:
parent
098412be83
commit
429639f938
16 changed files with 6752 additions and 1 deletions
|
@ -1,7 +1,7 @@
|
|||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= csu libc libcurses libdriver libnetdriver libend libedit libm libsys \
|
||||
libtimers libutil libbz2 libl libhgfs libz
|
||||
libtimers libutil libbz2 libl libhgfs libz libfetch
|
||||
|
||||
.if ${COMPILER_TYPE} == "ack"
|
||||
SUBDIR+= ack/libd ack/libe ack/libfp ack/liby
|
||||
|
|
44
lib/libfetch/Makefile
Normal file
44
lib/libfetch/Makefile
Normal file
|
@ -0,0 +1,44 @@
|
|||
# $NetBSD: Makefile,v 1.5 2010/02/24 22:00:51 joerg Exp $
|
||||
|
||||
LIB= fetch
|
||||
SRCS= fetch.c common.c ftp.c http.c file.c
|
||||
#DPSRCS= ftperr.h httperr.h
|
||||
INCSDIR= /usr/include
|
||||
INCS= fetch.h
|
||||
MAN= fetch.3
|
||||
# CLEANFILES= ftperr.h httperr.h
|
||||
MKLINT= no
|
||||
MKPIC= no
|
||||
MKPROFILE= no
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
CPPFLAGS+= -D_POSIX_SOURCE
|
||||
CPPFLAGS+= -I.
|
||||
CPPFLAGS+= -D_LARGEFILE_SOURCE -D_LARGE_FILES
|
||||
|
||||
FETCH_WITH_INET6?= no
|
||||
FETCH_WITH_OPENSSL?= no
|
||||
|
||||
.if !empty(FETCH_WITH_INET6:M[yY][eE][sS])
|
||||
CPPFLAGS+= -DINET6
|
||||
.endif
|
||||
|
||||
.if !empty(FETCH_WITH_OPENSSL:M[yY][eE][sS])
|
||||
CPPFLAGS+= -DWITH_SSL
|
||||
LDADD= -lssl -lcrypto
|
||||
.endif
|
||||
|
||||
CPPFLAGS+= -DFTP_COMBINE_CWDS
|
||||
|
||||
# WARNS?= 4
|
||||
|
||||
#ftperr.h: ${.CURDIR}/ftp.errors ${.CURDIR}/Makefile ${.CURDIR}/errlist.sh
|
||||
# ${.CURDIR}/errlist.sh ftp_errlist FTP \
|
||||
# ${.CURDIR}/ftp.errors > ${.TARGET}
|
||||
#
|
||||
#httperr.h: ${.CURDIR}/http.errors ${.CURDIR}/Makefile ${.CURDIR}/errlist.sh
|
||||
# ${.CURDIR}/errlist.sh http_errlist HTTP \
|
||||
# ${.CURDIR}/http.errors > ${.TARGET}
|
||||
|
||||
.include <bsd.lib.mk>
|
1053
lib/libfetch/common.c
Normal file
1053
lib/libfetch/common.c
Normal file
File diff suppressed because it is too large
Load diff
139
lib/libfetch/common.h
Normal file
139
lib/libfetch/common.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/* $NetBSD: common.h,v 1.16 2010/03/21 16:48:43 joerg Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: common.h,v 1.30 2007/12/18 11:03:07 des Exp $
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_INCLUDED
|
||||
#define _COMMON_H_INCLUDED
|
||||
|
||||
#define FTP_DEFAULT_PORT 21
|
||||
#define HTTP_DEFAULT_PORT 80
|
||||
#define FTP_DEFAULT_PROXY_PORT 21
|
||||
#define HTTP_DEFAULT_PROXY_PORT 3128
|
||||
|
||||
#ifdef WITH_SSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__sun) && !defined(__hpux) && !defined(__INTERIX) && \
|
||||
!defined(__digital__) && !defined(__linux) && !defined(__MINT__) && \
|
||||
!defined(__sgi) && !defined(__minix)
|
||||
#define HAVE_SA_LEN
|
||||
#endif
|
||||
|
||||
/* Connection */
|
||||
typedef struct fetchconn conn_t;
|
||||
|
||||
struct fetchconn {
|
||||
int sd; /* socket descriptor */
|
||||
char *buf; /* buffer */
|
||||
size_t bufsize; /* buffer size */
|
||||
size_t buflen; /* length of buffer contents */
|
||||
char *next_buf; /* pending buffer, e.g. after getln */
|
||||
size_t next_len; /* size of pending buffer */
|
||||
int err; /* last protocol reply code */
|
||||
#ifdef WITH_SSL
|
||||
SSL *ssl; /* SSL handle */
|
||||
SSL_CTX *ssl_ctx; /* SSL context */
|
||||
X509 *ssl_cert; /* server certificate */
|
||||
# if OPENSSL_VERSION_NUMBER < 0x00909000L
|
||||
SSL_METHOD *ssl_meth; /* SSL method */
|
||||
# else
|
||||
const SSL_METHOD *ssl_meth; /* SSL method */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
char *ftp_home;
|
||||
|
||||
struct url *cache_url;
|
||||
int cache_af;
|
||||
int (*cache_close)(conn_t *);
|
||||
conn_t *next_cached;
|
||||
};
|
||||
|
||||
/* Structure used for error message lists */
|
||||
struct fetcherr {
|
||||
const int num;
|
||||
const int cat;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
void fetch_seterr(struct fetcherr *, int);
|
||||
void fetch_syserr(void);
|
||||
void fetch_info(const char *, ...);
|
||||
int fetch_default_port(const char *);
|
||||
int fetch_default_proxy_port(const char *);
|
||||
int fetch_bind(int, int, const char *);
|
||||
conn_t *fetch_cache_get(const struct url *, int);
|
||||
void fetch_cache_put(conn_t *, int (*)(conn_t *));
|
||||
conn_t *fetch_connect(struct url *, int, int);
|
||||
conn_t *fetch_reopen(int);
|
||||
int fetch_ssl(conn_t *, int);
|
||||
ssize_t fetch_read(conn_t *, char *, size_t);
|
||||
int fetch_getln(conn_t *);
|
||||
ssize_t fetch_write(conn_t *, const void *, size_t);
|
||||
int fetch_close(conn_t *);
|
||||
int fetch_add_entry(struct url_list *, struct url *, const char *, int);
|
||||
int fetch_netrc_auth(struct url *url);
|
||||
int fetch_no_proxy_match(const char *);
|
||||
int fetch_urlpath_safe(char);
|
||||
|
||||
#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)
|
||||
#define url_seterr(n) fetch_seterr(url_errlist, n)
|
||||
|
||||
fetchIO *fetchIO_unopen(void *, ssize_t (*)(void *, void *, size_t),
|
||||
ssize_t (*)(void *, const void *, size_t), void (*)(void *));
|
||||
|
||||
/*
|
||||
* I don't really like exporting http_request() and ftp_request(),
|
||||
* but the HTTP and FTP code occasionally needs to cross-call
|
||||
* eachother, and this saves me from adding a lot of special-case code
|
||||
* to handle those cases.
|
||||
*
|
||||
* Note that _*_request() free purl, which is way ugly but saves us a
|
||||
* whole lot of trouble.
|
||||
*/
|
||||
fetchIO *http_request(struct url *, const char *,
|
||||
struct url_stat *, struct url *, const char *);
|
||||
fetchIO *ftp_request(struct url *, const char *, const char *,
|
||||
struct url_stat *, struct url *, const char *);
|
||||
|
||||
|
||||
/*
|
||||
* Check whether a particular flag is set
|
||||
*/
|
||||
#define CHECK_FLAG(x) (flags && strchr(flags, (x)))
|
||||
|
||||
#endif
|
11
lib/libfetch/errlist.sh
Executable file
11
lib/libfetch/errlist.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
# $NetBSD: errlist.sh,v 1.2 2008/10/06 12:58:29 joerg Exp $
|
||||
|
||||
printf "static struct fetcherr $1[] = {\n"
|
||||
while read code type msg; do
|
||||
[ "${code}" = "#" ] && continue
|
||||
printf "\t{ ${code}, FETCH_${type}, \"${msg}\" },\n"
|
||||
done < $3
|
||||
|
||||
printf "\t{ -1, FETCH_UNKNOWN, \"Unknown $2 error\" }\n"
|
||||
printf "};\n"
|
781
lib/libfetch/fetch.3
Normal file
781
lib/libfetch/fetch.3
Normal file
|
@ -0,0 +1,781 @@
|
|||
.\"-
|
||||
.\" Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD: fetch.3,v 1.64 2007/12/18 11:03:26 des Exp $
|
||||
.\" $NetBSD: fetch.3,v 1.15 2010/01/22 13:56:45 wiz Exp $
|
||||
.\"
|
||||
.Dd January 22, 2010
|
||||
.Dt FETCH 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm fetchMakeURL ,
|
||||
.Nm fetchParseURL ,
|
||||
.Nm fetchCopyURL ,
|
||||
.Nm fetchFreeURL ,
|
||||
.Nm fetchXGetURL ,
|
||||
.Nm fetchGetURL ,
|
||||
.Nm fetchPutURL ,
|
||||
.Nm fetchStatURL ,
|
||||
.Nm fetchListURL ,
|
||||
.Nm fetchXGet ,
|
||||
.Nm fetchGet ,
|
||||
.Nm fetchPut ,
|
||||
.Nm fetchStat ,
|
||||
.Nm fetchList ,
|
||||
.Nm fetchXGetFile ,
|
||||
.Nm fetchGetFile ,
|
||||
.Nm fetchPutFile ,
|
||||
.Nm fetchStatFile ,
|
||||
.Nm fetchListFile ,
|
||||
.Nm fetchXGetHTTP ,
|
||||
.Nm fetchGetHTTP ,
|
||||
.Nm fetchPutHTTP ,
|
||||
.Nm fetchStatHTTP ,
|
||||
.Nm fetchListHTTP ,
|
||||
.Nm fetchXGetFTP ,
|
||||
.Nm fetchGetFTP ,
|
||||
.Nm fetchPutFTP ,
|
||||
.Nm fetchStatFTP ,
|
||||
.Nm fetchListFTP
|
||||
.Nm fetchInitURLList ,
|
||||
.Nm fetchFreeURLList ,
|
||||
.Nm fetchUnquotePath ,
|
||||
.Nm fetchUnquoteFilename ,
|
||||
.Nm fetchStringifyURL ,
|
||||
.Nm fetchConnectionCacheInit ,
|
||||
.Nm fetchConnectionCacheClose ,
|
||||
.Nm fetch
|
||||
.Nd file transfer functions
|
||||
.Sh LIBRARY
|
||||
.Lb libfetch
|
||||
.Sh SYNOPSIS
|
||||
.In stdio.h
|
||||
.In fetch.h
|
||||
.Ft struct url *
|
||||
.Fn fetchMakeURL "const char *scheme" "const char *host" "int port" "const char *doc" "const char *user" "const char *pwd"
|
||||
.Ft struct url *
|
||||
.Fn fetchParseURL "const char *URL"
|
||||
.Ft struct url *
|
||||
.Fn fetchCopyURL "const struct url *u"
|
||||
.Ft void
|
||||
.Fn fetchFreeURL "struct url *u"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchXGetURL "const char *URL" "struct url_stat *us" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchGetURL "const char *URL" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchPutURL "const char *URL" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchStatURL "const char *URL" "struct url_stat *us" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchListURL "struct url_list *list" "const char *URL" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchXGet "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchGet "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchPut "struct url *u" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchStat "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchList "struct url_list *list" "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchXGetFile "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchGetFile "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchPutFile "struct url *u" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchStatFile "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchListFile "struct url_list *list" "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchXGetHTTP "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchGetHTTP "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchPutHTTP "struct url *u" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchStatHTTP "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchListHTTP "struct url_list *list" "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchXGetFTP "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchGetFTP "struct url *u" "const char *flags"
|
||||
.Ft fetchIO *
|
||||
.Fn fetchPutFTP "struct url *u" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchStatFTP "struct url *u" "struct url_stat *us" "const char *flags"
|
||||
.Ft int
|
||||
.Fn fetchListFTP "struct url_list *list" "struct url *u" "const char *flags"
|
||||
.Ft void
|
||||
.Fn fetchInitURLList "struct url_list *ul"
|
||||
.Ft int
|
||||
.Fn fetchAppendURLList "struct url_list *dst" "const struct url_list *src"
|
||||
.Ft void
|
||||
.Fn fetchFreeURLList "struct url_list *ul"
|
||||
.Ft char *
|
||||
.Fn fetchUnquotePath "struct url *u"
|
||||
.Ft char *
|
||||
.Fn fetchUnquoteFilename "struct url *u"
|
||||
.Ft char *
|
||||
.Fn fetchStringifyURL "const struct url *u"
|
||||
.Ft void
|
||||
.Fn fetchConnectionCacheInit "int global" "int per_host"
|
||||
.Ft void
|
||||
.Fn fetchConnectionCacheClose "void"
|
||||
.Sh DESCRIPTION
|
||||
These functions implement a high-level library for retrieving and
|
||||
uploading files using Uniform Resource Locators (URLs).
|
||||
.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
|
||||
detailed in RFC 1738.
|
||||
A regular expression which produces this syntax is:
|
||||
.Bd -literal -offset indent
|
||||
\*[Lt]scheme\*[Gt]:(//(\*[Lt]user\*[Gt](:\*[Lt]pwd\*[Gt])?@)?\*[Lt]host\*[Gt](:\*[Lt]port\*[Gt])?)?/(\*[Lt]document\*[Gt])?
|
||||
.Ed
|
||||
.Pp
|
||||
If the URL does not seem to begin with a scheme name, it is assumed to be a local path.
|
||||
Only absolute path names are accepted.
|
||||
.Pp
|
||||
Note that some components of the URL are not necessarily relevant to
|
||||
all URL schemes.
|
||||
For instance, the file scheme only needs the
|
||||
.Aq scheme
|
||||
and
|
||||
.Aq document
|
||||
components.
|
||||
.Fn fetchParseURL
|
||||
quotes any unsafe character in the URL automatically.
|
||||
This is not done by
|
||||
.Fn fetchMakeURL .
|
||||
.Fn fetchCopyURL
|
||||
copies an existing
|
||||
.Vt url
|
||||
structure.
|
||||
.Pp
|
||||
.Fn fetchMakeURL ,
|
||||
.Fn fetchParseURL ,
|
||||
and
|
||||
.Fn fetchCopyURL
|
||||
return a pointer to a
|
||||
.Vt url
|
||||
structure, which is defined as follows in
|
||||
.In fetch.h :
|
||||
.Bd -literal
|
||||
#define URL_SCHEMELEN 16
|
||||
#define URL_USERLEN 256
|
||||
#define URL_PWDLEN 256
|
||||
#define URL_HOSTLEN 255
|
||||
|
||||
struct url {
|
||||
char scheme[URL_SCHEMELEN + 1];
|
||||
char user[URL_USERLEN + 1];
|
||||
char pwd[URL_PWDLEN + 1];
|
||||
char host[URL_HOSTLEN + 1];
|
||||
int port;
|
||||
char *doc;
|
||||
off_t offset;
|
||||
size_t length;
|
||||
time_t last_modified;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The pointer returned by
|
||||
.Fn fetchMakeURL ,
|
||||
.Fn fetchCopyURL ,
|
||||
and
|
||||
.Fn fetchParseURL
|
||||
should be freed using
|
||||
.Fn fetchFreeURL .
|
||||
The size of
|
||||
.Vt struct URL
|
||||
is not part of the ABI.
|
||||
.Pp
|
||||
.Fn fetchXGetURL ,
|
||||
.Fn fetchGetURL ,
|
||||
and
|
||||
.Fn fetchPutURL
|
||||
constitute the recommended interface to the
|
||||
.Nm fetch
|
||||
library.
|
||||
They examine the URL passed to them to determine the transfer
|
||||
method, and call the appropriate lower-level functions to perform the
|
||||
actual transfer.
|
||||
.Fn fetchXGetURL
|
||||
also returns the remote document's metadata in the
|
||||
.Vt url_stat
|
||||
structure pointed to by the
|
||||
.Fa us
|
||||
argument.
|
||||
.Pp
|
||||
The
|
||||
.Fa flags
|
||||
argument is a string of characters which specify transfer options.
|
||||
The
|
||||
meaning of the individual flags is scheme-dependent, and is detailed
|
||||
in the appropriate section below.
|
||||
.Pp
|
||||
.Fn fetchStatURL
|
||||
attempts to obtain the requested document's metadata and fill in the
|
||||
structure pointed to by its second argument.
|
||||
The
|
||||
.Vt url_stat
|
||||
structure is defined as follows in
|
||||
.In fetch.h :
|
||||
.Bd -literal
|
||||
struct url_stat {
|
||||
off_t size;
|
||||
time_t atime;
|
||||
time_t mtime;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
If the size could not be obtained from the server, the
|
||||
.Fa size
|
||||
field is set to \-1.
|
||||
If the modification time could not be obtained from the server, the
|
||||
.Fa mtime
|
||||
field is set to the epoch.
|
||||
If the access time could not be obtained from the server, the
|
||||
.Fa atime
|
||||
field is set to the modification time.
|
||||
.Pp
|
||||
.Fn fetchListURL
|
||||
attempts to list the contents of the directory pointed to by the URL provided.
|
||||
The pattern can be a simple glob-like expression as hint.
|
||||
Callers should not depend on the server to filter names.
|
||||
If successful, it appends the list of entries to the
|
||||
.Vt url_list
|
||||
structure.
|
||||
The
|
||||
.Vt url_list
|
||||
structure is defined as follows in
|
||||
.In fetch.h :
|
||||
.Bd -literal
|
||||
struct url_list {
|
||||
size_t length;
|
||||
size_t alloc_size;
|
||||
struct url *urls;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The list should be initialized by calling
|
||||
.Fn fetchInitURLList
|
||||
and the entries be freed by calling
|
||||
.Fn fetchFreeURLList .
|
||||
The function
|
||||
.Fn fetchAppendURLList
|
||||
can be used to append one URL lists to another.
|
||||
If the
|
||||
.Ql c
|
||||
(cache result) flag is specified, the library is allowed to internally
|
||||
cache the result.
|
||||
.Pp
|
||||
.Fn fetchStringifyURL
|
||||
returns the URL as string.
|
||||
.Fn fetchUnquotePath
|
||||
returns the path name part of the URL with any quoting undone.
|
||||
Query arguments and fragment identifiers are not included.
|
||||
.Fn fetchUnquoteFilename
|
||||
returns the last component of the path name as returned by
|
||||
.Fn fetchUnquotePath .
|
||||
.Fn fetchStringifyURL ,
|
||||
.Fn fetchUnquotePath ,
|
||||
and
|
||||
.Fn fetchUnquoteFilename
|
||||
return a string that should be deallocated with
|
||||
.Fn free
|
||||
after use.
|
||||
.Pp
|
||||
.Fn fetchConnectionCacheInit
|
||||
enables the connection cache.
|
||||
The first argument specifies the global limit on cached connections.
|
||||
The second argument specifies the host limit.
|
||||
Entries are considered to specify the same host, if the host name
|
||||
from the URL is identical, indepent of the address or address family.
|
||||
.Fn fetchConnectionCacheClose
|
||||
flushed the connection cache and closes all cached connections.
|
||||
.Pp
|
||||
.Fn fetchXGet ,
|
||||
.Fn fetchGet ,
|
||||
.Fn fetchPut ,
|
||||
and
|
||||
.Fn fetchStat
|
||||
are similar to
|
||||
.Fn fetchXGetURL ,
|
||||
.Fn fetchGetURL ,
|
||||
.Fn fetchPutURL ,
|
||||
and
|
||||
.Fn fetchStatURL ,
|
||||
except that they expect a pre-parsed URL in the form of a pointer to
|
||||
a
|
||||
.Vt struct url
|
||||
rather than a string.
|
||||
.Pp
|
||||
All of the
|
||||
.Fn fetchXGetXXX ,
|
||||
.Fn fetchGetXXX ,
|
||||
and
|
||||
.Fn fetchPutXXX
|
||||
functions return a pointer to a stream which can be used to read or
|
||||
write data from or to the requested document, respectively.
|
||||
Note that
|
||||
although the implementation details of the individual access methods
|
||||
vary, it can generally be assumed that a stream returned by one of the
|
||||
.Fn fetchXGetXXX
|
||||
or
|
||||
.Fn fetchGetXXX
|
||||
functions is read-only, and that a stream returned by one of the
|
||||
.Fn fetchPutXXX
|
||||
functions is write-only.
|
||||
.Sh PROTOCOL INDEPENDENT FLAGS
|
||||
If the
|
||||
.Ql i
|
||||
(if-modified-since) flag is specified, the library will try to fetch
|
||||
the content only if it is newer than
|
||||
.Va last_modified .
|
||||
For HTTP an
|
||||
.Li If-Modified-Since
|
||||
HTTP header is sent.
|
||||
For FTP a
|
||||
.Li MTDM
|
||||
command is sent first and compared locally.
|
||||
For FILE the source file is compared.
|
||||
.Sh FILE SCHEME
|
||||
.Fn fetchXGetFile ,
|
||||
.Fn fetchGetFile ,
|
||||
and
|
||||
.Fn fetchPutFile
|
||||
provide access to documents which are files in a locally mounted file
|
||||
system.
|
||||
Only the
|
||||
.Aq document
|
||||
component of the URL is used.
|
||||
.Pp
|
||||
.Fn fetchXGetFile
|
||||
and
|
||||
.Fn fetchGetFile
|
||||
do not accept any flags.
|
||||
.Pp
|
||||
.Fn fetchPutFile
|
||||
accepts the
|
||||
.Ql a
|
||||
(append to file) flag.
|
||||
If that flag is specified, the data written to
|
||||
the stream returned by
|
||||
.Fn fetchPutFile
|
||||
will be appended to the previous contents of the file, instead of
|
||||
replacing them.
|
||||
.Sh FTP SCHEME
|
||||
.Fn fetchXGetFTP ,
|
||||
.Fn fetchGetFTP ,
|
||||
and
|
||||
.Fn fetchPutFTP
|
||||
implement the FTP protocol as described in RFC 959.
|
||||
.Pp
|
||||
By default
|
||||
.Nm libfetch
|
||||
will attempt to use passive mode first and only fallback to active mode
|
||||
if the server reports a syntax error.
|
||||
If the
|
||||
.Ql a
|
||||
(active) flag is specified, a passive connection is not tried and active mode
|
||||
is used directly.
|
||||
.Pp
|
||||
If the
|
||||
.Ql l
|
||||
(low) flag is specified, data sockets will be allocated in the low (or
|
||||
default) port range instead of the high port range (see
|
||||
.Xr ip 4 ) .
|
||||
.Pp
|
||||
If the
|
||||
.Ql d
|
||||
(direct) flag is specified,
|
||||
.Fn fetchXGetFTP ,
|
||||
.Fn fetchGetFTP ,
|
||||
and
|
||||
.Fn fetchPutFTP
|
||||
will use a direct connection even if a proxy server is defined.
|
||||
.Pp
|
||||
If no user name or password is given, the
|
||||
.Nm fetch
|
||||
library will attempt an anonymous login, with user name "anonymous"
|
||||
and password "anonymous@\*[Lt]hostname\*[Gt]".
|
||||
.Sh HTTP SCHEME
|
||||
The
|
||||
.Fn fetchXGetHTTP ,
|
||||
.Fn fetchGetHTTP ,
|
||||
and
|
||||
.Fn fetchPutHTTP
|
||||
functions implement the HTTP/1.1 protocol.
|
||||
With a little luck, there is
|
||||
even a chance that they comply with RFC 2616 and RFC 2617.
|
||||
.Pp
|
||||
If the
|
||||
.Ql d
|
||||
(direct) flag is specified,
|
||||
.Fn fetchXGetHTTP ,
|
||||
.Fn fetchGetHTTP ,
|
||||
and
|
||||
.Fn fetchPutHTTP
|
||||
will use a direct connection even if a proxy server is defined.
|
||||
.Pp
|
||||
Since there seems to be no good way of implementing the HTTP PUT
|
||||
method in a manner consistent with the rest of the
|
||||
.Nm fetch
|
||||
library,
|
||||
.Fn fetchPutHTTP
|
||||
is currently unimplemented.
|
||||
.Sh AUTHENTICATION
|
||||
Apart from setting the appropriate environment variables and
|
||||
specifying the user name and password in the URL or the
|
||||
.Vt struct url ,
|
||||
the calling program has the option of defining an authentication
|
||||
function with the following prototype:
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn myAuthMethod "struct url *u"
|
||||
.Pp
|
||||
The callback function should fill in the
|
||||
.Fa user
|
||||
and
|
||||
.Fa pwd
|
||||
fields in the provided
|
||||
.Vt struct url
|
||||
and return 0 on success, or any other value to indicate failure.
|
||||
.Pp
|
||||
To register the authentication callback, simply set
|
||||
.Va fetchAuthMethod
|
||||
to point at it.
|
||||
The callback will be used whenever a site requires authentication and
|
||||
the appropriate environment variables are not set.
|
||||
.Pp
|
||||
This interface is experimental and may be subject to change.
|
||||
.Sh RETURN VALUES
|
||||
.Fn fetchParseURL
|
||||
returns a pointer to a
|
||||
.Vt struct url
|
||||
containing the individual components of the URL.
|
||||
If it is
|
||||
unable to allocate memory, or the URL is syntactically incorrect,
|
||||
.Fn fetchParseURL
|
||||
returns a
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.Pp
|
||||
The
|
||||
.Fn fetchStat
|
||||
functions return 0 on success and \-1 on failure.
|
||||
.Pp
|
||||
All other functions return a stream pointer which may be used to
|
||||
access the requested document, or
|
||||
.Dv NULL
|
||||
if an error occurred.
|
||||
.Pp
|
||||
The following error codes are defined in
|
||||
.In fetch.h :
|
||||
.Bl -tag -width 18n
|
||||
.It Bq Er FETCH_ABORT
|
||||
Operation aborted
|
||||
.It Bq Er FETCH_AUTH
|
||||
Authentication failed
|
||||
.It Bq Er FETCH_DOWN
|
||||
Service unavailable
|
||||
.It Bq Er FETCH_EXISTS
|
||||
File exists
|
||||
.It Bq Er FETCH_FULL
|
||||
File system full
|
||||
.It Bq Er FETCH_INFO
|
||||
Informational response
|
||||
.It Bq Er FETCH_MEMORY
|
||||
Insufficient memory
|
||||
.It Bq Er FETCH_MOVED
|
||||
File has moved
|
||||
.It Bq Er FETCH_NETWORK
|
||||
Network error
|
||||
.It Bq Er FETCH_OK
|
||||
No error
|
||||
.It Bq Er FETCH_PROTO
|
||||
Protocol error
|
||||
.It Bq Er FETCH_RESOLV
|
||||
Resolver error
|
||||
.It Bq Er FETCH_SERVER
|
||||
Server error
|
||||
.It Bq Er FETCH_TEMP
|
||||
Temporary error
|
||||
.It Bq Er FETCH_TIMEOUT
|
||||
Operation timed out
|
||||
.It Bq Er FETCH_UNAVAIL
|
||||
File is not available
|
||||
.It Bq Er FETCH_UNKNOWN
|
||||
Unknown error
|
||||
.It Bq Er FETCH_URL
|
||||
Invalid URL
|
||||
.El
|
||||
.Pp
|
||||
The accompanying error message includes a protocol-specific error code
|
||||
and message, e.g.\& "File is not available (404 Not Found)"
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width ".Ev FETCH_BIND_ADDRESS"
|
||||
.It Ev FETCH_BIND_ADDRESS
|
||||
Specifies a host name or IP address to which sockets used for outgoing
|
||||
connections will be bound.
|
||||
.It Ev FTP_LOGIN
|
||||
Default FTP login if none was provided in the URL.
|
||||
.It Ev FTP_PASSIVE_MODE
|
||||
If set to anything but
|
||||
.Ql no ,
|
||||
forces the FTP code to use passive mode.
|
||||
.It Ev FTP_PASSWORD
|
||||
Default FTP password if the remote server requests one and none was
|
||||
provided in the URL.
|
||||
.It Ev FTP_PROXY
|
||||
URL of the proxy to use for FTP requests.
|
||||
The document part is ignored.
|
||||
FTP and HTTP proxies are supported; if no scheme is specified, FTP is
|
||||
assumed.
|
||||
If the proxy is an FTP proxy,
|
||||
.Nm libfetch
|
||||
will send
|
||||
.Ql user@host
|
||||
as user name to the proxy, where
|
||||
.Ql user
|
||||
is the real user name, and
|
||||
.Ql host
|
||||
is the name of the FTP server.
|
||||
.Pp
|
||||
If this variable is set to an empty string, no proxy will be used for
|
||||
FTP requests, even if the
|
||||
.Ev HTTP_PROXY
|
||||
variable is set.
|
||||
.It Ev ftp_proxy
|
||||
Same as
|
||||
.Ev FTP_PROXY ,
|
||||
for compatibility.
|
||||
.It Ev HTTP_AUTH
|
||||
Specifies HTTP authorization parameters as a colon-separated list of
|
||||
items.
|
||||
The first and second item are the authorization scheme and realm
|
||||
respectively; further items are scheme-dependent.
|
||||
Currently, only basic authorization is supported.
|
||||
.Pp
|
||||
Basic authorization requires two parameters: the user name and
|
||||
password, in that order.
|
||||
.Pp
|
||||
This variable is only used if the server requires authorization and
|
||||
no user name or password was specified in the URL.
|
||||
.It Ev HTTP_PROXY
|
||||
URL of the proxy to use for HTTP requests.
|
||||
The document part is ignored.
|
||||
Only HTTP proxies are supported for HTTP requests.
|
||||
If no port number is specified, the default is 3128.
|
||||
.Pp
|
||||
Note that this proxy will also be used for FTP documents, unless the
|
||||
.Ev FTP_PROXY
|
||||
variable is set.
|
||||
.It Ev http_proxy
|
||||
Same as
|
||||
.Ev HTTP_PROXY ,
|
||||
for compatibility.
|
||||
.It Ev HTTP_PROXY_AUTH
|
||||
Specifies authorization parameters for the HTTP proxy in the same
|
||||
format as the
|
||||
.Ev HTTP_AUTH
|
||||
variable.
|
||||
.Pp
|
||||
This variable is used if and only if connected to an HTTP proxy, and
|
||||
is ignored if a user and/or a password were specified in the proxy
|
||||
URL.
|
||||
.It Ev HTTP_REFERER
|
||||
Specifies the referrer URL to use for HTTP requests.
|
||||
If set to
|
||||
.Dq auto ,
|
||||
the document URL will be used as referrer URL.
|
||||
.It Ev HTTP_USER_AGENT
|
||||
Specifies the User-Agent string to use for HTTP requests.
|
||||
This can be useful when working with HTTP origin or proxy servers that
|
||||
differentiate between user agents.
|
||||
.It Ev NETRC
|
||||
Specifies a file to use instead of
|
||||
.Pa ~/.netrc
|
||||
to look up login names and passwords for FTP sites.
|
||||
See
|
||||
.Xr ftp 1
|
||||
for a description of the file format.
|
||||
This feature is experimental.
|
||||
.It Ev NO_PROXY
|
||||
Either a single asterisk, which disables the use of proxies
|
||||
altogether, or a comma- or whitespace-separated list of hosts for
|
||||
which proxies should not be used.
|
||||
.It Ev no_proxy
|
||||
Same as
|
||||
.Ev NO_PROXY ,
|
||||
for compatibility.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
To access a proxy server on
|
||||
.Pa proxy.example.com
|
||||
port 8080, set the
|
||||
.Ev HTTP_PROXY
|
||||
environment variable in a manner similar to this:
|
||||
.Pp
|
||||
.Dl HTTP_PROXY=http://proxy.example.com:8080
|
||||
.Pp
|
||||
If the proxy server requires authentication, there are
|
||||
two options available for passing the authentication data.
|
||||
The first method is by using the proxy URL:
|
||||
.Pp
|
||||
.Dl HTTP_PROXY=http://\*[Lt]user\*[Gt]:\*[Lt]pwd\*[Gt]@proxy.example.com:8080
|
||||
.Pp
|
||||
The second method is by using the
|
||||
.Ev HTTP_PROXY_AUTH
|
||||
environment variable:
|
||||
.Bd -literal -offset indent
|
||||
HTTP_PROXY=http://proxy.example.com:8080
|
||||
HTTP_PROXY_AUTH=basic:*:\*[Lt]user\*[Gt]:\*[Lt]pwd\*[Gt]
|
||||
.Ed
|
||||
.Pp
|
||||
To disable the use of a proxy for an HTTP server running on the local
|
||||
host, define
|
||||
.Ev NO_PROXY
|
||||
as follows:
|
||||
.Bd -literal -offset indent
|
||||
NO_PROXY=localhost,127.0.0.1
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.\" .Xr fetch 1 ,
|
||||
.\" .Xr ftpio 3 ,
|
||||
.Xr ftp 1 ,
|
||||
.Xr ip 4
|
||||
.Rs
|
||||
.%A J. Postel
|
||||
.%A J. K. Reynolds
|
||||
.%D October 1985
|
||||
.%B File Transfer Protocol
|
||||
.%O RFC 959
|
||||
.Re
|
||||
.Rs
|
||||
.%A P. Deutsch
|
||||
.%A A. Emtage
|
||||
.%A A. Marine
|
||||
.%D May 1994
|
||||
.%T How to Use Anonymous FTP
|
||||
.%O RFC 1635
|
||||
.Re
|
||||
.Rs
|
||||
.%A T. Berners-Lee
|
||||
.%A L. Masinter
|
||||
.%A M. McCahill
|
||||
.%D December 1994
|
||||
.%T Uniform Resource Locators (URL)
|
||||
.%O RFC 1738
|
||||
.Re
|
||||
.Rs
|
||||
.%A R. Fielding
|
||||
.%A J. Gettys
|
||||
.%A J. Mogul
|
||||
.%A H. Frystyk
|
||||
.%A L. Masinter
|
||||
.%A P. Leach
|
||||
.%A T. Berners-Lee
|
||||
.%D January 1999
|
||||
.%B Hypertext Transfer Protocol -- HTTP/1.1
|
||||
.%O RFC 2616
|
||||
.Re
|
||||
.Rs
|
||||
.%A J. Franks
|
||||
.%A P. Hallam-Baker
|
||||
.%A J. Hostetler
|
||||
.%A S. Lawrence
|
||||
.%A P. Leach
|
||||
.%A A. Luotonen
|
||||
.%A L. Stewart
|
||||
.%D June 1999
|
||||
.%B HTTP Authentication: Basic and Digest Access Authentication
|
||||
.%O RFC 2617
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm fetch
|
||||
library first appeared in
|
||||
.Fx 3.0 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm fetch
|
||||
library was mostly written by
|
||||
.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org
|
||||
with numerous suggestions from
|
||||
.An Jordan K. Hubbard Aq jkh@FreeBSD.org ,
|
||||
.An Eugene Skepner Aq eu@qub.com
|
||||
and other
|
||||
.Fx
|
||||
developers.
|
||||
It replaces the older
|
||||
.Nm ftpio
|
||||
library written by
|
||||
.An Poul-Henning Kamp Aq phk@FreeBSD.org
|
||||
and
|
||||
.An Jordan K. Hubbard Aq jkh@FreeBSD.org .
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org .
|
||||
.Sh BUGS
|
||||
Some parts of the library are not yet implemented.
|
||||
The most notable
|
||||
examples of this are
|
||||
.Fn fetchPutHTTP
|
||||
and FTP proxy support.
|
||||
.Pp
|
||||
There is no way to select a proxy at run-time other than setting the
|
||||
.Ev HTTP_PROXY
|
||||
or
|
||||
.Ev FTP_PROXY
|
||||
environment variables as appropriate.
|
||||
.Pp
|
||||
.Nm libfetch
|
||||
does not understand or obey 305 (Use Proxy) replies.
|
||||
.Pp
|
||||
Error numbers are unique only within a certain context; the error
|
||||
codes used for FTP and HTTP overlap, as do those used for resolver and
|
||||
system errors.
|
||||
For instance, error code 202 means "Command not
|
||||
implemented, superfluous at this site" in an FTP context and
|
||||
"Accepted" in an HTTP context.
|
||||
.Pp
|
||||
.Fn fetchStatFTP
|
||||
does not check that the result of an MDTM command is a valid date.
|
||||
.Pp
|
||||
The man page is incomplete, poorly written and produces badly
|
||||
formatted text.
|
||||
.Pp
|
||||
The error reporting mechanism is unsatisfactory.
|
||||
.Pp
|
||||
Some parts of the code are not fully reentrant.
|
627
lib/libfetch/fetch.c
Normal file
627
lib/libfetch/fetch.c
Normal file
|
@ -0,0 +1,627 @@
|
|||
/* $NetBSD: fetch.c,v 1.19 2009/08/11 20:48:06 joerg Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: fetch.c,v 1.41 2007/12/19 00:26:36 des Exp $
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#if !defined(NETBSD) && !defined(__minix)
|
||||
#include <nbcompat.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fetch.h"
|
||||
#include "common.h"
|
||||
|
||||
auth_t fetchAuthMethod;
|
||||
int fetchLastErrCode;
|
||||
char fetchLastErrString[MAXERRSTRING];
|
||||
int fetchTimeout;
|
||||
volatile int fetchRestartCalls = 1;
|
||||
int fetchDebug;
|
||||
|
||||
|
||||
/*** Local data **************************************************************/
|
||||
|
||||
/*
|
||||
* Error messages for parser errors
|
||||
*/
|
||||
#define URL_MALFORMED 1
|
||||
#define URL_BAD_SCHEME 2
|
||||
#define URL_BAD_PORT 3
|
||||
static struct fetcherr url_errlist[] = {
|
||||
{ URL_MALFORMED, FETCH_URL, "Malformed URL" },
|
||||
{ URL_BAD_SCHEME, FETCH_URL, "Invalid URL scheme" },
|
||||
{ URL_BAD_PORT, FETCH_URL, "Invalid server port" },
|
||||
{ -1, FETCH_UNKNOWN, "Unknown parser error" }
|
||||
};
|
||||
|
||||
|
||||
/*** Public API **************************************************************/
|
||||
|
||||
/*
|
||||
* Select the appropriate protocol for the URL scheme, and return a
|
||||
* read-only stream connected to the document referenced by the URL.
|
||||
* Also fill out the struct url_stat.
|
||||
*/
|
||||
fetchIO *
|
||||
fetchXGet(struct url *URL, struct url_stat *us, const char *flags)
|
||||
{
|
||||
|
||||
if (us != NULL) {
|
||||
us->size = -1;
|
||||
us->atime = us->mtime = 0;
|
||||
}
|
||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||
return (fetchXGetFile(URL, us, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||
return (fetchXGetFTP(URL, us, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
||||
return (fetchXGetHTTP(URL, us, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
|
||||
return (fetchXGetHTTP(URL, us, flags));
|
||||
url_seterr(URL_BAD_SCHEME);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the appropriate protocol for the URL scheme, and return a
|
||||
* read-only stream connected to the document referenced by the URL.
|
||||
*/
|
||||
fetchIO *
|
||||
fetchGet(struct url *URL, const char *flags)
|
||||
{
|
||||
return (fetchXGet(URL, NULL, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the appropriate protocol for the URL scheme, and return a
|
||||
* write-only stream connected to the document referenced by the URL.
|
||||
*/
|
||||
fetchIO *
|
||||
fetchPut(struct url *URL, const char *flags)
|
||||
{
|
||||
|
||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||
return (fetchPutFile(URL, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||
return (fetchPutFTP(URL, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
||||
return (fetchPutHTTP(URL, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
|
||||
return (fetchPutHTTP(URL, flags));
|
||||
url_seterr(URL_BAD_SCHEME);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the appropriate protocol for the URL scheme, and return the
|
||||
* size of the document referenced by the URL if it exists.
|
||||
*/
|
||||
int
|
||||
fetchStat(struct url *URL, struct url_stat *us, const char *flags)
|
||||
{
|
||||
|
||||
if (us != NULL) {
|
||||
us->size = -1;
|
||||
us->atime = us->mtime = 0;
|
||||
}
|
||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||
return (fetchStatFile(URL, us, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||
return (fetchStatFTP(URL, us, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
||||
return (fetchStatHTTP(URL, us, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
|
||||
return (fetchStatHTTP(URL, us, flags));
|
||||
url_seterr(URL_BAD_SCHEME);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the appropriate protocol for the URL scheme, and return a
|
||||
* list of files in the directory pointed to by the URL.
|
||||
*/
|
||||
int
|
||||
fetchList(struct url_list *ue, struct url *URL, const char *pattern,
|
||||
const char *flags)
|
||||
{
|
||||
|
||||
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
|
||||
return (fetchListFile(ue, URL, pattern, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
|
||||
return (fetchListFTP(ue, URL, pattern, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
|
||||
return (fetchListHTTP(ue, URL, pattern, flags));
|
||||
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
|
||||
return (fetchListHTTP(ue, URL, pattern, flags));
|
||||
url_seterr(URL_BAD_SCHEME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to parse the given URL; if successful, call fetchXGet().
|
||||
*/
|
||||
fetchIO *
|
||||
fetchXGetURL(const char *URL, struct url_stat *us, const char *flags)
|
||||
{
|
||||
struct url *u;
|
||||
fetchIO *f;
|
||||
|
||||
if ((u = fetchParseURL(URL)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
f = fetchXGet(u, us, flags);
|
||||
|
||||
fetchFreeURL(u);
|
||||
return (f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to parse the given URL; if successful, call fetchGet().
|
||||
*/
|
||||
fetchIO *
|
||||
fetchGetURL(const char *URL, const char *flags)
|
||||
{
|
||||
return (fetchXGetURL(URL, NULL, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to parse the given URL; if successful, call fetchPut().
|
||||
*/
|
||||
fetchIO *
|
||||
fetchPutURL(const char *URL, const char *flags)
|
||||
{
|
||||
struct url *u;
|
||||
fetchIO *f;
|
||||
|
||||
if ((u = fetchParseURL(URL)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
f = fetchPut(u, flags);
|
||||
|
||||
fetchFreeURL(u);
|
||||
return (f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to parse the given URL; if successful, call fetchStat().
|
||||
*/
|
||||
int
|
||||
fetchStatURL(const char *URL, struct url_stat *us, const char *flags)
|
||||
{
|
||||
struct url *u;
|
||||
int s;
|
||||
|
||||
if ((u = fetchParseURL(URL)) == NULL)
|
||||
return (-1);
|
||||
|
||||
s = fetchStat(u, us, flags);
|
||||
|
||||
fetchFreeURL(u);
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to parse the given URL; if successful, call fetchList().
|
||||
*/
|
||||
int
|
||||
fetchListURL(struct url_list *ue, const char *URL, const char *pattern,
|
||||
const char *flags)
|
||||
{
|
||||
struct url *u;
|
||||
int rv;
|
||||
|
||||
if ((u = fetchParseURL(URL)) == NULL)
|
||||
return -1;
|
||||
|
||||
rv = fetchList(ue, u, pattern, flags);
|
||||
|
||||
fetchFreeURL(u);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a URL
|
||||
*/
|
||||
struct url *
|
||||
fetchMakeURL(const char *scheme, const char *host, int port, const char *doc,
|
||||
const char *user, const char *pwd)
|
||||
{
|
||||
struct url *u;
|
||||
|
||||
if (!scheme || (!host && !doc)) {
|
||||
url_seterr(URL_MALFORMED);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (port < 0 || port > 65535) {
|
||||
url_seterr(URL_BAD_PORT);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* allocate struct url */
|
||||
if ((u = calloc(1, sizeof(*u))) == NULL) {
|
||||
fetch_syserr();
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((u->doc = strdup(doc ? doc : "/")) == NULL) {
|
||||
fetch_syserr();
|
||||
free(u);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#define seturl(x) snprintf(u->x, sizeof(u->x), "%s", x)
|
||||
seturl(scheme);
|
||||
seturl(host);
|
||||
seturl(user);
|
||||
seturl(pwd);
|
||||
#undef seturl
|
||||
u->port = port;
|
||||
|
||||
return (u);
|
||||
}
|
||||
|
||||
int
|
||||
fetch_urlpath_safe(char x)
|
||||
{
|
||||
if ((x >= '0' && x <= '9') || (x >= 'A' && x <= 'Z') ||
|
||||
(x >= 'a' && x <= 'z'))
|
||||
return 1;
|
||||
|
||||
switch (x) {
|
||||
case '$':
|
||||
case '-':
|
||||
case '_':
|
||||
case '.':
|
||||
case '+':
|
||||
case '!':
|
||||
case '*':
|
||||
case '\'':
|
||||
case '(':
|
||||
case ')':
|
||||
case ',':
|
||||
/* The following are allowed in segment and path components: */
|
||||
case '?':
|
||||
case ':':
|
||||
case '@':
|
||||
case '&':
|
||||
case '=':
|
||||
case '/':
|
||||
case ';':
|
||||
/* If something is already quoted... */
|
||||
case '%':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy an existing URL.
|
||||
*/
|
||||
struct url *
|
||||
fetchCopyURL(const struct url *src)
|
||||
{
|
||||
struct url *dst;
|
||||
char *doc;
|
||||
|
||||
/* allocate struct url */
|
||||
if ((dst = malloc(sizeof(*dst))) == NULL) {
|
||||
fetch_syserr();
|
||||
return (NULL);
|
||||
}
|
||||
if ((doc = strdup(src->doc)) == NULL) {
|
||||
fetch_syserr();
|
||||
free(dst);
|
||||
return (NULL);
|
||||
}
|
||||
*dst = *src;
|
||||
dst->doc = doc;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/*
|
||||
* Split an URL into components. URL syntax is:
|
||||
* [method:/][/[user[:pwd]@]host[:port]/][document]
|
||||
* This almost, but not quite, RFC1738 URL syntax.
|
||||
*/
|
||||
struct url *
|
||||
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) {
|
||||
fetch_syserr();
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
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] != '/') {
|
||||
url_seterr(URL_MALFORMED);
|
||||
goto ouch;
|
||||
}
|
||||
p = URL + 2;
|
||||
goto quote_doc;
|
||||
}
|
||||
if (strncmp(URL, "http:", 5) == 0 ||
|
||||
strncmp(URL, "https:", 6) == 0) {
|
||||
pre_quoted = 1;
|
||||
if (URL[4] == ':') {
|
||||
strcpy(u->scheme, SCHEME_HTTP);
|
||||
URL += 5;
|
||||
} else {
|
||||
strcpy(u->scheme, SCHEME_HTTPS);
|
||||
URL += 6;
|
||||
}
|
||||
|
||||
if (URL[0] != '/' || URL[1] != '/') {
|
||||
url_seterr(URL_MALFORMED);
|
||||
goto ouch;
|
||||
}
|
||||
URL += 2;
|
||||
p = URL;
|
||||
goto find_user;
|
||||
}
|
||||
if (strncmp(URL, "ftp:", 4) == 0) {
|
||||
pre_quoted = 1;
|
||||
strcpy(u->scheme, SCHEME_FTP);
|
||||
URL += 4;
|
||||
if (URL[0] != '/' || URL[1] != '/') {
|
||||
url_seterr(URL_MALFORMED);
|
||||
goto ouch;
|
||||
}
|
||||
URL += 2;
|
||||
p = URL;
|
||||
goto find_user;
|
||||
}
|
||||
|
||||
url_seterr(URL_BAD_SCHEME);
|
||||
goto ouch;
|
||||
|
||||
find_user:
|
||||
p = strpbrk(URL, "/@");
|
||||
if (p != NULL && *p == '@') {
|
||||
/* username */
|
||||
for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++) {
|
||||
if (i < URL_USERLEN)
|
||||
u->user[i++] = *q;
|
||||
}
|
||||
|
||||
/* password */
|
||||
if (*q == ':') {
|
||||
for (q++, i = 0; (*q != '@'); q++)
|
||||
if (i < URL_PWDLEN)
|
||||
u->pwd[i++] = *q;
|
||||
}
|
||||
|
||||
p++;
|
||||
} else {
|
||||
p = URL;
|
||||
}
|
||||
|
||||
/* hostname */
|
||||
#ifdef INET6
|
||||
if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&
|
||||
(*++q == '\0' || *q == '/' || *q == ':')) {
|
||||
if ((i = q - p - 2) > URL_HOSTLEN)
|
||||
i = URL_HOSTLEN;
|
||||
strncpy(u->host, ++p, i);
|
||||
p = q;
|
||||
} else
|
||||
#endif
|
||||
for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
|
||||
if (i < URL_HOSTLEN)
|
||||
u->host[i++] = *p;
|
||||
|
||||
/* port */
|
||||
if (*p == ':') {
|
||||
for (q = ++p; *q && (*q != '/'); q++)
|
||||
if (isdigit((unsigned char)*q))
|
||||
u->port = u->port * 10 + (*q - '0');
|
||||
else {
|
||||
/* invalid port */
|
||||
url_seterr(URL_BAD_PORT);
|
||||
goto ouch;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
/* document */
|
||||
if (!*p)
|
||||
p = "/";
|
||||
|
||||
quote_doc:
|
||||
count = 1;
|
||||
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 ((!pre_quoted && *p == '%') ||
|
||||
!fetch_urlpath_safe(*p)) {
|
||||
u->doc[i++] = '%';
|
||||
if ((unsigned char)*p < 160)
|
||||
u->doc[i++] = '0' + ((unsigned char)*p) / 16;
|
||||
else
|
||||
u->doc[i++] = 'a' - 10 + ((unsigned char)*p) / 16;
|
||||
if ((unsigned char)*p % 16 < 10)
|
||||
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';
|
||||
|
||||
return (u);
|
||||
|
||||
ouch:
|
||||
free(u);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a URL
|
||||
*/
|
||||
void
|
||||
fetchFreeURL(struct url *u)
|
||||
{
|
||||
free(u->doc);
|
||||
free(u);
|
||||
}
|
||||
|
||||
static char
|
||||
xdigit2digit(char digit)
|
||||
{
|
||||
digit = tolower((unsigned char)digit);
|
||||
if (digit >= 'a' && digit <= 'f')
|
||||
digit = digit - 'a' + 10;
|
||||
else
|
||||
digit = digit - '0';
|
||||
|
||||
return digit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unquote whole URL.
|
||||
* Skips optional parts like query or fragment identifier.
|
||||
*/
|
||||
char *
|
||||
fetchUnquotePath(struct url *url)
|
||||
{
|
||||
char *unquoted;
|
||||
const char *iter;
|
||||
size_t i;
|
||||
|
||||
if ((unquoted = malloc(strlen(url->doc) + 1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, iter = url->doc; *iter != '\0'; ++iter) {
|
||||
if (*iter == '#' || *iter == '?')
|
||||
break;
|
||||
if (iter[0] != '%' ||
|
||||
!isxdigit((unsigned char)iter[1]) ||
|
||||
!isxdigit((unsigned char)iter[2])) {
|
||||
unquoted[i++] = *iter;
|
||||
continue;
|
||||
}
|
||||
unquoted[i++] = xdigit2digit(iter[1]) * 16 +
|
||||
xdigit2digit(iter[2]);
|
||||
iter += 2;
|
||||
}
|
||||
unquoted[i] = '\0';
|
||||
return unquoted;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Extract the file name component of a URL.
|
||||
*/
|
||||
char *
|
||||
fetchUnquoteFilename(struct url *url)
|
||||
{
|
||||
char *unquoted, *filename;
|
||||
const char *last_slash;
|
||||
|
||||
if ((unquoted = fetchUnquotePath(url)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((last_slash = strrchr(unquoted, '/')) == NULL)
|
||||
return unquoted;
|
||||
filename = strdup(last_slash + 1);
|
||||
free(unquoted);
|
||||
return filename;
|
||||
}
|
||||
|
||||
char *
|
||||
fetchStringifyURL(const struct url *url)
|
||||
{
|
||||
size_t total;
|
||||
char *doc;
|
||||
|
||||
/* scheme :// user : pwd @ host :port doc */
|
||||
total = strlen(url->scheme) + 3 + strlen(url->user) + 1 +
|
||||
strlen(url->pwd) + 1 + strlen(url->host) + 6 + strlen(url->doc) + 1;
|
||||
if ((doc = malloc(total)) == NULL)
|
||||
return NULL;
|
||||
if (url->port != 0)
|
||||
snprintf(doc, total, "%s%s%s%s%s%s%s:%d%s",
|
||||
url->scheme,
|
||||
url->scheme[0] != '\0' ? "://" : "",
|
||||
url->user,
|
||||
url->pwd[0] != '\0' ? ":" : "",
|
||||
url->pwd,
|
||||
url->user[0] != '\0' || url->pwd[0] != '\0' ? "@" : "",
|
||||
url->host,
|
||||
(int)url->port,
|
||||
url->doc);
|
||||
else {
|
||||
snprintf(doc, total, "%s%s%s%s%s%s%s%s",
|
||||
url->scheme,
|
||||
url->scheme[0] != '\0' ? "://" : "",
|
||||
url->user,
|
||||
url->pwd[0] != '\0' ? ":" : "",
|
||||
url->pwd,
|
||||
url->user[0] != '\0' || url->pwd[0] != '\0' ? "@" : "",
|
||||
url->host,
|
||||
url->doc);
|
||||
}
|
||||
return doc;
|
||||
}
|
526
lib/libfetch/fetch.cat3
Normal file
526
lib/libfetch/fetch.cat3
Normal file
|
@ -0,0 +1,526 @@
|
|||
FETCH(3) NetBSD Library Functions Manual FETCH(3)
|
||||
|
||||
NNAAMMEE
|
||||
ffeettcchhMMaakkeeUURRLL, ffeettcchhPPaarrsseeUURRLL, ffeettcchhCCooppyyUURRLL, ffeettcchhFFrreeeeUURRLL, ffeettcchhXXGGeettUURRLL,
|
||||
ffeettcchhGGeettUURRLL, ffeettcchhPPuuttUURRLL, ffeettcchhSSttaattUURRLL, ffeettcchhLLiissttUURRLL, ffeettcchhXXGGeett,
|
||||
ffeettcchhGGeett, ffeettcchhPPuutt, ffeettcchhSSttaatt, ffeettcchhLLiisstt, ffeettcchhXXGGeettFFiillee, ffeettcchhGGeettFFiillee,
|
||||
ffeettcchhPPuuttFFiillee, ffeettcchhSSttaattFFiillee, ffeettcchhLLiissttFFiillee, ffeettcchhXXGGeettHHTTTTPP, ffeettcchhGGeettHHTTTTPP,
|
||||
ffeettcchhPPuuttHHTTTTPP, ffeettcchhSSttaattHHTTTTPP, ffeettcchhLLiissttHHTTTTPP, ffeettcchhXXGGeettFFTTPP, ffeettcchhGGeettFFTTPP,
|
||||
ffeettcchhPPuuttFFTTPP, ffeettcchhSSttaattFFTTPP, ffeettcchhLLiissttFFTTPP ffeettcchhIInniittUURRLLLLiisstt,
|
||||
ffeettcchhFFrreeeeUURRLLLLiisstt, ffeettcchhUUnnqquuootteePPaatthh, ffeettcchhUUnnqquuootteeFFiilleennaammee,
|
||||
ffeettcchhSSttrriinnggiiffyyUURRLL, ffeettcchhCCoonnnneeccttiioonnCCaacchheeIInniitt, ffeettcchhCCoonnnneeccttiioonnCCaacchheeCClloossee,
|
||||
ffeettcchh -- file transfer functions
|
||||
|
||||
LLIIBBRRAARRYY
|
||||
File Transfer Library for URLs (libfetch, -lfetch)
|
||||
|
||||
SSYYNNOOPPSSIISS
|
||||
##iinncclluuddee <<ssttddiioo..hh>>
|
||||
##iinncclluuddee <<ffeettcchh..hh>>
|
||||
|
||||
_s_t_r_u_c_t _u_r_l _*
|
||||
ffeettcchhMMaakkeeUURRLL(_c_o_n_s_t _c_h_a_r _*_s_c_h_e_m_e, _c_o_n_s_t _c_h_a_r _*_h_o_s_t, _i_n_t _p_o_r_t,
|
||||
_c_o_n_s_t _c_h_a_r _*_d_o_c, _c_o_n_s_t _c_h_a_r _*_u_s_e_r, _c_o_n_s_t _c_h_a_r _*_p_w_d);
|
||||
|
||||
_s_t_r_u_c_t _u_r_l _*
|
||||
ffeettcchhPPaarrsseeUURRLL(_c_o_n_s_t _c_h_a_r _*_U_R_L);
|
||||
|
||||
_s_t_r_u_c_t _u_r_l _*
|
||||
ffeettcchhCCooppyyUURRLL(_c_o_n_s_t _s_t_r_u_c_t _u_r_l _*_u);
|
||||
|
||||
_v_o_i_d
|
||||
ffeettcchhFFrreeeeUURRLL(_s_t_r_u_c_t _u_r_l _*_u);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhXXGGeettUURRLL(_c_o_n_s_t _c_h_a_r _*_U_R_L, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhGGeettUURRLL(_c_o_n_s_t _c_h_a_r _*_U_R_L, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhPPuuttUURRLL(_c_o_n_s_t _c_h_a_r _*_U_R_L, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhSSttaattUURRLL(_c_o_n_s_t _c_h_a_r _*_U_R_L, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhLLiissttUURRLL(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_l_i_s_t, _c_o_n_s_t _c_h_a_r _*_U_R_L, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhXXGGeett(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhGGeett(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhPPuutt(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhSSttaatt(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhLLiisstt(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_l_i_s_t, _s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhXXGGeettFFiillee(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhGGeettFFiillee(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhPPuuttFFiillee(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhSSttaattFFiillee(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhLLiissttFFiillee(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_l_i_s_t, _s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhXXGGeettHHTTTTPP(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhGGeettHHTTTTPP(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhPPuuttHHTTTTPP(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhSSttaattHHTTTTPP(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhLLiissttHHTTTTPP(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_l_i_s_t, _s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhXXGGeettFFTTPP(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhGGeettFFTTPP(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_f_e_t_c_h_I_O _*
|
||||
ffeettcchhPPuuttFFTTPP(_s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhSSttaattFFTTPP(_s_t_r_u_c_t _u_r_l _*_u, _s_t_r_u_c_t _u_r_l___s_t_a_t _*_u_s, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhLLiissttFFTTPP(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_l_i_s_t, _s_t_r_u_c_t _u_r_l _*_u, _c_o_n_s_t _c_h_a_r _*_f_l_a_g_s);
|
||||
|
||||
_v_o_i_d
|
||||
ffeettcchhIInniittUURRLLLLiisstt(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_u_l);
|
||||
|
||||
_i_n_t
|
||||
ffeettcchhAAppppeennddUURRLLLLiisstt(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_d_s_t, _c_o_n_s_t _s_t_r_u_c_t _u_r_l___l_i_s_t _*_s_r_c);
|
||||
|
||||
_v_o_i_d
|
||||
ffeettcchhFFrreeeeUURRLLLLiisstt(_s_t_r_u_c_t _u_r_l___l_i_s_t _*_u_l);
|
||||
|
||||
_c_h_a_r _*
|
||||
ffeettcchhUUnnqquuootteePPaatthh(_s_t_r_u_c_t _u_r_l _*_u);
|
||||
|
||||
_c_h_a_r _*
|
||||
ffeettcchhUUnnqquuootteeFFiilleennaammee(_s_t_r_u_c_t _u_r_l _*_u);
|
||||
|
||||
_c_h_a_r _*
|
||||
ffeettcchhSSttrriinnggiiffyyUURRLL(_c_o_n_s_t _s_t_r_u_c_t _u_r_l _*_u);
|
||||
|
||||
_v_o_i_d
|
||||
ffeettcchhCCoonnnneeccttiioonnCCaacchheeIInniitt(_i_n_t _g_l_o_b_a_l, _i_n_t _p_e_r___h_o_s_t);
|
||||
|
||||
_v_o_i_d
|
||||
ffeettcchhCCoonnnneeccttiioonnCCaacchheeCClloossee(_v_o_i_d);
|
||||
|
||||
DDEESSCCRRIIPPTTIIOONN
|
||||
These functions implement a high-level library for retrieving and upload-
|
||||
ing files using Uniform Resource Locators (URLs).
|
||||
|
||||
ffeettcchhPPaarrsseeUURRLL() 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 detailed in RFC 1738. A regular expression which produces
|
||||
this syntax is:
|
||||
|
||||
<scheme>:(//(<user>(:<pwd>)?@)?<host>(:<port>)?)?/(<document>)?
|
||||
|
||||
If the URL does not seem to begin with a scheme name, it is assumed to be
|
||||
a local path. Only absolute path names are accepted.
|
||||
|
||||
Note that some components of the URL are not necessarily relevant to all
|
||||
URL schemes. For instance, the file scheme only needs the <scheme> and
|
||||
<document> components. ffeettcchhPPaarrsseeUURRLL() quotes any unsafe character in
|
||||
the URL automatically. This is not done by ffeettcchhMMaakkeeUURRLL().
|
||||
ffeettcchhCCooppyyUURRLL() copies an existing _u_r_l structure.
|
||||
|
||||
ffeettcchhMMaakkeeUURRLL(), ffeettcchhPPaarrsseeUURRLL(), and ffeettcchhCCooppyyUURRLL() return a pointer to a
|
||||
_u_r_l structure, which is defined as follows in <_f_e_t_c_h_._h>:
|
||||
|
||||
#define URL_SCHEMELEN 16
|
||||
#define URL_USERLEN 256
|
||||
#define URL_PWDLEN 256
|
||||
#define URL_HOSTLEN 255
|
||||
|
||||
struct url {
|
||||
char scheme[URL_SCHEMELEN + 1];
|
||||
char user[URL_USERLEN + 1];
|
||||
char pwd[URL_PWDLEN + 1];
|
||||
char host[URL_HOSTLEN + 1];
|
||||
int port;
|
||||
char *doc;
|
||||
off_t offset;
|
||||
size_t length;
|
||||
time_t last_modified;
|
||||
};
|
||||
|
||||
The pointer returned by ffeettcchhMMaakkeeUURRLL(), ffeettcchhCCooppyyUURRLL(), and
|
||||
ffeettcchhPPaarrsseeUURRLL() should be freed using ffeettcchhFFrreeeeUURRLL(). The size of _s_t_r_u_c_t
|
||||
_U_R_L is not part of the ABI.
|
||||
|
||||
ffeettcchhXXGGeettUURRLL(), ffeettcchhGGeettUURRLL(), and ffeettcchhPPuuttUURRLL() constitute the recom-
|
||||
mended interface to the ffeettcchh library. They examine the URL passed to
|
||||
them to determine the transfer method, and call the appropriate lower-
|
||||
level functions to perform the actual transfer. ffeettcchhXXGGeettUURRLL() also
|
||||
returns the remote document's metadata in the _u_r_l___s_t_a_t structure pointed
|
||||
to by the _u_s argument.
|
||||
|
||||
The _f_l_a_g_s argument is a string of characters which specify transfer
|
||||
options. The meaning of the individual flags is scheme-dependent, and is
|
||||
detailed in the appropriate section below.
|
||||
|
||||
ffeettcchhSSttaattUURRLL() attempts to obtain the requested document's metadata and
|
||||
fill in the structure pointed to by its second argument. The _u_r_l___s_t_a_t
|
||||
structure is defined as follows in <_f_e_t_c_h_._h>:
|
||||
|
||||
struct url_stat {
|
||||
off_t size;
|
||||
time_t atime;
|
||||
time_t mtime;
|
||||
};
|
||||
|
||||
If the size could not be obtained from the server, the _s_i_z_e field is set
|
||||
to -1. If the modification time could not be obtained from the server,
|
||||
the _m_t_i_m_e field is set to the epoch. If the access time could not be
|
||||
obtained from the server, the _a_t_i_m_e field is set to the modification
|
||||
time.
|
||||
|
||||
ffeettcchhLLiissttUURRLL() attempts to list the contents of the directory pointed to
|
||||
by the URL provided. The pattern can be a simple glob-like expression as
|
||||
hint. Callers should not depend on the server to filter names. If suc-
|
||||
cessful, it appends the list of entries to the _u_r_l___l_i_s_t structure. The
|
||||
_u_r_l___l_i_s_t structure is defined as follows in <_f_e_t_c_h_._h>:
|
||||
|
||||
struct url_list {
|
||||
size_t length;
|
||||
size_t alloc_size;
|
||||
struct url *urls;
|
||||
};
|
||||
|
||||
The list should be initialized by calling ffeettcchhIInniittUURRLLLLiisstt() and the
|
||||
entries be freed by calling ffeettcchhFFrreeeeUURRLLLLiisstt(). The function
|
||||
ffeettcchhAAppppeennddUURRLLLLiisstt() can be used to append one URL lists to another. If
|
||||
the `c' (cache result) flag is specified, the library is allowed to
|
||||
internally cache the result.
|
||||
|
||||
ffeettcchhSSttrriinnggiiffyyUURRLL() returns the URL as string. ffeettcchhUUnnqquuootteePPaatthh()
|
||||
returns the path name part of the URL with any quoting undone. Query
|
||||
arguments and fragment identifiers are not included.
|
||||
ffeettcchhUUnnqquuootteeFFiilleennaammee() returns the last component of the path name as
|
||||
returned by ffeettcchhUUnnqquuootteePPaatthh(). ffeettcchhSSttrriinnggiiffyyUURRLL(), ffeettcchhUUnnqquuootteePPaatthh(),
|
||||
and ffeettcchhUUnnqquuootteeFFiilleennaammee() return a string that should be deallocated
|
||||
with ffrreeee() after use.
|
||||
|
||||
ffeettcchhCCoonnnneeccttiioonnCCaacchheeIInniitt() enables the connection cache. The first argu-
|
||||
ment specifies the global limit on cached connections. The second argu-
|
||||
ment specifies the host limit. Entries are considered to specify the
|
||||
same host, if the host name from the URL is identical, indepent of the
|
||||
address or address family. ffeettcchhCCoonnnneeccttiioonnCCaacchheeCClloossee() flushed the con-
|
||||
nection cache and closes all cached connections.
|
||||
|
||||
ffeettcchhXXGGeett(), ffeettcchhGGeett(), ffeettcchhPPuutt(), and ffeettcchhSSttaatt() are similar to
|
||||
ffeettcchhXXGGeettUURRLL(), ffeettcchhGGeettUURRLL(), ffeettcchhPPuuttUURRLL(), and ffeettcchhSSttaattUURRLL(), except
|
||||
that they expect a pre-parsed URL in the form of a pointer to a _s_t_r_u_c_t
|
||||
_u_r_l rather than a string.
|
||||
|
||||
All of the ffeettcchhXXGGeettXXXXXX(), ffeettcchhGGeettXXXXXX(), and ffeettcchhPPuuttXXXXXX() functions
|
||||
return a pointer to a stream which can be used to read or write data from
|
||||
or to the requested document, respectively. Note that although the
|
||||
implementation details of the individual access methods vary, it can gen-
|
||||
erally be assumed that a stream returned by one of the ffeettcchhXXGGeettXXXXXX() or
|
||||
ffeettcchhGGeettXXXXXX() functions is read-only, and that a stream returned by one
|
||||
of the ffeettcchhPPuuttXXXXXX() functions is write-only.
|
||||
|
||||
PPRROOTTOOCCOOLL IINNDDEEPPEENNDDEENNTT FFLLAAGGSS
|
||||
If the `i' (if-modified-since) flag is specified, the library will try to
|
||||
fetch the content only if it is newer than _l_a_s_t___m_o_d_i_f_i_e_d. For HTTP an
|
||||
If-Modified-Since HTTP header is sent. For FTP a MTDM command is sent
|
||||
first and compared locally. For FILE the source file is compared.
|
||||
|
||||
FFIILLEE SSCCHHEEMMEE
|
||||
ffeettcchhXXGGeettFFiillee(), ffeettcchhGGeettFFiillee(), and ffeettcchhPPuuttFFiillee() provide access to
|
||||
documents which are files in a locally mounted file system. Only the
|
||||
<document> component of the URL is used.
|
||||
|
||||
ffeettcchhXXGGeettFFiillee() and ffeettcchhGGeettFFiillee() do not accept any flags.
|
||||
|
||||
ffeettcchhPPuuttFFiillee() accepts the `a' (append to file) flag. If that flag is
|
||||
specified, the data written to the stream returned by ffeettcchhPPuuttFFiillee() will
|
||||
be appended to the previous contents of the file, instead of replacing
|
||||
them.
|
||||
|
||||
FFTTPP SSCCHHEEMMEE
|
||||
ffeettcchhXXGGeettFFTTPP(), ffeettcchhGGeettFFTTPP(), and ffeettcchhPPuuttFFTTPP() implement the FTP proto-
|
||||
col as described in RFC 959.
|
||||
|
||||
By default lliibbffeettcchh will attempt to use passive mode first and only fall-
|
||||
back to active mode if the server reports a syntax error. If the `a'
|
||||
(active) flag is specified, a passive connection is not tried and active
|
||||
mode is used directly.
|
||||
|
||||
If the `l' (low) flag is specified, data sockets will be allocated in the
|
||||
low (or default) port range instead of the high port range (see ip(4)).
|
||||
|
||||
If the `d' (direct) flag is specified, ffeettcchhXXGGeettFFTTPP(), ffeettcchhGGeettFFTTPP(), and
|
||||
ffeettcchhPPuuttFFTTPP() will use a direct connection even if a proxy server is
|
||||
defined.
|
||||
|
||||
If no user name or password is given, the ffeettcchh library will attempt an
|
||||
anonymous login, with user name "anonymous" and password "anony-
|
||||
mous@<hostname>".
|
||||
|
||||
HHTTTTPP SSCCHHEEMMEE
|
||||
The ffeettcchhXXGGeettHHTTTTPP(), ffeettcchhGGeettHHTTTTPP(), and ffeettcchhPPuuttHHTTTTPP() functions imple-
|
||||
ment the HTTP/1.1 protocol. With a little luck, there is even a chance
|
||||
that they comply with RFC 2616 and RFC 2617.
|
||||
|
||||
If the `d' (direct) flag is specified, ffeettcchhXXGGeettHHTTTTPP(), ffeettcchhGGeettHHTTTTPP(),
|
||||
and ffeettcchhPPuuttHHTTTTPP() will use a direct connection even if a proxy server is
|
||||
defined.
|
||||
|
||||
Since there seems to be no good way of implementing the HTTP PUT method
|
||||
in a manner consistent with the rest of the ffeettcchh library, ffeettcchhPPuuttHHTTTTPP()
|
||||
is currently unimplemented.
|
||||
|
||||
AAUUTTHHEENNTTIICCAATTIIOONN
|
||||
Apart from setting the appropriate environment variables and specifying
|
||||
the user name and password in the URL or the _s_t_r_u_c_t _u_r_l, the calling pro-
|
||||
gram has the option of defining an authentication function with the fol-
|
||||
lowing prototype:
|
||||
|
||||
_i_n_t mmyyAAuutthhMMeetthhoodd(_s_t_r_u_c_t _u_r_l _*_u)
|
||||
|
||||
The callback function should fill in the _u_s_e_r and _p_w_d fields in the pro-
|
||||
vided _s_t_r_u_c_t _u_r_l and return 0 on success, or any other value to indicate
|
||||
failure.
|
||||
|
||||
To register the authentication callback, simply set _f_e_t_c_h_A_u_t_h_M_e_t_h_o_d to
|
||||
point at it. The callback will be used whenever a site requires authen-
|
||||
tication and the appropriate environment variables are not set.
|
||||
|
||||
This interface is experimental and may be subject to change.
|
||||
|
||||
RREETTUURRNN VVAALLUUEESS
|
||||
ffeettcchhPPaarrsseeUURRLL() returns a pointer to a _s_t_r_u_c_t _u_r_l containing the individ-
|
||||
ual components of the URL. If it is unable to allocate memory, or the
|
||||
URL is syntactically incorrect, ffeettcchhPPaarrsseeUURRLL() returns a NULL pointer.
|
||||
|
||||
The ffeettcchhSSttaatt() functions return 0 on success and -1 on failure.
|
||||
|
||||
All other functions return a stream pointer which may be used to access
|
||||
the requested document, or NULL if an error occurred.
|
||||
|
||||
The following error codes are defined in <_f_e_t_c_h_._h>:
|
||||
|
||||
[FETCH_ABORT] Operation aborted
|
||||
|
||||
[FETCH_AUTH] Authentication failed
|
||||
|
||||
[FETCH_DOWN] Service unavailable
|
||||
|
||||
[FETCH_EXISTS] File exists
|
||||
|
||||
[FETCH_FULL] File system full
|
||||
|
||||
[FETCH_INFO] Informational response
|
||||
|
||||
[FETCH_MEMORY] Insufficient memory
|
||||
|
||||
[FETCH_MOVED] File has moved
|
||||
|
||||
[FETCH_NETWORK] Network error
|
||||
|
||||
[FETCH_OK] No error
|
||||
|
||||
[FETCH_PROTO] Protocol error
|
||||
|
||||
[FETCH_RESOLV] Resolver error
|
||||
|
||||
[FETCH_SERVER] Server error
|
||||
|
||||
[FETCH_TEMP] Temporary error
|
||||
|
||||
[FETCH_TIMEOUT] Operation timed out
|
||||
|
||||
[FETCH_UNAVAIL] File is not available
|
||||
|
||||
[FETCH_UNKNOWN] Unknown error
|
||||
|
||||
[FETCH_URL] Invalid URL
|
||||
|
||||
The accompanying error message includes a protocol-specific error code
|
||||
and message, e.g. "File is not available (404 Not Found)"
|
||||
|
||||
EENNVVIIRROONNMMEENNTT
|
||||
FETCH_BIND_ADDRESS Specifies a host name or IP address to which sockets
|
||||
used for outgoing connections will be bound.
|
||||
|
||||
FTP_LOGIN Default FTP login if none was provided in the URL.
|
||||
|
||||
FTP_PASSIVE_MODE If set to anything but `no', forces the FTP code to
|
||||
use passive mode.
|
||||
|
||||
FTP_PASSWORD Default FTP password if the remote server requests
|
||||
one and none was provided in the URL.
|
||||
|
||||
FTP_PROXY URL of the proxy to use for FTP requests. The docu-
|
||||
ment part is ignored. FTP and HTTP proxies are sup-
|
||||
ported; if no scheme is specified, FTP is assumed.
|
||||
If the proxy is an FTP proxy, lliibbffeettcchh will send
|
||||
`user@host' as user name to the proxy, where `user'
|
||||
is the real user name, and `host' is the name of the
|
||||
FTP server.
|
||||
|
||||
If this variable is set to an empty string, no proxy
|
||||
will be used for FTP requests, even if the HTTP_PROXY
|
||||
variable is set.
|
||||
|
||||
ftp_proxy Same as FTP_PROXY, for compatibility.
|
||||
|
||||
HTTP_AUTH Specifies HTTP authorization parameters as a colon-
|
||||
separated list of items. The first and second item
|
||||
are the authorization scheme and realm respectively;
|
||||
further items are scheme-dependent. Currently, only
|
||||
basic authorization is supported.
|
||||
|
||||
Basic authorization requires two parameters: the user
|
||||
name and password, in that order.
|
||||
|
||||
This variable is only used if the server requires
|
||||
authorization and no user name or password was speci-
|
||||
fied in the URL.
|
||||
|
||||
HTTP_PROXY URL of the proxy to use for HTTP requests. The docu-
|
||||
ment part is ignored. Only HTTP proxies are sup-
|
||||
ported for HTTP requests. If no port number is spec-
|
||||
ified, the default is 3128.
|
||||
|
||||
Note that this proxy will also be used for FTP docu-
|
||||
ments, unless the FTP_PROXY variable is set.
|
||||
|
||||
http_proxy Same as HTTP_PROXY, for compatibility.
|
||||
|
||||
HTTP_PROXY_AUTH Specifies authorization parameters for the HTTP proxy
|
||||
in the same format as the HTTP_AUTH variable.
|
||||
|
||||
This variable is used if and only if connected to an
|
||||
HTTP proxy, and is ignored if a user and/or a pass-
|
||||
word were specified in the proxy URL.
|
||||
|
||||
HTTP_REFERER Specifies the referrer URL to use for HTTP requests.
|
||||
If set to ``auto'', the document URL will be used as
|
||||
referrer URL.
|
||||
|
||||
HTTP_USER_AGENT Specifies the User-Agent string to use for HTTP
|
||||
requests. This can be useful when working with HTTP
|
||||
origin or proxy servers that differentiate between
|
||||
user agents.
|
||||
|
||||
NETRC Specifies a file to use instead of _~_/_._n_e_t_r_c to look
|
||||
up login names and passwords for FTP sites. See
|
||||
ftp(1) for a description of the file format. This
|
||||
feature is experimental.
|
||||
|
||||
NO_PROXY Either a single asterisk, which disables the use of
|
||||
proxies altogether, or a comma- or whitespace-sepa-
|
||||
rated list of hosts for which proxies should not be
|
||||
used.
|
||||
|
||||
no_proxy Same as NO_PROXY, for compatibility.
|
||||
|
||||
EEXXAAMMPPLLEESS
|
||||
To access a proxy server on _p_r_o_x_y_._e_x_a_m_p_l_e_._c_o_m port 8080, set the
|
||||
HTTP_PROXY environment variable in a manner similar to this:
|
||||
|
||||
HTTP_PROXY=http://proxy.example.com:8080
|
||||
|
||||
If the proxy server requires authentication, there are two options avail-
|
||||
able for passing the authentication data. The first method is by using
|
||||
the proxy URL:
|
||||
|
||||
HTTP_PROXY=http://<user>:<pwd>@proxy.example.com:8080
|
||||
|
||||
The second method is by using the HTTP_PROXY_AUTH environment variable:
|
||||
|
||||
HTTP_PROXY=http://proxy.example.com:8080
|
||||
HTTP_PROXY_AUTH=basic:*:<user>:<pwd>
|
||||
|
||||
To disable the use of a proxy for an HTTP server running on the local
|
||||
host, define NO_PROXY as follows:
|
||||
|
||||
NO_PROXY=localhost,127.0.0.1
|
||||
|
||||
SSEEEE AALLSSOO
|
||||
ftp(1), ip(4)
|
||||
|
||||
J. Postel and J. K. Reynolds, _F_i_l_e _T_r_a_n_s_f_e_r _P_r_o_t_o_c_o_l, October 1985, RFC
|
||||
959.
|
||||
|
||||
P. Deutsch, A. Emtage, and A. Marine, _H_o_w _t_o _U_s_e _A_n_o_n_y_m_o_u_s _F_T_P, May 1994,
|
||||
RFC 1635.
|
||||
|
||||
T. Berners-Lee, L. Masinter, and M. McCahill, _U_n_i_f_o_r_m _R_e_s_o_u_r_c_e _L_o_c_a_t_o_r_s
|
||||
_(_U_R_L_), December 1994, RFC 1738.
|
||||
|
||||
R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, and
|
||||
T. Berners-Lee, _H_y_p_e_r_t_e_x_t _T_r_a_n_s_f_e_r _P_r_o_t_o_c_o_l _-_- _H_T_T_P_/_1_._1, January 1999,
|
||||
RFC 2616.
|
||||
|
||||
J. Franks, P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A.
|
||||
Luotonen, and L. Stewart, _H_T_T_P _A_u_t_h_e_n_t_i_c_a_t_i_o_n_: _B_a_s_i_c _a_n_d _D_i_g_e_s_t _A_c_c_e_s_s
|
||||
_A_u_t_h_e_n_t_i_c_a_t_i_o_n, June 1999, RFC 2617.
|
||||
|
||||
HHIISSTTOORRYY
|
||||
The ffeettcchh library first appeared in FreeBSD 3.0.
|
||||
|
||||
AAUUTTHHOORRSS
|
||||
The ffeettcchh library was mostly written by Dag-Erling Smørgrav
|
||||
<des@FreeBSD.org> with numerous suggestions from Jordan K. Hubbard
|
||||
<jkh@FreeBSD.org>, Eugene Skepner <eu@qub.com> and other FreeBSD develop-
|
||||
ers. It replaces the older ffttppiioo library written by Poul-Henning Kamp
|
||||
<phk@FreeBSD.org> and Jordan K. Hubbard <jkh@FreeBSD.org>.
|
||||
|
||||
This manual page was written by Dag-Erling Smørgrav <des@FreeBSD.org>.
|
||||
|
||||
BBUUGGSS
|
||||
Some parts of the library are not yet implemented. The most notable
|
||||
examples of this are ffeettcchhPPuuttHHTTTTPP() and FTP proxy support.
|
||||
|
||||
There is no way to select a proxy at run-time other than setting the
|
||||
HTTP_PROXY or FTP_PROXY environment variables as appropriate.
|
||||
|
||||
lliibbffeettcchh does not understand or obey 305 (Use Proxy) replies.
|
||||
|
||||
Error numbers are unique only within a certain context; the error codes
|
||||
used for FTP and HTTP overlap, as do those used for resolver and system
|
||||
errors. For instance, error code 202 means "Command not implemented,
|
||||
superfluous at this site" in an FTP context and "Accepted" in an HTTP
|
||||
context.
|
||||
|
||||
ffeettcchhSSttaattFFTTPP() does not check that the result of an MDTM command is a
|
||||
valid date.
|
||||
|
||||
The man page is incomplete, poorly written and produces badly formatted
|
||||
text.
|
||||
|
||||
The error reporting mechanism is unsatisfactory.
|
||||
|
||||
Some parts of the code are not fully reentrant.
|
||||
|
||||
NetBSD 5.0 January 22, 2010 NetBSD 5.0
|
187
lib/libfetch/fetch.h
Normal file
187
lib/libfetch/fetch.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
/* $NetBSD: fetch.h,v 1.16 2010/01/22 13:21:09 joerg Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: fetch.h,v 1.26 2004/09/21 18:35:20 des Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FETCH_H_INCLUDED
|
||||
#define _FETCH_H_INCLUDED
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define _LIBFETCH_VER "libfetch/2.0"
|
||||
|
||||
#define URL_HOSTLEN 255
|
||||
#define URL_SCHEMELEN 16
|
||||
#define URL_USERLEN 256
|
||||
#define URL_PWDLEN 256
|
||||
|
||||
typedef struct fetchIO fetchIO;
|
||||
|
||||
struct url {
|
||||
char scheme[URL_SCHEMELEN + 1];
|
||||
char user[URL_USERLEN + 1];
|
||||
char pwd[URL_PWDLEN + 1];
|
||||
char host[URL_HOSTLEN + 1];
|
||||
int port;
|
||||
char *doc;
|
||||
off_t offset;
|
||||
size_t length;
|
||||
time_t last_modified;
|
||||
};
|
||||
|
||||
struct url_stat {
|
||||
off_t size;
|
||||
time_t atime;
|
||||
time_t mtime;
|
||||
};
|
||||
|
||||
struct url_list {
|
||||
size_t length;
|
||||
size_t alloc_size;
|
||||
struct url *urls;
|
||||
};
|
||||
|
||||
/* Recognized schemes */
|
||||
#define SCHEME_FTP "ftp"
|
||||
#define SCHEME_HTTP "http"
|
||||
#define SCHEME_HTTPS "https"
|
||||
#define SCHEME_FILE "file"
|
||||
|
||||
/* Error codes */
|
||||
#define FETCH_ABORT 1
|
||||
#define FETCH_AUTH 2
|
||||
#define FETCH_DOWN 3
|
||||
#define FETCH_EXISTS 4
|
||||
#define FETCH_FULL 5
|
||||
#define FETCH_INFO 6
|
||||
#define FETCH_MEMORY 7
|
||||
#define FETCH_MOVED 8
|
||||
#define FETCH_NETWORK 9
|
||||
#define FETCH_OK 10
|
||||
#define FETCH_PROTO 11
|
||||
#define FETCH_RESOLV 12
|
||||
#define FETCH_SERVER 13
|
||||
#define FETCH_TEMP 14
|
||||
#define FETCH_TIMEOUT 15
|
||||
#define FETCH_UNAVAIL 16
|
||||
#define FETCH_UNKNOWN 17
|
||||
#define FETCH_URL 18
|
||||
#define FETCH_VERBOSE 19
|
||||
#define FETCH_UNCHANGED 20
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void fetchIO_close(fetchIO *);
|
||||
ssize_t fetchIO_read(fetchIO *, void *, size_t);
|
||||
ssize_t fetchIO_write(fetchIO *, const void *, size_t);
|
||||
|
||||
/* fetchIO-specific functions */
|
||||
fetchIO *fetchXGetFile(struct url *, struct url_stat *, const char *);
|
||||
fetchIO *fetchGetFile(struct url *, const char *);
|
||||
fetchIO *fetchPutFile(struct url *, const char *);
|
||||
int fetchStatFile(struct url *, struct url_stat *, const char *);
|
||||
int fetchListFile(struct url_list *, struct url *, const char *,
|
||||
const char *);
|
||||
|
||||
/* HTTP-specific functions */
|
||||
fetchIO *fetchXGetHTTP(struct url *, struct url_stat *, const char *);
|
||||
fetchIO *fetchGetHTTP(struct url *, const char *);
|
||||
fetchIO *fetchPutHTTP(struct url *, const char *);
|
||||
int fetchStatHTTP(struct url *, struct url_stat *, const char *);
|
||||
int fetchListHTTP(struct url_list *, struct url *, const char *,
|
||||
const char *);
|
||||
|
||||
/* FTP-specific functions */
|
||||
fetchIO *fetchXGetFTP(struct url *, struct url_stat *, const char *);
|
||||
fetchIO *fetchGetFTP(struct url *, const char *);
|
||||
fetchIO *fetchPutFTP(struct url *, const char *);
|
||||
int fetchStatFTP(struct url *, struct url_stat *, const char *);
|
||||
int fetchListFTP(struct url_list *, struct url *, const char *,
|
||||
const char *);
|
||||
|
||||
/* Generic functions */
|
||||
fetchIO *fetchXGetURL(const char *, struct url_stat *, const char *);
|
||||
fetchIO *fetchGetURL(const char *, const char *);
|
||||
fetchIO *fetchPutURL(const char *, const char *);
|
||||
int fetchStatURL(const char *, struct url_stat *, const char *);
|
||||
int fetchListURL(struct url_list *, const char *, const char *,
|
||||
const char *);
|
||||
fetchIO *fetchXGet(struct url *, struct url_stat *, const char *);
|
||||
fetchIO *fetchGet(struct url *, const char *);
|
||||
fetchIO *fetchPut(struct url *, const char *);
|
||||
int fetchStat(struct url *, struct url_stat *, const char *);
|
||||
int fetchList(struct url_list *, struct url *, const char *,
|
||||
const char *);
|
||||
|
||||
/* URL parsing */
|
||||
struct url *fetchMakeURL(const char *, const char *, int,
|
||||
const char *, const char *, const char *);
|
||||
struct url *fetchParseURL(const char *);
|
||||
struct url *fetchCopyURL(const struct url *);
|
||||
char *fetchStringifyURL(const struct url *);
|
||||
void fetchFreeURL(struct url *);
|
||||
|
||||
/* URL listening */
|
||||
void fetchInitURLList(struct url_list *);
|
||||
int fetchAppendURLList(struct url_list *, const struct url_list *);
|
||||
void fetchFreeURLList(struct url_list *);
|
||||
char *fetchUnquotePath(struct url *);
|
||||
char *fetchUnquoteFilename(struct url *);
|
||||
|
||||
/* Connection caching */
|
||||
void fetchConnectionCacheInit(int, int);
|
||||
void fetchConnectionCacheClose(void);
|
||||
|
||||
/* Authentication */
|
||||
typedef int (*auth_t)(struct url *);
|
||||
extern auth_t fetchAuthMethod;
|
||||
|
||||
/* Last error code */
|
||||
extern int fetchLastErrCode;
|
||||
#define MAXERRSTRING 256
|
||||
extern char fetchLastErrString[MAXERRSTRING];
|
||||
|
||||
/* I/O timeout */
|
||||
extern int fetchTimeout;
|
||||
|
||||
/* Restart interrupted syscalls */
|
||||
extern volatile int fetchRestartCalls;
|
||||
|
||||
/* Extra verbosity */
|
||||
extern int fetchDebug;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
265
lib/libfetch/file.c
Normal file
265
lib/libfetch/file.c
Normal file
|
@ -0,0 +1,265 @@
|
|||
/* $NetBSD: file.c,v 1.15 2009/10/15 12:36:57 joerg Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: file.c,v 1.18 2007/12/14 10:26:58 des Exp $
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#if !defined(NETBSD) && !defined(__minix)
|
||||
#include <nbcompat.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fetch.h"
|
||||
#include "common.h"
|
||||
|
||||
static int fetch_stat_file(int, struct url_stat *);
|
||||
|
||||
static ssize_t
|
||||
fetchFile_read(void *cookie, void *buf, size_t len)
|
||||
{
|
||||
return read(*(int *)cookie, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
fetchFile_write(void *cookie, const void *buf, size_t len)
|
||||
{
|
||||
return write(*(int *)cookie, buf, len);
|
||||
}
|
||||
|
||||
static void
|
||||
fetchFile_close(void *cookie)
|
||||
{
|
||||
int fd = *(int *)cookie;
|
||||
|
||||
free(cookie);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fetchIO *
|
||||
fetchXGetFile(struct url *u, struct url_stat *us, const char *flags)
|
||||
{
|
||||
char *path;
|
||||
fetchIO *f;
|
||||
struct url_stat local_us;
|
||||
int if_modified_since, fd, *cookie;
|
||||
|
||||
if_modified_since = CHECK_FLAG('i');
|
||||
if (if_modified_since && us == NULL)
|
||||
us = &local_us;
|
||||
|
||||
if ((path = fetchUnquotePath(u)) == NULL) {
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
free(path);
|
||||
if (fd == -1) {
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (us && fetch_stat_file(fd, us) == -1) {
|
||||
close(fd);
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (if_modified_since && u->last_modified > 0 &&
|
||||
u->last_modified >= us->mtime) {
|
||||
close(fd);
|
||||
fetchLastErrCode = FETCH_UNCHANGED;
|
||||
snprintf(fetchLastErrString, MAXERRSTRING, "Unchanged");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (u->offset && lseek(fd, u->offset, SEEK_SET) == -1) {
|
||||
close(fd);
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cookie = malloc(sizeof(int));
|
||||
if (cookie == NULL) {
|
||||
close(fd);
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*cookie = fd;
|
||||
f = fetchIO_unopen(cookie, fetchFile_read, fetchFile_write, fetchFile_close);
|
||||
if (f == NULL) {
|
||||
close(fd);
|
||||
free(cookie);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
fetchIO *
|
||||
fetchGetFile(struct url *u, const char *flags)
|
||||
{
|
||||
return (fetchXGetFile(u, NULL, flags));
|
||||
}
|
||||
|
||||
fetchIO *
|
||||
fetchPutFile(struct url *u, const char *flags)
|
||||
{
|
||||
char *path;
|
||||
fetchIO *f;
|
||||
int fd, *cookie;
|
||||
|
||||
if ((path = fetchUnquotePath(u)) == NULL) {
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CHECK_FLAG('a'))
|
||||
fd = open(path, O_WRONLY | O_APPEND);
|
||||
else
|
||||
fd = open(path, O_WRONLY);
|
||||
|
||||
free(path);
|
||||
|
||||
if (fd == -1) {
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (u->offset && lseek(fd, u->offset, SEEK_SET) == -1) {
|
||||
close(fd);
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cookie = malloc(sizeof(int));
|
||||
if (cookie == NULL) {
|
||||
close(fd);
|
||||
fetch_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*cookie = fd;
|
||||
f = fetchIO_unopen(cookie, fetchFile_read, fetchFile_write, fetchFile_close);
|
||||
if (f == NULL) {
|
||||
close(fd);
|
||||
free(cookie);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_stat_file(int fd, struct url_stat *us)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
us->size = -1;
|
||||
us->atime = us->mtime = 0;
|
||||
if (fstat(fd, &sb) == -1) {
|
||||
fetch_syserr();
|
||||
return (-1);
|
||||
}
|
||||
us->size = sb.st_size;
|
||||
us->atime = sb.st_atime;
|
||||
us->mtime = sb.st_mtime;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fetchStatFile(struct url *u, struct url_stat *us, const char *flags)
|
||||
{
|
||||
char *path;
|
||||
int fd, rv;
|
||||
|
||||
if ((path = fetchUnquotePath(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
|
||||
fetchListFile(struct url_list *ue, struct url *u, const char *pattern, const char *flags)
|
||||
{
|
||||
char *path;
|
||||
struct dirent *de;
|
||||
DIR *dir;
|
||||
int ret;
|
||||
|
||||
if ((path = fetchUnquotePath(u)) == NULL) {
|
||||
fetch_syserr();
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir = opendir(path);
|
||||
free(path);
|
||||
|
||||
if (dir == NULL) {
|
||||
fetch_syserr();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
if (pattern && fnmatch(pattern, de->d_name, 0) != 0)
|
||||
continue;
|
||||
ret = fetch_add_entry(ue, u, de->d_name, 0);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return ret;
|
||||
}
|
1363
lib/libfetch/ftp.c
Normal file
1363
lib/libfetch/ftp.c
Normal file
File diff suppressed because it is too large
Load diff
48
lib/libfetch/ftp.errors
Normal file
48
lib/libfetch/ftp.errors
Normal file
|
@ -0,0 +1,48 @@
|
|||
# $NetBSD: ftp.errors,v 1.2 2008/10/06 12:58:29 joerg Exp $
|
||||
# $FreeBSD: ftp.errors,v 1.6 2002/10/30 06:06:16 des Exp $
|
||||
#
|
||||
# This list is taken from RFC 959.
|
||||
# It probably needs a going over.
|
||||
#
|
||||
110 OK Restart marker reply
|
||||
120 TEMP Service ready in a few minutes
|
||||
125 OK Data connection already open; transfer starting
|
||||
150 OK File status okay; about to open data connection
|
||||
200 OK Command okay
|
||||
202 PROTO Command not implemented, superfluous at this site
|
||||
211 INFO System status, or system help reply
|
||||
212 INFO Directory status
|
||||
213 INFO File status
|
||||
214 INFO Help message
|
||||
215 INFO Set system type
|
||||
220 OK Service ready for new user
|
||||
221 OK Service closing control connection
|
||||
225 OK Data connection open; no transfer in progress
|
||||
226 OK Requested file action successful
|
||||
227 OK Entering Passive Mode
|
||||
229 OK Entering Extended Passive Mode
|
||||
230 OK User logged in, proceed
|
||||
250 OK Requested file action okay, completed
|
||||
257 OK File/directory created
|
||||
331 AUTH User name okay, need password
|
||||
332 AUTH Need account for login
|
||||
350 OK Requested file action pending further information
|
||||
421 DOWN Service not available, closing control connection
|
||||
425 NETWORK Can't open data connection
|
||||
426 ABORT Connection closed; transfer aborted
|
||||
450 UNAVAIL File unavailable (e.g., file busy)
|
||||
451 SERVER Requested action aborted: local error in processing
|
||||
452 FULL Insufficient storage space in system
|
||||
500 PROTO Syntax error, command unrecognized
|
||||
501 PROTO Syntax error in parameters or arguments
|
||||
502 PROTO Command not implemented
|
||||
503 PROTO Bad sequence of commands
|
||||
504 PROTO Command not implemented for that parameter
|
||||
530 AUTH Not logged in
|
||||
532 AUTH Need account for storing files
|
||||
535 PROTO Bug in MediaHawk Video Kernel FTP server
|
||||
550 UNAVAIL File unavailable (e.g., file not found, no access)
|
||||
551 PROTO Requested action aborted. Page type unknown
|
||||
552 FULL Exceeded storage allocation
|
||||
553 EXISTS File name not allowed
|
||||
999 PROTO Protocol error
|
45
lib/libfetch/ftperr.h
Normal file
45
lib/libfetch/ftperr.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
static struct fetcherr ftp_errlist[] = {
|
||||
{ 110, FETCH_OK, "Restart marker reply" },
|
||||
{ 120, FETCH_TEMP, "Service ready in a few minutes" },
|
||||
{ 125, FETCH_OK, "Data connection already open; transfer starting" },
|
||||
{ 150, FETCH_OK, "File status okay; about to open data connection" },
|
||||
{ 200, FETCH_OK, "Command okay" },
|
||||
{ 202, FETCH_PROTO, "Command not implemented, superfluous at this site" },
|
||||
{ 211, FETCH_INFO, "System status, or system help reply" },
|
||||
{ 212, FETCH_INFO, "Directory status" },
|
||||
{ 213, FETCH_INFO, "File status" },
|
||||
{ 214, FETCH_INFO, "Help message" },
|
||||
{ 215, FETCH_INFO, "Set system type" },
|
||||
{ 220, FETCH_OK, "Service ready for new user" },
|
||||
{ 221, FETCH_OK, "Service closing control connection" },
|
||||
{ 225, FETCH_OK, "Data connection open; no transfer in progress" },
|
||||
{ 226, FETCH_OK, "Requested file action successful" },
|
||||
{ 227, FETCH_OK, "Entering Passive Mode" },
|
||||
{ 229, FETCH_OK, "Entering Extended Passive Mode" },
|
||||
{ 230, FETCH_OK, "User logged in, proceed" },
|
||||
{ 250, FETCH_OK, "Requested file action okay, completed" },
|
||||
{ 257, FETCH_OK, "File/directory created" },
|
||||
{ 331, FETCH_AUTH, "User name okay, need password" },
|
||||
{ 332, FETCH_AUTH, "Need account for login" },
|
||||
{ 350, FETCH_OK, "Requested file action pending further information" },
|
||||
{ 421, FETCH_DOWN, "Service not available, closing control connection" },
|
||||
{ 425, FETCH_NETWORK, "Can't open data connection" },
|
||||
{ 426, FETCH_ABORT, "Connection closed; transfer aborted" },
|
||||
{ 450, FETCH_UNAVAIL, "File unavailable (e.g., file busy)" },
|
||||
{ 451, FETCH_SERVER, "Requested action aborted: local error in processing" },
|
||||
{ 452, FETCH_FULL, "Insufficient storage space in system" },
|
||||
{ 500, FETCH_PROTO, "Syntax error, command unrecognized" },
|
||||
{ 501, FETCH_PROTO, "Syntax error in parameters or arguments" },
|
||||
{ 502, FETCH_PROTO, "Command not implemented" },
|
||||
{ 503, FETCH_PROTO, "Bad sequence of commands" },
|
||||
{ 504, FETCH_PROTO, "Command not implemented for that parameter" },
|
||||
{ 530, FETCH_AUTH, "Not logged in" },
|
||||
{ 532, FETCH_AUTH, "Need account for storing files" },
|
||||
{ 535, FETCH_PROTO, "Bug in MediaHawk Video Kernel FTP server" },
|
||||
{ 550, FETCH_UNAVAIL, "File unavailable (e.g., file not found, no access)" },
|
||||
{ 551, FETCH_PROTO, "Requested action aborted. Page type unknown" },
|
||||
{ 552, FETCH_FULL, "Exceeded storage allocation" },
|
||||
{ 553, FETCH_EXISTS, "File name not allowed" },
|
||||
{ 999, FETCH_PROTO, "Protocol error" },
|
||||
{ -1, FETCH_UNKNOWN, "Unknown FTP error" }
|
||||
};
|
1572
lib/libfetch/http.c
Normal file
1572
lib/libfetch/http.c
Normal file
File diff suppressed because it is too large
Load diff
46
lib/libfetch/http.errors
Normal file
46
lib/libfetch/http.errors
Normal file
|
@ -0,0 +1,46 @@
|
|||
# $FreeBSD: http.errors,v 1.5 2001/05/23 18:52:02 des Exp $
|
||||
# $NetBSD: http.errors,v 1.3 2009/02/05 16:59:45 joerg Exp $
|
||||
#
|
||||
# This list is taken from RFC 2068.
|
||||
#
|
||||
100 OK Continue
|
||||
101 OK Switching Protocols
|
||||
200 OK OK
|
||||
201 OK Created
|
||||
202 OK Accepted
|
||||
203 INFO Non-Authoritative Information
|
||||
204 OK No Content
|
||||
205 OK Reset Content
|
||||
206 OK Partial Content
|
||||
300 MOVED Multiple Choices
|
||||
301 MOVED Moved Permanently
|
||||
302 MOVED Moved Temporarily
|
||||
303 MOVED See Other
|
||||
304 UNCHANGED Not Modified
|
||||
305 INFO Use Proxy
|
||||
307 MOVED Temporary Redirect
|
||||
400 PROTO Bad Request
|
||||
401 AUTH Unauthorized
|
||||
402 AUTH Payment Required
|
||||
403 AUTH Forbidden
|
||||
404 UNAVAIL Not Found
|
||||
405 PROTO Method Not Allowed
|
||||
406 PROTO Not Acceptable
|
||||
407 AUTH Proxy Authentication Required
|
||||
408 TIMEOUT Request Time-out
|
||||
409 EXISTS Conflict
|
||||
410 UNAVAIL Gone
|
||||
411 PROTO Length Required
|
||||
412 SERVER Precondition Failed
|
||||
413 PROTO Request Entity Too Large
|
||||
414 PROTO Request-URI Too Large
|
||||
415 PROTO Unsupported Media Type
|
||||
416 UNAVAIL Requested Range Not Satisfiable
|
||||
417 SERVER Expectation Failed
|
||||
500 SERVER Internal Server Error
|
||||
501 PROTO Not Implemented
|
||||
502 SERVER Bad Gateway
|
||||
503 TEMP Service Unavailable
|
||||
504 TIMEOUT Gateway Time-out
|
||||
505 PROTO HTTP Version not supported
|
||||
999 PROTO Protocol error
|
44
lib/libfetch/httperr.h
Normal file
44
lib/libfetch/httperr.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
static struct fetcherr http_errlist[] = {
|
||||
{ 100, FETCH_OK, "Continue" },
|
||||
{ 101, FETCH_OK, "Switching Protocols" },
|
||||
{ 200, FETCH_OK, "OK" },
|
||||
{ 201, FETCH_OK, "Created" },
|
||||
{ 202, FETCH_OK, "Accepted" },
|
||||
{ 203, FETCH_INFO, "Non-Authoritative Information" },
|
||||
{ 204, FETCH_OK, "No Content" },
|
||||
{ 205, FETCH_OK, "Reset Content" },
|
||||
{ 206, FETCH_OK, "Partial Content" },
|
||||
{ 300, FETCH_MOVED, "Multiple Choices" },
|
||||
{ 301, FETCH_MOVED, "Moved Permanently" },
|
||||
{ 302, FETCH_MOVED, "Moved Temporarily" },
|
||||
{ 303, FETCH_MOVED, "See Other" },
|
||||
{ 304, FETCH_UNCHANGED, "Not Modified" },
|
||||
{ 305, FETCH_INFO, "Use Proxy" },
|
||||
{ 307, FETCH_MOVED, "Temporary Redirect" },
|
||||
{ 400, FETCH_PROTO, "Bad Request" },
|
||||
{ 401, FETCH_AUTH, "Unauthorized" },
|
||||
{ 402, FETCH_AUTH, "Payment Required" },
|
||||
{ 403, FETCH_AUTH, "Forbidden" },
|
||||
{ 404, FETCH_UNAVAIL, "Not Found" },
|
||||
{ 405, FETCH_PROTO, "Method Not Allowed" },
|
||||
{ 406, FETCH_PROTO, "Not Acceptable" },
|
||||
{ 407, FETCH_AUTH, "Proxy Authentication Required" },
|
||||
{ 408, FETCH_TIMEOUT, "Request Time-out" },
|
||||
{ 409, FETCH_EXISTS, "Conflict" },
|
||||
{ 410, FETCH_UNAVAIL, "Gone" },
|
||||
{ 411, FETCH_PROTO, "Length Required" },
|
||||
{ 412, FETCH_SERVER, "Precondition Failed" },
|
||||
{ 413, FETCH_PROTO, "Request Entity Too Large" },
|
||||
{ 414, FETCH_PROTO, "Request-URI Too Large" },
|
||||
{ 415, FETCH_PROTO, "Unsupported Media Type" },
|
||||
{ 416, FETCH_UNAVAIL, "Requested Range Not Satisfiable" },
|
||||
{ 417, FETCH_SERVER, "Expectation Failed" },
|
||||
{ 500, FETCH_SERVER, "Internal Server Error" },
|
||||
{ 501, FETCH_PROTO, "Not Implemented" },
|
||||
{ 502, FETCH_SERVER, "Bad Gateway" },
|
||||
{ 503, FETCH_TEMP, "Service Unavailable" },
|
||||
{ 504, FETCH_TIMEOUT, "Gateway Time-out" },
|
||||
{ 505, FETCH_PROTO, "HTTP Version not supported" },
|
||||
{ 999, FETCH_PROTO, "Protocol error" },
|
||||
{ -1, FETCH_UNKNOWN, "Unknown HTTP error" }
|
||||
};
|
Loading…
Reference in a new issue