New function urlStrerror to fish out URL open failure codes.
CVS patchset: 2795
CVS date: 1999/02/16 02:14:19
noinst_HEADERS = \
acconfig.h build.h checksig.h ftp.h \
- install.h system.h url.h http.h\
- verify.h
+ install.h system.h url.h verify.h
-rpm_SOURCES = build.c checksig.c ftp.c http.c install.c rpm.c url.c \
- verify.c
+rpm_SOURCES = build.c checksig.c ftp.c install.c rpm.c url.c verify.c
rpm_LDADD = $(mylibs) @LIBMISC@
$(PROGRAMS): $(mylibs) @LIBMISC@
static int ftpDebug = 0;
static int ftpTimeoutSecs = TIMEOUT_SECS;
+static int httpTimeoutSecs = TIMEOUT_SECS;
-#ifdef DYING
-static int ftpCheckResponse(urlinfo *u, char ** str);
-static int ftpCommand(urlinfo *u, char * command, ...);
-static int copyData(FD_t sfd, FD_t tfd);
-static int getHostAddress(const char * host, struct in_addr * address);
-#endif
-
-static int ftpCheckResponse(urlinfo *u, char ** str) {
+static int checkResponse(int fd, int secs, int *ecp, char ** str) {
static char buf[BUFFER_SIZE + 1];
int bufLength = 0;
fd_set emptySet, readSet;
- char * chptr, * start;
+ char *se, *s;
struct timeval timeout;
int bytesRead, rc = 0;
int doesContinue = 1;
errorCode[0] = '\0';
do {
- FD_ZERO(&emptySet);
- FD_ZERO(&readSet);
- FD_SET(u->ftpControl, &readSet);
-
- timeout.tv_sec = ftpTimeoutSecs;
- timeout.tv_usec = 0;
-
- rc = select(u->ftpControl + 1, &readSet, &emptySet, &emptySet, &timeout);
- if (rc < 1) {
- if (rc==0)
- return FTPERR_BAD_SERVER_RESPONSE;
- else
- rc = FTPERR_UNKNOWN;
- } else
- rc = 0;
-
- bytesRead = read(u->ftpControl, buf + bufLength, sizeof(buf) - bufLength - 1);
-
- bufLength += bytesRead;
-
- buf[bufLength] = '\0';
-
- /* divide the response into lines, checking each one to see if
- we are finished or need to continue */
-
- start = chptr = buf;
-
+ /*
+ * XXX In order to preserve both getFile and getFd methods with
+ * XXX HTTP, the response is read 1 char at a time with breaks on
+ * XXX newlines.
+ */
do {
- while (*chptr != '\n' && *chptr) chptr++;
-
- if (*chptr == '\n') {
- *chptr = '\0';
- if (*(chptr - 1) == '\r') *(chptr - 1) = '\0';
- if (str) *str = start;
+ FD_ZERO(&emptySet);
+ FD_ZERO(&readSet);
+ FD_SET(fd, &readSet);
- if (errorCode[0]) {
- if (!strncmp(start, errorCode, 3) && start[3] == ' ')
- doesContinue = 0;
- } else {
- strncpy(errorCode, start, 3);
- errorCode[3] = '\0';
- if (start[3] != '-') {
+ timeout.tv_sec = secs;
+ timeout.tv_usec = 0;
+
+ rc = select(fd + 1, &readSet, &emptySet, &emptySet, &timeout);
+ if (rc < 1) {
+ if (rc == 0)
+ return FTPERR_BAD_SERVER_RESPONSE;
+ else
+ rc = FTPERR_UNKNOWN;
+ } else
+ rc = 0;
+
+ s = buf + bufLength;
+ bytesRead = read(fd, s, 1);
+ bufLength += bytesRead;
+ buf[bufLength] = '\0';
+ } while (bufLength < sizeof(buf) && *s != '\n');
+
+ /*
+ * Divide the response into lines. Skip continuation lines.
+ */
+ s = se = buf;
+ while (*se != '\0') {
+ while (*se && *se != '\n') se++;
+
+ if (se > s && se[-1] == '\r')
+ se[-1] = '\0';
+ if (*se == '\0')
+ break;
+
+ /* HTTP header termination on empty line */
+ if (*s == '\0') {
doesContinue = 0;
- }
+ break;
+ }
+ *se++ = '\0';
+
+ /* HTTP: look for "HTTP/1.1 123 ..." */
+ if (!strncmp(s, "HTTP", 4)) {
+ char *e;
+ if ((e = strchr(s, ' ')) != NULL) {
+ e++;
+ if (strchr("0123456789", *e))
+ strncpy(errorCode, e, 3);
+ errorCode[3] = '\0';
+ }
+ s = se;
+ continue;
}
- start = chptr + 1;
- chptr++;
- } else {
- chptr++;
- }
- } while (*chptr);
+ /* FTP: look for "123-" and/or "123 " */
+ if (strchr("0123456789", *s)) {
+ if (errorCode[0]) {
+ if (!strncmp(s, errorCode, 3) && s[3] == ' ')
+ doesContinue = 0;
+ } else {
+ strncpy(errorCode, s, 3);
+ errorCode[3] = '\0';
+ if (s[3] != '-') {
+ doesContinue = 0;
+ }
+ }
+ }
+ s = se;
+ }
- if (doesContinue && chptr > start) {
- memcpy(buf, start, chptr - start - 1);
- bufLength = chptr - start - 1;
+ if (doesContinue && se > s) {
+ bufLength = se - s - 1;
+ if (s != buf)
+ memcpy(buf, s, bufLength);
} else {
bufLength = 0;
}
if (ftpDebug)
fprintf(stderr, "<- %s\n", buf);
- if (*errorCode == '4' || *errorCode == '5') {
- if (!strncmp(errorCode, "550", 3))
- return FTPERR_FILE_NOT_FOUND;
- if (!strncmp(errorCode, "552", 3))
- return FTPERR_NIC_ABORT_IN_PROGRESS;
+ if (str) *str = buf;
+ if (ecp) *ecp = atoi(errorCode);
- return FTPERR_BAD_SERVER_RESPONSE;
- }
+ return rc;
+}
- if (rc) return rc;
+static int ftpCheckResponse(urlinfo *u, char ** str) {
+ int ec = 0;
+ int rc = checkResponse(u->ftpControl, ftpTimeoutSecs, &ec, str);
- return 0;
+ switch (ec) {
+ case 550:
+ return FTPERR_FILE_NOT_FOUND;
+ break;
+ case 552:
+ return FTPERR_NIC_ABORT_IN_PROGRESS;
+ break;
+ default:
+ if (ec >= 400 && ec <= 599)
+ return FTPERR_BAD_SERVER_RESPONSE;
+ break;
+ }
+ return rc;
}
static int ftpCommand(urlinfo *u, char * command, ...) {
return 0;
}
-int tcpConnect(const char *host, int port)
+static int tcpConnect(const char *host, int port)
{
struct sockaddr_in sin;
int sock = -1;
return sock;
}
+int httpOpen(urlinfo *u)
+{
+ int sock;
+ const char *host;
+ const char *path;
+ int port;
+ char *buf;
+ size_t len;
+
+ if (u == NULL || ((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
+ return FTPERR_BAD_HOSTNAME;
+
+ if ((port = (u->proxyp > 0 ? u->proxyp : u->port)) < 0) port = 80;
+
+ path = (u->proxyh || u->proxyp > 0) ? u->url : u->path;
+ if ((sock = tcpConnect(host, port)) < 0)
+ return sock;
+
+ len = strlen(path) + sizeof("GET HTTP 1.0\r\n\r\n");
+ buf = alloca(len);
+ strcpy(buf, "GET ");
+ strcat(buf, path);
+ strcat(buf, " HTTP 1.0\r\n");
+ strcat(buf, "\r\n");
+
+ if (write(sock, buf, len) != len) {
+ close(sock);
+ return FTPERR_SERVER_IO_ERROR;
+ }
+
+if (ftpDebug)
+fprintf(stderr, "-> %s", buf);
+
+ { int ec = 0;
+ int rc;
+ rc = checkResponse(sock, httpTimeoutSecs, &ec, NULL);
+
+ switch (ec) {
+ default:
+ if (rc == 0 && ec != 200) /* not HTTP_OK */
+ rc = FTPERR_FILE_NOT_FOUND;
+ break;
+ }
+
+ if (rc < 0) {
+ close(sock);
+ return rc;
+ }
+ }
+
+ return sock;
+}
+
int ftpOpen(urlinfo *u)
{
const char * host;
int port;
int rc;
- if (u == NULL || ((host = u->host) == NULL))
+ if (u == NULL || ((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
return FTPERR_BAD_HOSTNAME;
- if ((port = u->port) < 0) port = IPPORT_FTP;
+ if ((port = (u->proxyp > 0 ? u->proxyp : u->port)) < 0) port = IPPORT_FTP;
- if ((user = u->user) == NULL)
+ if ((user = (u->proxyu ? u->proxyu : u->user)) == NULL)
user = "anonymous";
if ((password = u->password) == NULL) {
return 0;
}
+int httpGetFile(FD_t sfd, FD_t tfd) {
+ return copyData(sfd, tfd);
+}
+
int ftpGetFile(FD_t sfd, FD_t tfd)
{
urlinfo *u;
return _("Unknown or unexpected error");
}
}
-
+
int ftpGetFileDesc(FD_t);
int ftpAbort(FD_t fd);
int ftpClose(FD_t fd);
-int tcpConnect(const char *host, int port);
#endif
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 1999-02-04 17:21-0500\n"
+"POT-Creation-Date: 1999-02-15 21:09-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "rpmconvert 1.0 - converting database in /var/lib/rpm\n"
msgstr ""
-#: ../ftp.c:531
+#: ../ftp.c:617
msgid "Success"
msgstr ""
-#: ../ftp.c:534
+#: ../ftp.c:620
msgid "Bad server response"
msgstr ""
-#: ../ftp.c:537
+#: ../ftp.c:623
msgid "Server IO error"
msgstr ""
-#: ../ftp.c:540
+#: ../ftp.c:626
msgid "Server timeout"
msgstr ""
-#: ../ftp.c:543
+#: ../ftp.c:629
msgid "Unable to lookup server host address"
msgstr ""
-#: ../ftp.c:546
+#: ../ftp.c:632
msgid "Unable to lookup server host name"
msgstr ""
-#: ../ftp.c:549
+#: ../ftp.c:635
msgid "Failed to connect to server"
msgstr ""
-#: ../ftp.c:552
+#: ../ftp.c:638
msgid "Failed to establish data connection to server"
msgstr ""
-#: ../ftp.c:555
+#: ../ftp.c:641
msgid "IO error to local file"
msgstr ""
-#: ../ftp.c:558
+#: ../ftp.c:644
msgid "Error setting remote server to passive mode"
msgstr ""
-#: ../ftp.c:561
+#: ../ftp.c:647
msgid "File not found on server"
msgstr ""
-#: ../ftp.c:564
+#: ../ftp.c:650
msgid "Abort in progress"
msgstr ""
-#: ../ftp.c:568
+#: ../ftp.c:654
msgid "Unknown or unexpected error"
msgstr ""
msgid "error reading header from package\n"
msgstr ""
-#: ../url.c:105
+#: ../url.c:118
#, c-format
msgid "Password for %s@%s: "
msgstr ""
-#: ../url.c:169
+#: ../url.c:136 ../url.c:158
+#, c-format
+msgid "error: %sport must be a number\n"
+msgstr ""
+
+#: ../url.c:227
msgid "url port must be a number\n"
msgstr ""
-#: ../url.c:207
+#: ../url.c:263
#, c-format
msgid "logging into %s as %s, pw %s\n"
msgstr ""
-#: ../url.c:230
-msgid "error: ftpport must be a number\n"
-msgstr ""
-
-#: ../lib/rpmdb.c:168 ../url.c:335
+#: ../lib/rpmdb.c:168 ../url.c:370
#, c-format
msgid "failed to open %s\n"
msgstr ""
-#: ../url.c:350
+#: ../url.c:385
#, c-format
msgid "failed to create %s\n"
msgstr ""
msgstr ""
#: ../build/files.c:291 ../build/files.c:303 ../build/files.c:372
-#: ../build/files.c:384 ../build/files.c:410
+#: ../build/files.c:384 ../build/files.c:415
#, c-format
msgid "Bad %s() syntax: %s"
msgstr ""
msgid "No files after %%defattr(): %s"
msgstr ""
-#: ../build/files.c:420
+#: ../build/files.c:425
#, c-format
msgid "Bad %s() mode spec: %s"
msgstr ""
-#: ../build/files.c:432
+#: ../build/files.c:437
#, c-format
msgid "Bad %s() dirmode spec: %s"
msgstr ""
-#: ../build/files.c:483
+#: ../build/files.c:488
msgid "Bad %%config() syntax: %s"
msgstr ""
-#: ../build/files.c:501
+#: ../build/files.c:506
msgid "Invalid %%config token: %s"
msgstr ""
-#: ../build/files.c:524 ../build/files.c:536 ../build/files.c:549
+#: ../build/files.c:529 ../build/files.c:541 ../build/files.c:554
msgid "Bad %%lang() syntax: %s"
msgstr ""
-#: ../build/files.c:555
+#: ../build/files.c:560
msgid "%%lang() entries are 2 characters: %s"
msgstr ""
-#: ../build/files.c:561
+#: ../build/files.c:566
msgid "Only one entry in %%lang(): %s"
msgstr ""
-#: ../build/files.c:643
+#: ../build/files.c:648
msgid "Hit limit for %%docdir"
msgstr ""
-#: ../build/files.c:649
+#: ../build/files.c:654
msgid "Only one arg for %%docdir"
msgstr ""
#. We already got a file -- error
-#: ../build/files.c:674
+#: ../build/files.c:679
#, c-format
msgid "Two files on one line: %s"
msgstr ""
-#: ../build/files.c:687
+#: ../build/files.c:692
#, c-format
msgid "File must begin with \"/\": %s"
msgstr ""
-#: ../build/files.c:699
+#: ../build/files.c:704
msgid "Can't mix special %%doc with other forms: %s"
msgstr ""
-#: ../build/files.c:787
+#: ../build/files.c:792
#, c-format
msgid "File listed twice: %s"
msgstr ""
-#: ../build/files.c:939
+#: ../build/files.c:944
#, c-format
msgid "File doesn't match prefix (%s): %s"
msgstr ""
-#: ../build/files.c:949 ../build/files.c:1068
+#: ../build/files.c:954 ../build/files.c:1069
#, c-format
msgid "File not found: %s"
msgstr ""
-#: ../build/files.c:996
+#: ../build/files.c:997
#, c-format
msgid "Bad owner/group: %s\n"
msgstr ""
-#: ../build/files.c:1002
+#: ../build/files.c:1003
#, c-format
msgid "File %4d: 0%o %s.%s\t %s\n"
msgstr ""
-#: ../build/files.c:1052
+#: ../build/files.c:1053
#, c-format
msgid "File needs leading \"/\": %s"
msgstr ""
-#: ../build/files.c:1109
+#: ../build/files.c:1110
msgid "Could not open %%files file: %s"
msgstr ""
-#: ../build/files.c:1116 ../build/pack.c:448
+#: ../build/files.c:1117 ../build/pack.c:448
#, c-format
msgid "line: %s"
msgstr ""
-#: ../build/files.c:1384 ../build/parsePrep.c:40
+#: ../build/files.c:1385 ../build/parsePrep.c:40
#, c-format
msgid "Bad owner/group: %s"
msgstr ""
-#: ../build/files.c:1438
+#: ../build/files.c:1439
#, c-format
msgid "Couldn't exec %s"
msgstr ""
-#: ../build/files.c:1442
+#: ../build/files.c:1443
#, c-format
msgid "Couldn't fork %s"
msgstr ""
-#: ../build/files.c:1492
+#: ../build/files.c:1493
#, c-format
msgid "%s failed"
msgstr ""
-#: ../build/files.c:1496
+#: ../build/files.c:1497
#, c-format
msgid "failed to write all data to %s"
msgstr ""
-#: ../build/files.c:1530
+#: ../build/files.c:1531
msgid "Finding provides...\n"
msgstr ""
-#: ../build/files.c:1537
+#: ../build/files.c:1538
msgid "Failed to find provides"
msgstr ""
-#: ../build/files.c:1556
+#: ../build/files.c:1557
msgid "Finding requires...\n"
msgstr ""
-#: ../build/files.c:1563
+#: ../build/files.c:1564
msgid "Failed to find requires"
msgstr ""
-#: ../build/files.c:1597
+#: ../build/files.c:1598
msgid "Provides:"
msgstr ""
-#: ../build/files.c:1612
+#: ../build/files.c:1613
msgid "Prereqs:"
msgstr ""
-#: ../build/files.c:1624
+#: ../build/files.c:1625
msgid "Requires:"
msgstr ""
-#: ../build/files.c:1648
+#: ../build/files.c:1649
#, c-format
msgid "Processing files: %s\n"
msgstr ""
msgid "line %d: Second %%files list"
msgstr ""
-#: ../build/parsePreamble.c:156
+#: ../build/parsePreamble.c:157
#, c-format
msgid "Architecture is excluded: %s"
msgstr ""
-#: ../build/parsePreamble.c:161
+#: ../build/parsePreamble.c:162
#, c-format
msgid "Architecture is not included: %s"
msgstr ""
-#: ../build/parsePreamble.c:166
+#: ../build/parsePreamble.c:167
#, c-format
msgid "OS is excluded: %s"
msgstr ""
-#: ../build/parsePreamble.c:171
+#: ../build/parsePreamble.c:172
#, c-format
msgid "OS is not included: %s"
msgstr ""
-#: ../build/parsePreamble.c:207
+#: ../build/parsePreamble.c:208
#, c-format
msgid "%s field must be present in package: %s"
msgstr ""
-#: ../build/parsePreamble.c:229
+#: ../build/parsePreamble.c:230
#, c-format
msgid "Duplicate %s entries in package: %s"
msgstr ""
-#: ../build/parsePreamble.c:274
+#: ../build/parsePreamble.c:275
#, c-format
msgid "Unable to stat icon: %s"
msgstr ""
-#: ../build/parsePreamble.c:285
+#: ../build/parsePreamble.c:286
#, c-format
msgid "Unable to read icon: %s"
msgstr ""
-#: ../build/parsePreamble.c:295
+#: ../build/parsePreamble.c:296
#, c-format
msgid "Unknown icon type: %s"
msgstr ""
-#: ../build/parsePreamble.c:330
+#: ../build/parsePreamble.c:331
#, c-format
msgid "line %d: Malformed tag: %s"
msgstr ""
#. Empty field
-#: ../build/parsePreamble.c:338
+#: ../build/parsePreamble.c:339
#, c-format
msgid "line %d: Empty tag: %s"
msgstr ""
-#: ../build/parsePreamble.c:361 ../build/parsePreamble.c:368
+#: ../build/parsePreamble.c:362 ../build/parsePreamble.c:369
#, c-format
msgid "line %d: Illegal char '-' in %s: %s"
msgstr ""
-#: ../build/parsePreamble.c:399
+#: ../build/parsePreamble.c:400
#, c-format
msgid "line %d: BuildRoot can not be \"/\": %s"
msgstr ""
-#: ../build/parsePreamble.c:412
+#: ../build/parsePreamble.c:413
#, c-format
msgid "line %d: Prefixes must not end with \"/\": %s"
msgstr ""
-#: ../build/parsePreamble.c:424
+#: ../build/parsePreamble.c:425
#, c-format
msgid "line %d: Docdir must begin with '/': %s"
msgstr ""
-#: ../build/parsePreamble.c:435
+#: ../build/parsePreamble.c:436
#, c-format
msgid "line %d: Epoch/Serial field must be a number: %s"
msgstr ""
-#: ../build/parsePreamble.c:500
+#: ../build/parsePreamble.c:501
#, c-format
msgid "line %d: Bad BuildArchitecture format: %s"
msgstr ""
-#: ../build/parsePreamble.c:510
+#: ../build/parsePreamble.c:511
#, c-format
msgid "Internal error: Bogus tag %d"
msgstr ""
-#: ../build/parsePreamble.c:655
+#: ../build/parsePreamble.c:656
#, c-format
msgid "Bad package specification: %s"
msgstr ""
-#: ../build/parsePreamble.c:661
+#: ../build/parsePreamble.c:662
#, c-format
msgid "Package already exists: %s"
msgstr ""
-#: ../build/parsePreamble.c:688
+#: ../build/parsePreamble.c:689
#, c-format
msgid "line %d: Unknown tag: %s"
msgstr ""
-#: ../build/parsePreamble.c:713
+#: ../build/parsePreamble.c:714
msgid "Spec file can't use BuildRoot"
msgstr ""
msgid "error removing record %s into %s"
msgstr ""
-#: ../lib/depends.c:371 ../lib/depends.c:530
+#: ../lib/depends.c:372 ../lib/depends.c:531
#, c-format
msgid "cannot read header at %d for dependency check"
msgstr ""
-#: ../lib/depends.c:436
+#: ../lib/depends.c:437
#, c-format
msgid "dependencies: looking for %s\n"
msgstr ""
-#: ../lib/depends.c:623
+#: ../lib/depends.c:624
#, c-format
msgid "package %s require not satisfied: %s\n"
msgstr ""
-#: ../lib/depends.c:666
+#: ../lib/depends.c:667
#, c-format
msgid "package %s conflicts: %s\n"
msgstr ""
-#: ../lib/depends.c:766
+#: ../lib/depends.c:767
msgid "dbrecMatchesDepFlags() failed to read header"
msgstr ""
-#: ../lib/depends.c:818
+#: ../lib/depends.c:819
#, c-format
msgid "loop in prerequisite chain: %s"
msgstr ""
msgid "Invalid signature spec in rc file"
msgstr ""
-#: ../lib/transaction.c:570
+#: ../lib/transaction.c:576
#, c-format
msgid "relocating %s to %s\n"
msgstr ""
-#: ../lib/transaction.c:576
+#: ../lib/transaction.c:582
#, c-format
msgid "excluding %s\n"
msgstr ""
-#: ../lib/transaction.c:663
+#: ../lib/transaction.c:669
#, c-format
msgid "%s skipped due to missingok flag\n"
msgstr ""
#include "url.h"
#include "ftp.h"
-#include "http.h"
static struct urlstring {
const char *leadin;
{
if (u->ftpControl >= 0)
close(u->ftpControl);
+ FREE(u->url);
FREE(u->service);
FREE(u->user);
FREE(u->password);
FREE(u->host);
FREE(u->portstr);
FREE(u->path);
+ FREE(u->proxyu);
+ FREE(u->proxyh);
FREE(u);
}
if ((u = malloc(sizeof(*u))) == NULL)
return NULL;
memset(u, 0, sizeof(*u));
+ u->proxyp = -1;
u->port = -1;
u->ftpControl = -1;
+ u->ftpGetFileDoneNeeded = 0;
return u;
}
}
*empty = u;
} else {
+ /* Swap original url and path into the cached structure */
const char *up = uCache[i]->path;
uCache[i]->path = u->path;
u->path = up;
+ up = uCache[i]->url;
+ uCache[i]->url = u->url;
+ u->url = up;
freeUrlinfo(u);
}
+ /* This URL is now cached. */
*uret = u = uCache[i];
+ /* Perform one-time FTP initialization */
if (!strcmp(u->service, "ftp")) {
+ char *proxy;
+ char *proxyport;
+
if (mustAsk || (u->user != NULL && u->password == NULL)) {
char * prompt;
FREE(u->password);
sprintf(prompt, _("Password for %s@%s: "), u->user, u->host);
u->password = strdup(getpass(prompt));
}
+
+ if (u->proxyh == NULL && (proxy = rpmGetVar(RPMVAR_FTPPROXY)) != NULL) {
+ char *nu = malloc(strlen(u->user) + strlen(u->host) + sizeof("@"));
+ strcpy(nu, u->user);
+ strcat(nu, "@");
+ strcat(nu, u->host);
+ u->proxyu = nu;
+ u->proxyh = strdup(proxy);
+ }
+
+ if (u->proxyp < 0 && (proxyport = rpmGetVar(RPMVAR_FTPPORT)) != NULL) {
+ int port;
+ char *end;
+ port = strtol(proxyport, &end, 0);
+ if (*end) {
+ fprintf(stderr, _("error: %sport must be a number\n"),
+ u->service);
+ return;
+ }
+ u->proxyp = port;
+ }
+ }
+
+ /* Perform one-time HTTP initialization */
+ if (!strcmp(u->service, "http")) {
+ char *proxy;
+ char *proxyport;
+
+ if (u->proxyh == NULL && (proxy = rpmGetVar(RPMVAR_HTTPPROXY)) != NULL) {
+ u->proxyh = strdup(proxy);
+ }
+
+ if (u->proxyp < 0 && (proxyport = rpmGetVar(RPMVAR_HTTPPORT)) != NULL) {
+ int port;
+ char *end;
+ port = strtol(proxyport, &end, 0);
+ if (*end) {
+ fprintf(stderr, _("error: %sport must be a number\n"),
+ u->service);
+ return;
+ }
+ u->proxyp = port;
+ }
}
+
return;
}
freeUrlinfo(u);
return -1;
}
+ u->url = strdup(url);
do {
while (*se && *se != '/') se++;
if (*se == '\0') {
return -1;
if (!strcmp(u->service, "ftp") && u->ftpControl < 0) {
- char *proxy;
- char *proxyport;
rpmMessage(RPMMESS_DEBUG, _("logging into %s as %s, pw %s\n"),
u->host,
u->user ? u->user : "ftp",
u->password ? u->password : "(username)");
- /* XXX FIXME: this doesn't work with urlinfo caching */
- if ((proxy = rpmGetVar(RPMVAR_FTPPROXY)) != NULL) {
- char *nu = malloc(strlen(u->user) + strlen(u->host) + sizeof("@"));
- strcpy(nu, u->user);
- strcat(nu, "@");
- strcat(nu, u->host);
- free((void *)u->user);
- u->user = nu;
- free((void *)u->host);
- u->host = strdup(proxy);
- }
-
- /* XXX FIXME: this doesn't work with urlinfo caching */
- if ((proxyport = rpmGetVar(RPMVAR_FTPPORT)) != NULL) {
- int port;
- char *end;
- port = strtol(proxyport, &end, 0);
- if (*end) {
- fprintf(stderr, _("error: ftpport must be a number\n"));
- return -1;
- }
- u->port = port;
- }
-
u->ftpControl = ftpOpen(u);
- if (u->ftpControl < 0)
+ if (u->ftpControl < 0) { /* XXX save ftpOpen error */
+ u->openError = u->ftpControl;
return u->ftpControl;
+ }
}
break;
if ((fd = fdNew()) == NULL)
break;
- if (httpProxySetup(url,&u))
- break;
fd->fd_url = u;
fd->fd_fd = httpOpen(u);
+ if (fd->fd_fd < 0) /* XXX Save httpOpen error */
+ u->openError = fd->fd_fd;
break;
case URL_IS_PATH:
if (urlSplit(url, &u))
return rc;
}
+
+/* XXX This only works for httpOpen/ftpOpen failures */
+const char *urlStrerror(const char *url)
+{
+ urlinfo *u;
+ if (urlSplit(url, &u))
+ return "Malformed URL";
+ return ftpStrerror(u->openError);
+}
} urltype;
typedef struct urlinfo {
+ const char *url; /* copy of original url */
const char *service;
const char *user;
const char *password;
const char *host;
const char *portstr;
const char *path;
+ const char *proxyu; /* FTP: proxy user */
+ const char *proxyh; /* FTP/HTTP: proxy host */
+ int proxyp; /* FTP/HTTP: proxy port */
int port;
int ftpControl;
int ftpGetFileDoneNeeded;
+ int openError; /* Type of open failure */
} urlinfo;
#ifndef IPPORT_HTTP
FD_t ufdOpen(const char * pathname, int flags, mode_t mode);
int ufdClose(FD_t fd);
+const char *urlStrerror(const char *url);
int urlGetFile(const char * url, const char * dest);