First of a series of cleanups to libfetch. Changed files, in

alphabetical order:

 Makefile:
  Add common.c to SRCS.

  Make debugging easier by making 'CFLAGS += -DNDEBUG' conditional on DEBUG

  Don't declare struct {ftp,http}err in {ftp,http}err.c; use struct fetcherr
  instead.

 README:
  Remove the todo list, which is out of date anyway.

 common.c: (new file)
  Gather utility functions in this file.

  Merge the error reporting functions intp _fetch_errstring(),
  _fetch_seterr() and _fetch_syserr().

  Set fetchLastErrCode and fetchLastErrText appropriately when fetchConnect
  fails.

 common.h: (new file)
  Gather internal prototypes and structures in this files.

 fetch.3:
  Undocument fetchFreeURL().

  Document a few more known bugs.

  Document fetchLastErrCode and fetchLastErrText.

 fetch.c:
  Add descriptive comments to all functions that lacked them.

  Move fetchConnect() to common.c.

  Obviate the need for fetchFreeURL(), and remove it.

 fetch.h:
  Modify struct url_t so the document part is at the end.

 ftp.c:
  Remove code that is duplicated elsewhere.

 http.c:
  Remove code that is duplicated elsewhere.

Prompted by: jkh
This commit is contained in:
Dag-Erling Smørgrav 1998-11-05 19:48:17 +00:00
parent 8984b8ccf6
commit 842a95cc23
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=40939
9 changed files with 260 additions and 153 deletions

View File

@ -1,8 +1,11 @@
# $Id$
# $Id: Makefile,v 1.5 1998/08/17 20:39:09 bde Exp $
LIB= fetch
CFLAGS+= -I. -Wall -pedantic -DNDEBUG
SRCS= fetch.c ftp.c http.c file.c
CFLAGS+= -I. -Wall -pedantic
.if !defined(DEBUG)
CFLAGS+= -DNDEBUG
.endif
SRCS= fetch.c common.c ftp.c http.c file.c
DPSRCS= ftperr.c httperr.c
MAN3= fetch.3
CLEANFILES= ${DPSRCS}
@ -17,11 +20,7 @@ beforeinstall:
${DESTDIR}/usr/include
ftperr.c: ftp.errors
@echo "struct ftperr {" \ > ${.TARGET}
@echo " const int num;" \ >> ${.TARGET}
@echo " const char *string;" \ >> ${.TARGET}
@echo "};" \ >> ${.TARGET}
@echo "static struct ftperr _ftp_errlist[] = {" \ >> ${.TARGET}
@echo "static struct fetcherr _ftp_errlist[] = {" \ >> ${.TARGET}
@cat ${.ALLSRC} \
| grep -v ^# \
| sort \
@ -30,13 +29,12 @@ ftperr.c: ftp.errors
done >> ${.TARGET}
@echo " { -1, \"Unknown FTP error\" }" >> ${.TARGET}
@echo "};" >> ${.TARGET}
@echo "#define _ftp_errstring(n) _fetch_errstring(_ftp_errlist, n)" >> ${.TARGET}
@echo "#define _ftp_seterr(n) _fetch_seterr(_ftp_errlist, n)" >> ${.TARGET}
httperr.c: http.errors
@echo "struct httperr {" \ > ${.TARGET}
@echo " const int num;" \ >> ${.TARGET}
@echo " const char *string;" \ >> ${.TARGET}
@echo "};" \ >> ${.TARGET}
@echo "static struct httperr _http_errlist[] = {" \ >> ${.TARGET}
@echo "static struct fetcherr _http_errlist[] = {" \ >> ${.TARGET}
@cat ${.ALLSRC} \
| grep -v ^# \
| sort \
@ -45,6 +43,8 @@ httperr.c: http.errors
done >> ${.TARGET}
@echo " { -1, \"Unknown HTTP error\" }" >> ${.TARGET}
@echo "};" >> ${.TARGET}
@echo "#define _http_errstring(n) _fetch_errstring(_http_errlist, n)" >> ${.TARGET}
@echo "#define _http_seterr(n) _fetch_seterr(_http_errlist, n)" >> ${.TARGET}
.include <bsd.lib.mk>

View File

