summaryrefslogtreecommitdiff
path: root/lib/libfetch/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libfetch/fetch.c')
-rw-r--r--lib/libfetch/fetch.c142
1 files changed, 110 insertions, 32 deletions
diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c
index 3c944a189be7..5d83db5b5de8 100644
--- a/lib/libfetch/fetch.c
+++ b/lib/libfetch/fetch.c
@@ -40,8 +40,9 @@
#include "common.h"
-int fetchLastErrCode;
-int fetchTimeout;
+int fetchLastErrCode;
+char fetchLastErrString[MAXERRSTRING];
+int fetchTimeout;
/*** Local data **************************************************************/
@@ -69,13 +70,19 @@ static struct fetcherr _url_errlist[] = {
FILE *
fetchGet(struct url *URL, char *flags)
{
+ int direct;
+
+ direct = (flags && strchr(flags, 'd'));
if (strcasecmp(URL->scheme, "file") == 0)
return fetchGetFile(URL, flags);
else if (strcasecmp(URL->scheme, "http") == 0)
return fetchGetHTTP(URL, flags);
- else if (strcasecmp(URL->scheme, "ftp") == 0)
+ else if (strcasecmp(URL->scheme, "ftp") == 0) {
+ if (!direct &&
+ getenv("FTP_PROXY") == NULL && getenv("HTTP_PROXY") != NULL)
+ return fetchGetHTTP(URL, flags);
return fetchGetFTP(URL, flags);
- else {
+ } else {
_url_seterr(URL_BAD_SCHEME);
return NULL;
}
@@ -88,13 +95,19 @@ fetchGet(struct url *URL, char *flags)
FILE *
fetchPut(struct url *URL, char *flags)
{
+ int direct;
+
+ direct = (flags && strchr(flags, 'd'));
if (strcasecmp(URL->scheme, "file") == 0)
return fetchPutFile(URL, flags);
else if (strcasecmp(URL->scheme, "http") == 0)
return fetchPutHTTP(URL, flags);
- else if (strcasecmp(URL->scheme, "ftp") == 0)
+ else if (strcasecmp(URL->scheme, "ftp") == 0) {
+ if (!direct &&
+ getenv("FTP_PROXY") == NULL && getenv("HTTP_PROXY") != NULL)
+ return fetchPutHTTP(URL, flags);
return fetchPutFTP(URL, flags);
- else {
+ } else {
_url_seterr(URL_BAD_SCHEME);
return NULL;
}
@@ -107,13 +120,19 @@ fetchPut(struct url *URL, char *flags)
int
fetchStat(struct url *URL, struct url_stat *us, char *flags)
{
+ int direct;
+
+ direct = (flags && strchr(flags, 'd'));
if (strcasecmp(URL->scheme, "file") == 0)
return fetchStatFile(URL, us, flags);
else if (strcasecmp(URL->scheme, "http") == 0)
return fetchStatHTTP(URL, us, flags);
- else if (strcasecmp(URL->scheme, "ftp") == 0)
+ else if (strcasecmp(URL->scheme, "ftp") == 0) {
+ if (!direct &&
+ getenv("FTP_PROXY") == NULL && getenv("HTTP_PROXY") != NULL)
+ return fetchStatHTTP(URL, us, flags);
return fetchStatFTP(URL, us, flags);
- else {
+ } else {
_url_seterr(URL_BAD_SCHEME);
return -1;
}
@@ -126,13 +145,19 @@ fetchStat(struct url *URL, struct url_stat *us, char *flags)
struct url_ent *
fetchList(struct url *URL, char *flags)
{
+ int direct;
+
+ direct = (flags && strchr(flags, 'd'));
if (strcasecmp(URL->scheme, "file") == 0)
return fetchListFile(URL, flags);
else if (strcasecmp(URL->scheme, "http") == 0)
return fetchListHTTP(URL, flags);
- else if (strcasecmp(URL->scheme, "ftp") == 0)
+ else if (strcasecmp(URL->scheme, "ftp") == 0) {
+ if (!direct &&
+ getenv("FTP_PROXY") == NULL && getenv("HTTP_PROXY") != NULL)
+ return fetchListHTTP(URL, flags);
return fetchListFTP(URL, flags);
- else {
+ } else {
_url_seterr(URL_BAD_SCHEME);
return NULL;
}
@@ -152,7 +177,7 @@ fetchGetURL(char *URL, char *flags)
f = fetchGet(u, flags);
- free(u);
+ fetchFreeURL(u);
return f;
}
@@ -171,7 +196,7 @@ fetchPutURL(char *URL, char *flags)
f = fetchPut(u, flags);
- free(u);
+ fetchFreeURL(u);
return f;
}
@@ -189,7 +214,7 @@ fetchStatURL(char *URL, struct url_stat *us, char *flags)
s = fetchStat(u, us, flags);
- free(u);
+ fetchFreeURL(u);
return s;
}
@@ -207,11 +232,53 @@ fetchListURL(char *URL, char *flags)
ue = fetchList(u, flags);
- free(u);
+ fetchFreeURL(u);
return ue;
}
/*
+ * Make a URL
+ */
+struct url *
+fetchMakeURL(char *scheme, char *host, int port, char *doc,
+ char *user, 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;
+}
+
+/*
* Split an URL into components. URL syntax is:
* method:[//[user[:pwd]@]host[:port]]/[document]
* This almost, but not quite, RFC1738 URL syntax.
@@ -224,8 +291,7 @@ fetchParseURL(char *URL)
int i;
/* allocate struct url */
- if ((u = calloc(1, sizeof(struct url))) == NULL) {
- errno = ENOMEM;
+ if ((u = calloc(1, sizeof *u)) == NULL) {
_fetch_syserr();
return NULL;
}
@@ -262,9 +328,18 @@ fetchParseURL(char *URL)
} else p = URL;
/* hostname */
- for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
- if (i < MAXHOSTNAMELEN)
- u->host[i++] = *p;
+#ifdef INET6
+ if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&
+ (*++q == '\0' || *q == '/' || *q == ':')) {
+ if ((i = q - p - 2) > MAXHOSTNAMELEN)
+ i = MAXHOSTNAMELEN;
+ strncpy(u->host, ++p, i);
+ p = q;
+ } else
+#endif
+ for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
+ if (i < MAXHOSTNAMELEN)
+ u->host[i++] = *p;
/* port */
if (*p == ':') {
@@ -282,19 +357,12 @@ fetchParseURL(char *URL)
nohost:
/* document */
- if (*p) {
- struct url *t;
- t = realloc(u, sizeof(*u)+strlen(p)-1);
- if (t == NULL) {
- errno = ENOMEM;
- _fetch_syserr();
- goto ouch;
- }
- u = t;
- strcpy(u->doc, p);
- } else {
- u->doc[0] = '/';
- u->doc[1] = 0;
+ if (!*p)
+ p = "/";
+
+ if ((u->doc = strdup(p)) == NULL) {
+ _fetch_syserr();
+ goto ouch;
}
DEBUG(fprintf(stderr,
@@ -313,3 +381,13 @@ ouch:
free(u);
return NULL;
}
+
+/*
+ * Free a URL
+ */
+void
+fetchFreeURL(struct url *u)
+{
+ free(u->doc);
+ free(u);
+}