@ -3,19 +3,8 @@ library and provide a new, unified backend for all fetch(1),
pkg_add(1) and sysinstall(8).
Note that this is very much work in progress. It compiles (with a few
warnings), but there is much left to be implemented. Amongst other
items:
* The man page needs work. Really. I mean it. Now.
* HTTP authentication doesn't work. I'm not sure if I bungled http.c
or fubared base64.c (which was ripped from MIT fetch(1)).
* The library needs a decent interface for reporting errors. I've
started on something (sending back an error code in the url_t that
was sent in) but we're Not There (tm) yet.
Comments, patches etc. of all kinds are welcome, but please don't
commit anything without talking to me first.
warnings), but there is much left to be implemented. Comments, patches
etc. of all kinds are welcome, but please don't commit anything
without talking to me first.
-- Dag-Erling C. Smørgrav (des@FreeBSD.org)

134
lib/libfetch/common.c Normal file
View File

@ -0,0 +1,134 @@
/*-
* Copyright (c) 1998 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.
*
* $Id$
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include "fetch.h"
#include "common.h"
/*** Local data **************************************************************/
/*
* Error messages for resolver errors
*/
static struct fetcherr _netdb_errlist[] = {
{ HOST_NOT_FOUND, "Host not found" },
{ TRY_AGAIN, "Transient resolver failure" },
{ NO_RECOVERY, "Non-recoverable resolver failure" },
{ NO_DATA, "No address record" },
{ -1, "Unknown resolver error" }
};
#define _netdb_errstring(n) _fetch_errstring(_netdb_errlist, n)
#define _netdb_seterr(n) _fetch_seterr(_netdb_errlist, n)
/*** Error-reporting functions ***********************************************/
/*
* Map error code to string
*/
const char *
_fetch_errstring(struct fetcherr *p, int e)
{
while ((p->num != -1) && (p->num != e))
p++;
return p->string;
}
/*
* Set error code
*/
void
_fetch_seterr(struct fetcherr *p, int e)
{
fetchLastErrCode = e;
fetchLastErrText = _fetch_errstring(p, e);
}
/*
* Set error code according to errno
*/
void
_fetch_syserr(void)
{
fetchLastErrCode = errno;
fetchLastErrText = strerror(errno);
}
/*** Network-related utility functions ***************************************/
/*
* Establish a TCP connection to the specified port on the specified host.
*/
int
fetchConnect(char *host, int port)
{
struct sockaddr_in sin;
struct hostent *he;
int sd;
#ifndef NDEBUG
fprintf(stderr, "\033[1m---> %s:%d\033[m\n", host, port);
#endif
/* look up host name */
if ((he = gethostbyname(host)) == NULL) {
_netdb_seterr(h_errno);
return -1;
}
/* set up socket address structure */
bzero(&sin, sizeof(sin));
bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
sin.sin_family = he->h_addrtype;
sin.sin_port = htons(port);
/* try to connect */
if ((sd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
_fetch_syserr();
return -1;
}
if (connect(sd, (struct sockaddr *)&sin, sizeof sin) == -1) {
_fetch_syserr();
close(sd);
return -1;
}
return sd;
}

44
lib/libfetch/common.h Normal file
View File

@ -0,0 +1,44 @@
/*-
* Copyright (c) 1998 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.
*
* $Id$
*/
#ifndef _COMMON_H_INCLUDED
#define _COMMON_H_INCLUDED
/* Structure used for error message lists */
struct fetcherr {
const int num;
const char *string;
};
const char *_fetch_errstring(struct fetcherr *, int);
void _fetch_seterr(struct fetcherr *, int);
void _fetch_syserr(void);
#endif

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: fetch.3,v 1.1.1.1 1998/07/09 16:52:43 des Exp $
.\" $Id: fetch.3,v 1.2 1998/09/26 20:42:44 des Exp $
.\"
.Dd July 1, 1998
.Dt FETCH 3
@ -31,7 +31,6 @@
.Nm fetchGetURL ,
.Nm fetchPutURL ,
.Nm fetchParseURL ,
.Nm fetchFreeURL ,
.Nm fetchGet ,
.Nm fetchPut ,
.Nm fetchGetFile ,
@ -49,8 +48,6 @@
.Fn fetchPutURL "char *URL" "char *flags"
.Ft url_t *
.Fn fetchParseURL "char *URL" "char *flags"
.Ft void
.Fn fetchFreeURL "url_t *u"
.Ft FILE *
.Fn fetchGet "url_t *URL" "char *flags"
.Ft FILE *
@ -67,6 +64,8 @@
.Fn fetchGetFTP "url_t *u" "char *flags"
.Ft FILE *
.Fn fetchPutFTP "url_t *u" "char *flags"
.Vt extern int fetchLastErrCode;
.Vt extern const char *fetchLastErrText;
.Sh DESCRIPTION
These functions implement a high-level library for retrieving and
uploading files using Uniform Resource Locators (URLs).
@ -100,7 +99,7 @@ and <document> components.
The pointer returned by
.Fn fetchParseURL
should be freed using
.Fn fetchFreeURL .
.Fn free .
.Pp
.Fn fetchGet
and
@ -182,12 +181,13 @@ unable to allocate memory, or the URL is syntactically incorrect,
.Fn fetchParseURL
returns a NULL pointer.
.Pp
.Fn fetchFreeURL
does not return any value.
.Pp
All other functions return a stream pointer which may be used to
access the requested document. Upon failure of any kind, they return a
NULL pointer.
access the requested document, or NULL if an error occurred. In the
latter case, the variables
.Va fetchLastErrCode
and
.Va fetchLastErrText
are set to appropriately descriptive values.
.Sh ENVIRONMENT
The FTP and HTTP related functions use the
.Ev HTTP_PROXY
@ -259,6 +259,21 @@ code; as far as I can determine,
.Nm libfetch
handles HTTP/1.1 basic authentication correctly as outlined in
RFC2068, but I haven't been able to find an HTTP server that honors
the Authentication: header field.
the Authentication: header field. Also,
.Nm libfetch
does not attempt to interpret and respond to authentication requests
from the HTTP server.
.Pp
No attempt is made to encode spaces etc. within URLs. Spaces in the
document part of an URLshould be replaced with "%20" in HTTP URLs and
"\\ " in FTP URLs.
.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
The man page is poorly written and produces badly formatted text.
.Pp
Tons of other stuff.

View File

@ -25,20 +25,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: fetch.c,v 1.3 1998/07/11 21:29:07 des Exp $
* $Id: fetch.c,v 1.4 1998/08/17 09:30:19 des Exp $
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "fetch.h"
@ -51,6 +46,10 @@
int fetchLastErrCode;
const char *fetchLastErrText;
/*
* Select the appropriate protocol for the URL scheme, and return a
* read-only stream connected to the document referenced by the URL.
*/
FILE *
fetchGet(url_t *URL, char *flags)
{
@ -64,6 +63,10 @@ fetchGet(url_t *URL, char *flags)
}
/*
* Select the appropriate protocol for the URL scheme, and return a
* write-only stream connected to the document referenced by the URL.
*/
FILE *
fetchPut(url_t *URL, char *flags)
{
@ -76,7 +79,9 @@ fetchPut(url_t *URL, char *flags)
else return NULL;
}
/* get URL */
/*
* Attempt to parse the given URL; if successful, call fetchGet().
*/
FILE *
fetchGetURL(char *URL, char *flags)
{
@ -88,12 +93,14 @@ fetchGetURL(char *URL, char *flags)
f = fetchGet(u, flags);
fetchFreeURL(u);
free(u);
return f;
}
/* put URL */
/*
* Attempt to parse the given URL; if successful, call fetchPut().
*/
FILE *
fetchPutURL(char *URL, char *flags)
{
@ -105,7 +112,7 @@ fetchPutURL(char *URL, char *flags)
f = fetchPut(u, flags);
fetchFreeURL(u);
free(u);
return f;
}
@ -171,11 +178,17 @@ fetchParseURL(char *URL)
nohost:
/* document */
if (*p)
u->doc = strdup(p);
u->doc = strdup(*p ? p : "/");
if (!u->doc)
goto ouch;
if (*p) {
url_t *t;
t = realloc(u, sizeof(*u)+strlen(p)-1);
if (t == NULL)
goto ouch;
u = t;
strcpy(u->doc, p);
} else {
u->doc[0] = '/';
u->doc[1] = 0;
}
DEBUG(fprintf(stderr,
"scheme: [\033[1m%s\033[m]\n"
@ -193,45 +206,3 @@ fetchParseURL(char *URL)
free(u);
return NULL;
}
void
fetchFreeURL(url_t *u)
{
if (u) {
if (u->doc)
free(u->doc);
free(u);
}
}
int
fetchConnect(char *host, int port)
{
struct sockaddr_in sin;
struct hostent *he;
int sd;
#ifndef NDEBUG
fprintf(stderr, "\033[1m---> %s:%d\033[m\n", host, port);
#endif
/* look up host name */
if ((he = gethostbyname(host)) == NULL)
return -1;
/* set up socket address structure */
bzero(&sin, sizeof(sin));
bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
sin.sin_family = he->h_addrtype;
sin.sin_port = htons(port);
/* try to connect */
if ((sd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
return -1;
if (connect(sd, (struct sockaddr *)&sin, sizeof sin) == -1) {
close(sd);
return -1;
}
return sd;
}

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: fetch.h,v 1.3 1998/07/11 21:29:08 des Exp $
* $Id: fetch.h,v 1.4 1998/08/17 09:30:19 des Exp $
*/
#ifndef _FETCH_H_INCLUDED
@ -45,8 +45,8 @@ struct url_s {
char user[URL_USERLEN+1];
char pwd[URL_PWDLEN+1];
char host[MAXHOSTNAMELEN+1];
char *doc;
int port;
int port;
char doc[2];
};
typedef struct url_s url_t;

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ftp.c,v 1.4 1998/07/12 22:34:39 des Exp $
* $Id: ftp.c,v 1.5 1998/08/17 09:30:19 des Exp $
*/
/*
@ -70,6 +70,7 @@
#include <unistd.h>
#include "fetch.h"
#include "common.h"
#include "ftperr.c"
#define FTP_DEFAULT_TO_ANONYMOUS
@ -92,40 +93,6 @@ static FILE *cached_socket;
static char *_ftp_last_reply;
/*
* Map error code to string
*/
static const char *
_ftp_errstring(int e)
{
struct ftperr *p = _ftp_errlist;
while ((p->num != -1) && (p->num != e))
p++;
return p->string;
}
/*
* Set error code
*/
static void
_ftp_seterr(int e)
{
fetchLastErrCode = e;
fetchLastErrText = _ftp_errstring(e);
}
/*
* Set error code according to errno
*/
static void
_ftp_syserr(void)
{
fetchLastErrCode = errno;
fetchLastErrText = strerror(errno);
}
/*
* Get server response, check that first digit is a '2'
*/
@ -140,7 +107,7 @@ _ftp_chkerr(FILE *s, int *e)
do {
if (((line = fgetln(s, &len)) == NULL) || (len < 4)) {
_ftp_syserr();
_fetch_syserr();
return -1;
}
} while (line[3] == '-');
@ -217,7 +184,7 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
/* open data socket */
if ((sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
_ftp_syserr();
_fetch_syserr();
return NULL;
}
@ -296,7 +263,7 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
return df;
sysouch:
_ftp_syserr();
_fetch_syserr();
ouch:
close(sd);
return NULL;
@ -330,13 +297,13 @@ _ftp_connect(char *host, int port, char *user, char *pwd)
/* check connection */
if (sd == -1) {
_ftp_syserr();
_fetch_syserr();
return NULL;
}
/* streams make life easier */
if ((f = fdopen(sd, "r+")) == NULL) {
_ftp_syserr();
_fetch_syserr();
goto ouch;
}

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: http.c,v 1.4 1998/07/12 22:34:40 des Exp $
* $Id: http.c,v 1.5 1998/08/17 09:30:19 des Exp $
*/
/*
@ -77,6 +77,7 @@
#include <unistd.h>
#include "fetch.h"
#include "common.h"
#include "httperr.c"
#ifndef NDEBUG
@ -102,20 +103,6 @@ struct cookie
unsigned b_len, chunksize;
};
/*
* Look up error code
*/
static const char *
_http_errstring(int e)
{
struct httperr *p = _http_errlist;
while ((p->num != -1) && (p->num != e))
p++;
return p->string;
}
/*
* Send a formatted line; optionally echo to terminal
*/