fix: typo in error message (#6858).
tufdio.c: Create. rpmurl.h: Add ctrl, data, buf, and bufAlloced to urlinfo. UFDSANE assertion. rpmio.h: Add fdWritable(), fdReadable(), fdRdline(), exported (for now) to ftp.c checkResponse(). ftp.c: checkResponse() rewritten to use above. ftp.c: checkResponse() handles html in 501 response on closed http connection. ftp.c: ftpCommand() rewritten to simplify (using stpcpy). ftp.c: httpOpen() now reopens time-out persistent connection. ftp.c: Get rid of O_NONBLOCK reads, not necessary AFAICT. ftp.c: ftpFileDesc() uses u->data rather than passed in fd arg. Use a consistent refcounting scheme to achieve persistent malloc and open ctrl. query.c: get ready for Remglob(). rpmio.c: ftpCmd() functional (using tufdio). CVS patchset: 3420 CVS date: 1999/11/09 20:57:38
This commit is contained in:
parent
20cafc16fe
commit
aeab1e959d
1
CHANGES
1
CHANGES
|
@ -4,6 +4,7 @@
|
|||
- check for memory leaks (almost all leaks are plugged).
|
||||
- fix: resurrect multiple target platform builds.
|
||||
- freshen.sh: detect when all packages are up to date (Ian Macdonald).
|
||||
- fix: typo in error message (#6858).
|
||||
|
||||
3.0.2 -> 3.0.3
|
||||
- add --eval to find result of macro expansion.
|
||||
|
|
|
@ -16,6 +16,12 @@ noinst_HEADERS = \
|
|||
lookup.h md5.h oldheader.h oldrpmdb.h rpm_malloc.h \
|
||||
rpmdb.h rpmlead.h signature.h
|
||||
|
||||
mylibs= $(top_builddir)/lib/.libs/librpm.a \
|
||||
$(top_builddir)/popt/.libs/libpopt.a \
|
||||
@INTLLIBS@ \
|
||||
@LIBMISC@
|
||||
|
||||
|
||||
lib_LTLIBRARIES = librpm.la
|
||||
librpm_la_SOURCES = \
|
||||
cpio.c dbindex.c depends.c falloc.c \
|
||||
|
@ -42,11 +48,14 @@ BUILT_SOURCES = tagtable.c
|
|||
.PHONY: lclint
|
||||
.PHONY: lclint
|
||||
lclint:
|
||||
lclint ${DEFS} ${INCLUDES} ${librpm_la_SOURCES}
|
||||
lclint $(DEFS) $(INCLUDES) $(librpm_la_SOURCES)
|
||||
|
||||
tmacro: macro.c
|
||||
$(CC) $(CFLAGS) ${DEFS} -DDEBUG_MACROS ${INCLUDES} -o $@ $<
|
||||
$(CC) $(CFLAGS) $(DEFS) -DDEBUG_MACROS $(INCLUDES) -o $@ $<
|
||||
|
||||
rpmeval: macro.c
|
||||
$(CC) $(CFLAGS) ${DEFS} -DDEBUG_MACROS -DEVAL_MACROS ${INCLUDES} -o $@ $<
|
||||
$(CC) $(CFLAGS) $(DEFS) -DDEBUG_MACROS -DEVAL_MACROS $(INCLUDES) -o $@ $<
|
||||
|
||||
tufdio: tufdio.c
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDES) -o $@ $< $(mylibs) $(LIBS)
|
||||
|
||||
|
|
356
lib/ftp.c
356
lib/ftp.c
|
@ -67,58 +67,41 @@ int inet_aton(const char *cp, struct in_addr *inp);
|
|||
int _ftp_debug = 0;
|
||||
#define DBG(_f, _x) if ((_ftp_debug | (_f))) fprintf _x
|
||||
|
||||
static int checkResponse(urlinfo u, int fdno, int secs, int *ecp,
|
||||
/*@out@*/ char ** str)
|
||||
static int checkResponse(urlinfo u, /*@out@*/ int *ecp, /*@out@*/ char ** str)
|
||||
{
|
||||
static char buf[BUFSIZ + 1]; /* XXX Yuk! */
|
||||
char *buf;
|
||||
size_t bufAlloced;
|
||||
int bufLength = 0;
|
||||
fd_set emptySet, readSet;
|
||||
const char *s;
|
||||
char *se;
|
||||
struct timeval timeout, *tvp = (secs < 0 ? NULL : &timeout);
|
||||
int bytesRead, rc = 0;
|
||||
int doesContinue = 1;
|
||||
int ec = 0;
|
||||
int moretodo = 1;
|
||||
char errorCode[4];
|
||||
|
||||
assert(secs > 0);
|
||||
URLSANE(u);
|
||||
buf = u->buf;
|
||||
bufAlloced = u->bufAlloced;
|
||||
|
||||
errorCode[0] = '\0';
|
||||
u->httpContentLength = -1;
|
||||
|
||||
do {
|
||||
/*
|
||||
* 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 {
|
||||
FD_ZERO(&emptySet);
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(fdno, &readSet);
|
||||
|
||||
if (tvp) {
|
||||
tvp->tv_sec = secs;
|
||||
tvp->tv_usec = 0;
|
||||
}
|
||||
|
||||
rc = select(fdno + 1, &readSet, &emptySet, &emptySet, tvp);
|
||||
if (rc < 1) {
|
||||
if (rc == 0)
|
||||
return FTPERR_BAD_SERVER_RESPONSE;
|
||||
else
|
||||
rc = FTPERR_UNKNOWN;
|
||||
} else
|
||||
rc = 0;
|
||||
|
||||
se = buf + bufLength;
|
||||
bytesRead = read(fdno, se, 1);
|
||||
bufLength += bytesRead;
|
||||
buf[bufLength] = '\0';
|
||||
} while (bufLength < sizeof(buf) && *se != '\n');
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Divide the response into lines. Skip continuation lines.
|
||||
* Read next line from server.
|
||||
*/
|
||||
for (s = se = buf; *s != '\0'; s = se) {
|
||||
se = buf + bufLength;
|
||||
rc = fdRdline(u->ctrl, se, (bufAlloced - bufLength));
|
||||
if (rc < 0) {
|
||||
ec = FTPERR_BAD_SERVER_RESPONSE;
|
||||
continue;
|
||||
} else if (rc == 0 || fdWritable(u->ctrl, 0) < 1)
|
||||
moretodo = 0;
|
||||
|
||||
/*
|
||||
* Process next line from server.
|
||||
*/
|
||||
for (s = se; *s != '\0'; s = se) {
|
||||
const char *e;
|
||||
|
||||
while (*se && *se != '\n') se++;
|
||||
|
@ -132,18 +115,21 @@ static int checkResponse(urlinfo u, int fdno, int secs, int *ecp,
|
|||
|
||||
/* HTTP: header termination on empty line */
|
||||
if (*s == '\0') {
|
||||
doesContinue = 0;
|
||||
moretodo = 0;
|
||||
break;
|
||||
}
|
||||
*se++ = '\0';
|
||||
|
||||
/* HTTP: look for "HTTP/1.1 123 ..." */
|
||||
if (!strncmp(s, "HTTP", sizeof("HTTP")-1)) {
|
||||
u->httpContentLength = -1;
|
||||
if ((e = strchr(s, '.')) != NULL) {
|
||||
e++;
|
||||
u->httpVersion = *e - '0';
|
||||
if (u->httpVersion < 1 || u->httpVersion > 2)
|
||||
u->httpPersist = u->httpVersion = 0;
|
||||
else
|
||||
u->httpPersist = 1;
|
||||
}
|
||||
if ((e = strchr(s, ' ')) != NULL) {
|
||||
e++;
|
||||
|
@ -154,7 +140,7 @@ static int checkResponse(urlinfo u, int fdno, int secs, int *ecp,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* HTTP: look for "<token>: ..." */
|
||||
/* HTTP: look for "token: ..." */
|
||||
for (e = s; *e && !(*e == ' ' || *e == ':'); e++)
|
||||
;
|
||||
if (e > s && *e++ == ':') {
|
||||
|
@ -196,40 +182,46 @@ static int checkResponse(urlinfo u, int fdno, int secs, int *ecp,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* HTTP: look for "<TITLE>501 ... </TITLE>" */
|
||||
if (!strncmp(s, "<TITLE>", sizeof("<TITLE>")-1))
|
||||
s += sizeof("<TITLE>") - 1;
|
||||
|
||||
/* FTP: look for "123-" and/or "123 " */
|
||||
if (strchr("0123456789", *s)) {
|
||||
if (errorCode[0]) {
|
||||
if (!strncmp(s, errorCode, sizeof("123")-1) && s[3] == ' ')
|
||||
doesContinue = 0;
|
||||
moretodo = 0;
|
||||
} else {
|
||||
strncpy(errorCode, s, sizeof("123")-1);
|
||||
errorCode[3] = '\0';
|
||||
if (s[3] != '-')
|
||||
doesContinue = 0;
|
||||
moretodo = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doesContinue && se > s) {
|
||||
if (moretodo && se > s) {
|
||||
bufLength = se - s - 1;
|
||||
if (s != buf)
|
||||
memcpy(buf, s, bufLength);
|
||||
} else {
|
||||
bufLength = 0;
|
||||
}
|
||||
} while (doesContinue && !rc);
|
||||
} while (moretodo && ec == 0);
|
||||
|
||||
if (str) *str = buf;
|
||||
if (ecp) *ecp = atoi(errorCode);
|
||||
|
||||
return rc;
|
||||
return ec;
|
||||
}
|
||||
|
||||
int ftpCheckResponse(urlinfo u, /*@out@*/ char ** str)
|
||||
{
|
||||
int ec = 0;
|
||||
int secs = fdGetRdTimeoutSecs(u->ftpControl);
|
||||
int rc = checkResponse(u, fdio->fileno(u->ftpControl), secs, &ec, str);
|
||||
int rc;
|
||||
|
||||
URLSANE(u);
|
||||
rc = checkResponse(u, &ec, str);
|
||||
|
||||
switch (ec) {
|
||||
case 550:
|
||||
|
@ -246,42 +238,35 @@ int ftpCheckResponse(urlinfo u, /*@out@*/ char ** str)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int ftpCommand(urlinfo u, char * command, ...)
|
||||
int ftpCommand(urlinfo u, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
char * s;
|
||||
char * req;
|
||||
int len = 0;
|
||||
const char * s, * t;
|
||||
char * te;
|
||||
int rc;
|
||||
|
||||
va_start(ap, command);
|
||||
len = strlen(command) + 2;
|
||||
s = va_arg(ap, char *);
|
||||
while (s) {
|
||||
len += strlen(s) + 1;
|
||||
s = va_arg(ap, char *);
|
||||
URLSANE(u);
|
||||
va_start(ap, u);
|
||||
while ((s = va_arg(ap, const char *)) != NULL) {
|
||||
if (len) len++;
|
||||
len += strlen(s);
|
||||
}
|
||||
len += sizeof("\r\n")-1;
|
||||
va_end(ap);
|
||||
|
||||
req = alloca(len + 1);
|
||||
t = te = alloca(len + 1);
|
||||
|
||||
va_start(ap, command);
|
||||
strcpy(req, command);
|
||||
strcat(req, " ");
|
||||
s = va_arg(ap, char *);
|
||||
while (s) {
|
||||
strcat(req, s);
|
||||
strcat(req, " ");
|
||||
s = va_arg(ap, char *);
|
||||
va_start(ap, u);
|
||||
while ((s = va_arg(ap, const char *)) != NULL) {
|
||||
if (te > t) *te++ = ' ';
|
||||
te = stpcpy(te, s);
|
||||
}
|
||||
te = stpcpy(te, "\r\n");
|
||||
va_end(ap);
|
||||
|
||||
req[len - 2] = '\r';
|
||||
req[len - 1] = '\n';
|
||||
req[len] = '\0';
|
||||
|
||||
DBG(0, (stderr, "-> %s", req));
|
||||
if (fdio->write(u->ftpControl, req, len) != len)
|
||||
DBG(0, (stderr, "-> %s", t));
|
||||
if (fdio->write(u->ctrl, t, (te-t)) != (te-t))
|
||||
return FTPERR_SERVER_IO_ERROR;
|
||||
|
||||
rc = ftpCheckResponse(u, NULL);
|
||||
|
@ -320,7 +305,7 @@ static int getHostAddress(const char * host, struct in_addr * address)
|
|||
static int tcpConnect(const char *host, int port)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int sock = -1;
|
||||
int fdno = -1;
|
||||
int rc;
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
|
@ -331,46 +316,70 @@ static int tcpConnect(const char *host, int port)
|
|||
if ((rc = getHostAddress(host, &sin.sin_addr)) < 0)
|
||||
break;
|
||||
|
||||
if ((sock = socket(sin.sin_family, SOCK_STREAM, IPPROTO_IP)) < 0) {
|
||||
if ((fdno = socket(sin.sin_family, SOCK_STREAM, IPPROTO_IP)) < 0) {
|
||||
rc = FTPERR_FAILED_CONNECT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (connect(sock, (struct sockaddr *) &sin, sizeof(sin))) {
|
||||
if (connect(fdno, (struct sockaddr *) &sin, sizeof(sin))) {
|
||||
rc = FTPERR_FAILED_CONNECT;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (rc < 0 && sock >= 0) {
|
||||
close(sock);
|
||||
return rc;
|
||||
}
|
||||
if (rc < 0)
|
||||
goto errxit;
|
||||
|
||||
DBG(0, (stderr,"++ connect %s:%d on fd %d\n",
|
||||
DBG(0, (stderr,"++ connect %s:%d on fdno %d\n",
|
||||
/*@-unrecog@*/ inet_ntoa(sin.sin_addr) /*@=unrecog@*/ ,
|
||||
ntohs(sin.sin_port), sock));
|
||||
ntohs(sin.sin_port), fdno));
|
||||
|
||||
return sock;
|
||||
return fdno;
|
||||
|
||||
errxit:
|
||||
if (fdno >= 0)
|
||||
close(fdno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int httpOpen(urlinfo u, const char *httpcmd)
|
||||
{
|
||||
int sock;
|
||||
const char *host;
|
||||
const char *path;
|
||||
int port;
|
||||
int rc;
|
||||
char *req;
|
||||
size_t len;
|
||||
int retrying = 0;
|
||||
|
||||
if (u == NULL || ((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
|
||||
URLSANE(u);
|
||||
assert(u->ctrl != NULL);
|
||||
|
||||
if (((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;
|
||||
|
||||
reopen:
|
||||
if (fdio->fileno(u->ctrl) >= 0 && fdWritable(u->ctrl, 0) < 1)
|
||||
fdio->close(u->ctrl);
|
||||
|
||||
if (fdio->fileno(u->ctrl) < 0) {
|
||||
rc = tcpConnect(host, port);
|
||||
fdSetFdno(u->ctrl, (rc >= 0 ? rc : -1));
|
||||
if (rc < 0)
|
||||
goto errxit;
|
||||
|
||||
#ifdef DYING
|
||||
/* checkResponse() assumes the socket is nonblocking */
|
||||
if (fcntl(fdio->fileno(u->ctrl), F_SETFL, O_NONBLOCK)) {
|
||||
rc = FTPERR_FAILED_CONNECT;
|
||||
goto errxit;
|
||||
}
|
||||
#endif
|
||||
u->ctrl = fdLink(u->ctrl, "open ctrl (httpOpen)");
|
||||
}
|
||||
|
||||
len = sizeof("\
|
||||
req x HTTP/1.0\r\n\
|
||||
|
@ -391,32 +400,43 @@ Accept: text/plain\r\n\
|
|||
\r\n\
|
||||
", httpcmd, path, (u->httpVersion ? 1 : 0), VERSION, host, port);
|
||||
|
||||
if (write(sock, req, len) != len) {
|
||||
close(sock);
|
||||
return FTPERR_SERVER_IO_ERROR;
|
||||
}
|
||||
|
||||
DBG(0, (stderr, "-> %s", req));
|
||||
|
||||
{ int ec = 0;
|
||||
int secs = fdGetRdTimeoutSecs(u->ftpControl);
|
||||
int rc;
|
||||
rc = checkResponse(u, sock, secs, &ec, NULL);
|
||||
|
||||
switch (ec) {
|
||||
default:
|
||||
if (rc == 0 && ec != 200) /* not HTTP_OK */
|
||||
rc = FTPERR_FILE_NOT_FOUND;
|
||||
break;
|
||||
if (fdio->write(u->ctrl, req, len) != len) {
|
||||
rc = FTPERR_SERVER_IO_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
close(sock);
|
||||
return rc;
|
||||
{ int ec = 0;
|
||||
rc = checkResponse(u, &ec, NULL);
|
||||
|
||||
if (_ftp_debug && !(rc == 0 && ec == 200))
|
||||
fprintf(stderr, "*** httpOpen: rc %d ec %d\n", rc, ec);
|
||||
|
||||
switch (rc) {
|
||||
case 0:
|
||||
if (ec == 200)
|
||||
break;
|
||||
/*@fallthrough@*/
|
||||
default:
|
||||
if (!retrying) { /* not HTTP_OK */
|
||||
retrying = 1;
|
||||
fdio->close(u->ctrl);
|
||||
goto reopen;
|
||||
}
|
||||
rc = FTPERR_FILE_NOT_FOUND;
|
||||
goto errxit;
|
||||
/*@notreached@*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
return sock;
|
||||
u->ctrl = fdLink(u->ctrl, "open data (httpOpen)");
|
||||
return fdio->fileno(u->ctrl);
|
||||
|
||||
errxit:
|
||||
if (fdio->fileno(u->ctrl) >= 0)
|
||||
fdio->close(u->ctrl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ftpOpen(urlinfo u)
|
||||
|
@ -425,10 +445,10 @@ int ftpOpen(urlinfo u)
|
|||
const char * user;
|
||||
const char * password;
|
||||
int port;
|
||||
int secs;
|
||||
int rc;
|
||||
|
||||
if (u == NULL || ((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
|
||||
URLSANE(u);
|
||||
if (((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
|
||||
return FTPERR_BAD_HOSTNAME;
|
||||
|
||||
if ((port = (u->proxyp > 0 ? u->proxyp : u->port)) < 0) port = IPPORT_FTP;
|
||||
|
@ -448,19 +468,26 @@ int ftpOpen(urlinfo u)
|
|||
}
|
||||
}
|
||||
|
||||
secs = fdGetRdTimeoutSecs(u->ftpControl);
|
||||
fdSetFdno(u->ftpControl, tcpConnect(host, port));
|
||||
if (fdio->fileno(u->ftpControl) < 0)
|
||||
return fdio->fileno(u->ftpControl);
|
||||
if (fdio->fileno(u->ctrl) >= 0 && fdWritable(u->ctrl, 0) < 1)
|
||||
fdio->close(u->ctrl);
|
||||
|
||||
/* ftpCheckResponse() assumes the socket is nonblocking */
|
||||
if (fcntl(fdio->fileno(u->ftpControl), F_SETFL, O_NONBLOCK)) {
|
||||
if (fdio->fileno(u->ctrl) < 0) {
|
||||
rc = tcpConnect(host, port);
|
||||
fdSetFdno(u->ctrl, (rc >= 0 ? rc : -1));
|
||||
if (rc < 0)
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
#ifdef DYING
|
||||
/* checkResponse() assumes the socket is nonblocking */
|
||||
if (fcntl(fdio->fileno(u->ctrl), F_SETFL, O_NONBLOCK)) {
|
||||
rc = FTPERR_FAILED_CONNECT;
|
||||
goto errxit;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((rc = ftpCheckResponse(u, NULL)))
|
||||
return rc;
|
||||
goto errxit;
|
||||
|
||||
if ((rc = ftpCommand(u, "USER", user, NULL)))
|
||||
goto errxit;
|
||||
|
@ -471,11 +498,12 @@ int ftpOpen(urlinfo u)
|
|||
if ((rc = ftpCommand(u, "TYPE", "I", NULL)))
|
||||
goto errxit;
|
||||
|
||||
fdLink(u->ftpControl, "open ftpControl");
|
||||
return fdio->fileno(u->ftpControl);
|
||||
u->ctrl = fdLink(u->ctrl, "open ctrl");
|
||||
return fdio->fileno(u->ctrl);
|
||||
|
||||
errxit:
|
||||
fdio->close(u->ftpControl);
|
||||
if (fdio->fileno(u->ctrl) >= 0)
|
||||
fdio->close(u->ctrl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -483,37 +511,46 @@ int ftpFileDone(urlinfo u)
|
|||
{
|
||||
int rc = 0;
|
||||
|
||||
if (u == NULL)
|
||||
return FTPERR_UNKNOWN; /* XXX W2DO? */
|
||||
URLSANE(u);
|
||||
assert(u->ftpFileDoneNeeded);
|
||||
|
||||
if (u->ftpFileDoneNeeded) {
|
||||
u->ftpFileDoneNeeded = 0;
|
||||
fdFree(u->ftpControl, "ftpFileDone (from ftpFileDone)");
|
||||
u->ctrl = fdFree(u->ctrl, "open data (ftpFileDone)");
|
||||
u->ctrl = fdFree(u->ctrl, "grab data (ftpFileDone)");
|
||||
rc = ftpCheckResponse(u, NULL);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ftpFileDesc(urlinfo u, const char *cmd, FD_t fd)
|
||||
int ftpFileDesc(urlinfo u, const char *cmd)
|
||||
{
|
||||
struct sockaddr_in dataAddress;
|
||||
int cmdlen;
|
||||
char * passReply;
|
||||
char * chptr;
|
||||
int rc;
|
||||
FD_t fd;
|
||||
|
||||
if (u == NULL || cmd == NULL || fd == NULL)
|
||||
URLSANE(u);
|
||||
if (cmd == NULL)
|
||||
return FTPERR_UNKNOWN; /* XXX W2DO? */
|
||||
|
||||
cmdlen = strlen(cmd);
|
||||
fd = u->data;
|
||||
|
||||
#ifdef DYING
|
||||
/*
|
||||
* XXX When ftpFileDesc() is called, there may be a lurking
|
||||
* XXX transfer complete message (if ftpFileDone() was not
|
||||
* XXX called to clear that message). Clear that message now.
|
||||
*/
|
||||
|
||||
if (u->ftpFileDoneNeeded)
|
||||
rc = ftpFileDone(u); /* XXX return code ignored */
|
||||
#else
|
||||
assert(u->ftpFileDoneNeeded == 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the ftp version of the Content-Length.
|
||||
*/
|
||||
|
@ -523,22 +560,30 @@ int ftpFileDesc(urlinfo u, const char *cmd, FD_t fd)
|
|||
|
||||
memcpy(req, "SIZE", 4);
|
||||
DBG(0, (stderr, "-> %s", req));
|
||||
if (fdio->write(u->ftpControl, req, cmdlen) != cmdlen)
|
||||
return FTPERR_SERVER_IO_ERROR;
|
||||
if (fdio->write(u->ctrl, req, cmdlen) != cmdlen) {
|
||||
rc = FTPERR_SERVER_IO_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
if ((rc = ftpCheckResponse(u, &passReply)))
|
||||
return rc;
|
||||
if (sscanf(passReply, "%d %u", &rc, &cl) != 2)
|
||||
return FTPERR_BAD_SERVER_RESPONSE;
|
||||
goto errxit;
|
||||
if (sscanf(passReply, "%d %u", &rc, &cl) != 2) {
|
||||
rc = FTPERR_BAD_SERVER_RESPONSE;
|
||||
goto errxit;
|
||||
}
|
||||
rc = 0;
|
||||
u->httpContentLength = cl;
|
||||
}
|
||||
|
||||
DBG(0, (stderr, "-> PASV\n"));
|
||||
if (fdio->write(u->ftpControl, "PASV\r\n", 6) != 6)
|
||||
return FTPERR_SERVER_IO_ERROR;
|
||||
if (fdio->write(u->ctrl, "PASV\r\n", 6) != 6) {
|
||||
rc = FTPERR_SERVER_IO_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
if ((rc = ftpCheckResponse(u, &passReply)))
|
||||
return FTPERR_PASSIVE_ERROR;
|
||||
if ((rc = ftpCheckResponse(u, &passReply))) {
|
||||
rc = FTPERR_PASSIVE_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
chptr = passReply;
|
||||
while (*chptr && *chptr != '(') chptr++;
|
||||
|
@ -561,8 +606,10 @@ int ftpFileDesc(urlinfo u, const char *cmd, FD_t fd)
|
|||
|
||||
{ int i, j;
|
||||
dataAddress.sin_family = AF_INET;
|
||||
if (sscanf(chptr, "%d,%d", &i, &j) != 2)
|
||||
return FTPERR_PASSIVE_ERROR;
|
||||
if (sscanf(chptr, "%d,%d", &i, &j) != 2) {
|
||||
rc = FTPERR_PASSIVE_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
dataAddress.sin_port = htons((((unsigned)i) << 8) + j);
|
||||
}
|
||||
|
||||
|
@ -571,12 +618,19 @@ int ftpFileDesc(urlinfo u, const char *cmd, FD_t fd)
|
|||
if (*chptr == ',') *chptr = '.';
|
||||
}
|
||||
|
||||
if (!inet_aton(passReply, &dataAddress.sin_addr))
|
||||
return FTPERR_PASSIVE_ERROR;
|
||||
if (!inet_aton(passReply, &dataAddress.sin_addr)) {
|
||||
rc = FTPERR_PASSIVE_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
rc = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
fdSetFdno(fd, (rc >= 0 ? rc : -1));
|
||||
if (rc < 0) {
|
||||
rc = FTPERR_FAILED_CONNECT;
|
||||
goto errxit;
|
||||
}
|
||||
fd = fdLink(fd, "open data (ftpFileDesc)");
|
||||
|
||||
fdSetFdno(fd, socket(AF_INET, SOCK_STREAM, IPPROTO_IP));
|
||||
if (fdio->fileno(fd) < 0)
|
||||
return FTPERR_FAILED_CONNECT;
|
||||
/* XXX setsockopt SO_LINGER */
|
||||
/* XXX setsockopt SO_KEEPALIVE */
|
||||
/* XXX setsockopt SO_TOS IPTOS_THROUGHPUT */
|
||||
|
@ -586,19 +640,27 @@ int ftpFileDesc(urlinfo u, const char *cmd, FD_t fd)
|
|||
if (errno == EINTR)
|
||||
continue;
|
||||
fdio->close(fd);
|
||||
return FTPERR_FAILED_DATA_CONNECT;
|
||||
rc = FTPERR_FAILED_DATA_CONNECT;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
DBG(0, (stderr, "-> %s", cmd));
|
||||
if (fdio->write(u->ftpControl, cmd, cmdlen) != cmdlen)
|
||||
return FTPERR_SERVER_IO_ERROR;
|
||||
if (fdio->write(u->ctrl, cmd, cmdlen) != cmdlen) {
|
||||
fdio->close(fd);
|
||||
rc = FTPERR_SERVER_IO_ERROR;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
if ((rc = ftpCheckResponse(u, NULL))) {
|
||||
fdio->close(fd);
|
||||
return rc;
|
||||
goto errxit;
|
||||
}
|
||||
|
||||
u->ftpFileDoneNeeded = 1;
|
||||
fdLink(u->ftpControl, "ftpFileDone");
|
||||
u->ctrl = fdLink(u->ctrl, "grab data (ftpFileDesc)");
|
||||
u->ctrl = fdLink(u->ctrl, "open data (ftpFileDesc)");
|
||||
return 0;
|
||||
|
||||
errxit:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -761,7 +761,7 @@ void headerDump(Header h, FILE *f, int flags,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, _("Data type %d not supprted\n"),
|
||||
fprintf(stderr, _("Data type %d not supported\n"),
|
||||
(int) p->info.type);
|
||||
exit(EXIT_FAILURE);
|
||||
/*@notreached@*/ break;
|
||||
|
|
34
lib/query.c
34
lib/query.c
|
@ -454,11 +454,14 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
int retcode = 0;
|
||||
char *end = NULL;
|
||||
|
||||
switch (source) {
|
||||
case RPMQV_RPM:
|
||||
{ FD_t fd;
|
||||
switch (source) {
|
||||
case RPMQV_RPM:
|
||||
{ const char *myargv[2], **argv = myargv;;
|
||||
|
||||
fd = Fopen(arg, "r.ufdio");
|
||||
argv[0] = arg;
|
||||
argv[1] = NULL;
|
||||
while ((arg = *argv++) != NULL) {
|
||||
FD_t fd = Fopen(arg, "r.ufdio");
|
||||
if (Ferror(fd)) {
|
||||
/* XXX Fstrerror */
|
||||
fprintf(stderr, _("open of %s failed: %s\n"), arg,urlStrerror(arg));
|
||||
|
@ -490,9 +493,10 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
retcode = 1;
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case RPMQV_SPECFILE:
|
||||
case RPMQV_SPECFILE:
|
||||
if (showPackage != showQueryPackage)
|
||||
return 1;
|
||||
|
||||
|
@ -532,7 +536,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
freeSpecVec(spec);
|
||||
} break;
|
||||
|
||||
case RPMQV_ALL:
|
||||
case RPMQV_ALL:
|
||||
for (offset = rpmdbFirstRecNum(db);
|
||||
offset != 0;
|
||||
offset = rpmdbNextRecNum(db, offset)) {
|
||||
|
@ -547,7 +551,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_GROUP:
|
||||
case RPMQV_GROUP:
|
||||
if (rpmdbFindByGroup(db, arg, &matches)) {
|
||||
fprintf(stderr, _("group %s does not contain any packages\n"), arg);
|
||||
retcode = 1;
|
||||
|
@ -557,7 +561,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_WHATPROVIDES:
|
||||
case RPMQV_WHATPROVIDES:
|
||||
if (rpmdbFindByProvides(db, arg, &matches)) {
|
||||
fprintf(stderr, _("no package provides %s\n"), arg);
|
||||
retcode = 1;
|
||||
|
@ -567,7 +571,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_TRIGGEREDBY:
|
||||
case RPMQV_TRIGGEREDBY:
|
||||
if (rpmdbFindByTriggeredBy(db, arg, &matches)) {
|
||||
fprintf(stderr, _("no package triggers %s\n"), arg);
|
||||
retcode = 1;
|
||||
|
@ -577,7 +581,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_WHATREQUIRES:
|
||||
case RPMQV_WHATREQUIRES:
|
||||
if (rpmdbFindByRequiredBy(db, arg, &matches)) {
|
||||
fprintf(stderr, _("no package requires %s\n"), arg);
|
||||
retcode = 1;
|
||||
|
@ -587,7 +591,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_PATH:
|
||||
case RPMQV_PATH:
|
||||
if (rpmdbFindByFile(db, arg, &matches)) {
|
||||
int myerrno = 0;
|
||||
if (access(arg, F_OK) != 0)
|
||||
|
@ -607,7 +611,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_DBOFFSET:
|
||||
case RPMQV_DBOFFSET:
|
||||
recNumber = strtoul(arg, &end, 10);
|
||||
if ((*end) || (end == arg) || (recNumber == ULONG_MAX)) {
|
||||
fprintf(stderr, _("invalid package number: %s\n"), arg);
|
||||
|
@ -624,7 +628,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
}
|
||||
break;
|
||||
|
||||
case RPMQV_PACKAGE:
|
||||
case RPMQV_PACKAGE:
|
||||
rc = rpmdbFindByLabel(db, arg, &matches);
|
||||
if (rc == 1) {
|
||||
retcode = 1;
|
||||
|
@ -637,7 +641,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
|
|||
dbiFreeIndexRecord(matches);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ static void * showProgress(const Header h, const rpmCallbackType what,
|
|||
|
||||
switch (what) {
|
||||
case RPMCALLBACK_INST_OPEN_FILE:
|
||||
fd = Fopen(filename, "r.fdio");
|
||||
fd = Fopen(filename, "r.ufdio");
|
||||
return fd;
|
||||
|
||||
case RPMCALLBACK_INST_CLOSE_FILE:
|
||||
|
@ -186,7 +186,7 @@ int rpmInstall(const char * rootdir, const char ** argv, int transFlags,
|
|||
would create all sorts of confusion later. */
|
||||
|
||||
for (filename = packages; *filename; filename++) {
|
||||
fd = Fopen(*filename, "r.fdio");
|
||||
fd = Fopen(*filename, "r.ufdio");
|
||||
if (Ferror(fd)) {
|
||||
/* XXX Fstrerror */
|
||||
rpmMessage(RPMMESS_ERROR, _("cannot open file %s\n"), *filename);
|
||||
|
|
|
@ -78,8 +78,6 @@ int Unlink (const char * path);
|
|||
|
||||
/*@observer@*/ extern FDIO_t gzdio;
|
||||
|
||||
int timedRead(FD_t fd, /*@out@*/void * bufptr, int length);
|
||||
|
||||
void fdSetFdno(FD_t fd, int fdno);
|
||||
/*@null@*/ const FDIO_t fdGetIoCookie(FD_t fd);
|
||||
void fdSetIoCookie(FD_t fd, FDIO_t iop);
|
||||
|
@ -142,6 +140,12 @@ const char *const ftpStrerror(int errorNumber);
|
|||
#define ufdUnlink ufdio->unlink
|
||||
#endif
|
||||
|
||||
int fdWritable(FD_t fd, int secs);
|
||||
int fdReadable(FD_t fd, int secs);
|
||||
int fdRdline(FD_t fd, /*@out@*/ char * buf, size_t len);
|
||||
|
||||
int timedRead(FD_t fd, /*@out@*/ void * bufptr, int length);
|
||||
|
||||
/*@observer@*/ extern FDIO_t ufdio;
|
||||
#define timedRead ufdio->read
|
||||
|
||||
|
|
19
lib/rpmurl.h
19
lib/rpmurl.h
|
@ -1,6 +1,8 @@
|
|||
#ifndef H_RPMURL
|
||||
#define H_RPMURL
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef IPPORT_FTP
|
||||
#define IPPORT_FTP 21
|
||||
#endif
|
||||
|
@ -29,6 +31,9 @@ typedef enum {
|
|||
URL_IS_HTTP = 4
|
||||
} urltype;
|
||||
|
||||
#define URLMAGIC 0xd00b1ed0
|
||||
#define URLSANE(u) assert(u && u->magic == URLMAGIC)
|
||||
|
||||
typedef /*@abstract@*/ /*@refcounted@*/ struct urlinfo {
|
||||
/*@refs@*/ int nrefs;
|
||||
const char * url; /* copy of original url */
|
||||
|
@ -42,13 +47,17 @@ typedef /*@abstract@*/ /*@refcounted@*/ struct urlinfo {
|
|||
const char * proxyh; /* FTP/HTTP: proxy host */
|
||||
int proxyp; /* FTP/HTTP: proxy port */
|
||||
int port;
|
||||
FD_t ftpControl;
|
||||
FD_t ctrl; /* control channel */
|
||||
FD_t data; /* per-xfer data channel */
|
||||
int bufAlloced; /* sizeof I/O buffer */
|
||||
char *buf; /* I/O buffer */
|
||||
int ftpFileDoneNeeded;
|
||||
int openError; /* Type of open failure */
|
||||
int httpVersion;
|
||||
int httpHasRange;
|
||||
int httpContentLength;
|
||||
int httpPersist;
|
||||
int magic;
|
||||
} *urlinfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -56,10 +65,12 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
int ftpCheckResponse(urlinfo u, /*@out@*/ char ** str);
|
||||
int ftpCommand(urlinfo u, ...);
|
||||
|
||||
int httpOpen(urlinfo u, const char * httpcmd);
|
||||
int ftpOpen(urlinfo u);
|
||||
int ftpFileDone(urlinfo u);
|
||||
int ftpFileDesc(urlinfo u, const char * cmd, FD_t fd);
|
||||
int ftpFileDesc(urlinfo u, const char * cmd);
|
||||
|
||||
urlinfo urlLink(urlinfo u, const char * msg);
|
||||
urlinfo XurlLink(urlinfo u, const char * msg, const char * file, unsigned line);
|
||||
|
@ -69,8 +80,8 @@ urlinfo urlNew(const char * msg);
|
|||
urlinfo XurlNew(const char * msg, const char * file, unsigned line);
|
||||
#define urlNew(_msg) XurlNew(_msg, __FILE__, __LINE__)
|
||||
|
||||
void urlFree( /*@killref@*/ urlinfo u, const char * msg);
|
||||
void XurlFree( /*@killref@*/ urlinfo u, const char * msg, const char * file, unsigned line);
|
||||
urlinfo urlFree( /*@killref@*/ urlinfo u, const char * msg);
|
||||
urlinfo XurlFree( /*@killref@*/ urlinfo u, const char * msg, const char * file, unsigned line);
|
||||
#define urlFree(_u, _msg) XurlFree(_u, _msg, __FILE__, __LINE__)
|
||||
|
||||
void urlFreeCache(void);
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
#include "system.h"
|
||||
|
||||
#include <rpmlib.h>
|
||||
#include <rpmurl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <err.h>
|
||||
|
||||
extern int _ftp_debug;
|
||||
extern int _url_debug;
|
||||
extern int _rpmio_debug;
|
||||
|
||||
#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
|
||||
|
||||
const char *tmpdir = "/tmp";
|
||||
const char *dio_xxxxxx = "/dio.XXXXXX";
|
||||
#define DIO_XXXXXX alloca_strdup(dio_xxxxxx)
|
||||
const char *fio_xxxxxx = "/fio.XXXXXX";
|
||||
#define FIO_XXXXXX alloca_strdup(fio_xxxxxx)
|
||||
|
||||
static const char * xstrconcat(const char * arg, ...)
|
||||
{
|
||||
const char *s;
|
||||
char *t, *te;
|
||||
size_t nt = 0;
|
||||
va_list ap;
|
||||
|
||||
if (arg == NULL) return xstrdup("");
|
||||
|
||||
va_start(ap, arg);
|
||||
for (s = arg; s != NULL; s = va_arg(ap, const char *))
|
||||
nt += strlen(s);
|
||||
va_end(ap);
|
||||
|
||||
te = t = xmalloc(nt+1);
|
||||
|
||||
va_start(ap, arg);
|
||||
for (s = arg; s != NULL; s = va_arg(ap, const char *))
|
||||
te = stpcpy(te, s);
|
||||
va_end(ap);
|
||||
*te = '\0';
|
||||
return t;
|
||||
}
|
||||
|
||||
static int doFIO(const char *ofn, const char *rfmode, const char *wfmode)
|
||||
{
|
||||
FD_t fd;
|
||||
int rc = 0;
|
||||
char buf[8192];
|
||||
|
||||
if ((fd = Fopen(ofn, wfmode)) == NULL)
|
||||
warn("Fopen: write %s (%s) %s\n", wfmode, rfmode, ofn);
|
||||
else if ((rc = Fwrite(ofn, 1, strlen(ofn), fd)) != strlen(ofn))
|
||||
warn("Fwrite: write %s (%s) %s\n", wfmode, rfmode, ofn);
|
||||
else if ((rc = Fclose(fd)) != 0)
|
||||
warn("Fclose: write %s (%s) %s\n", wfmode, rfmode, ofn);
|
||||
else if ((fd = Fopen(ofn, rfmode)) == NULL)
|
||||
warn("Fopen: read %s (%s) %s\n", rfmode, wfmode, ofn);
|
||||
else if ((rc = Fread(buf, 1, sizeof(buf), fd)) != strlen(ofn))
|
||||
warn("Fread: read %s (%s) %s\n", rfmode, wfmode, ofn);
|
||||
else if ((rc = Fclose(fd)) != 0)
|
||||
warn("Fclose: read %s (%s) %s\n", rfmode, wfmode, ofn);
|
||||
else if (strcmp(ofn, buf))
|
||||
warn("Compare: write(%s) \"%s\" != read(%s) \"%s\" for %s\n", wfmode, ofn, rfmode, buf, ofn);
|
||||
else
|
||||
rc = 0;
|
||||
if (ufdio->unlink(ofn) != 0)
|
||||
warn("Unlink: write(%s) read(%s) for %s\n", wfmode, rfmode, ofn);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int doFile(const char * url, const char * odn, const char * ndn)
|
||||
{
|
||||
const char * ofn = xstrconcat(odn, mktemp(FIO_XXXXXX), NULL);
|
||||
const char * nfn = xstrconcat(ndn, mktemp(FIO_XXXXXX), NULL);
|
||||
FD_t fd;
|
||||
int rc;
|
||||
|
||||
if ((fd = Fopen(ofn, "r.ufdio")) != NULL)
|
||||
err(1, "Fopen: r !exists %s fail\n", ofn);
|
||||
|
||||
rc = doFIO(ofn, "r.ufdio", "w.ufdio");
|
||||
rc = doFIO(nfn, "r.ufdio", "w.ufdio");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int doDir(const char *url)
|
||||
{
|
||||
const char * odn = xstrconcat(url, tmpdir, mktemp(DIO_XXXXXX), NULL);
|
||||
const char * ndn = xstrconcat(url, tmpdir, mktemp(DIO_XXXXXX), NULL);
|
||||
|
||||
fprintf(stderr, "*** Rename #1 %s -> %s fail\n", ndn, odn);
|
||||
if (!ufdio->rename(ndn, odn))
|
||||
err(1, "Rename: dir !exists %s !exists %s fail\n", ndn, odn);
|
||||
fprintf(stderr, "*** Chdir #1 %s fail\n", odn);
|
||||
if (!ufdio->chdir(odn)) err(1, "Chdir: !exists %s fail\n", odn);
|
||||
|
||||
fprintf(stderr, "*** Mkdir #1 %s\n", odn);
|
||||
if (ufdio->mkdir(odn, 0755)) err(1, "Mkdir: !exists %s\n", odn);
|
||||
fprintf(stderr, "*** Mkdir %s fail\n", odn);
|
||||
if (!ufdio->mkdir(odn, 0755)) err(1, "Mkdir: exists %s fail\n", odn);
|
||||
|
||||
fprintf(stderr, "*** Chdir #2 %s\n", odn);
|
||||
if (ufdio->chdir(odn)) err(1, "Chdir: exists %s\n", odn);
|
||||
|
||||
fprintf(stderr, "*** Rename #2 %s -> %s fail\n", ndn, odn);
|
||||
if (!ufdio->rename(ndn, odn))
|
||||
err(1, "Rename: dir !exists %s exists %s fail\n", ndn, odn);
|
||||
fprintf(stderr, "*** Rename #3 %s -> %s\n", odn, ndn);
|
||||
if (ufdio->rename(odn, ndn))
|
||||
err(1, "Rename: dir exists %s !exists %s\n", odn, ndn);
|
||||
|
||||
fprintf(stderr, "*** Mkdir #2 %s\n", ndn);
|
||||
if (ufdio->mkdir(odn, 0755)) err(1, "Mkdir: #2 !exists %s\n", odn);
|
||||
|
||||
fprintf(stderr, "*** Rename #4 %s -> %s fail\n", odn, ndn);
|
||||
if (!ufdio->rename(odn, ndn))
|
||||
err(1, "Rename: dir exists %s exists %s fail\n", odn, ndn);
|
||||
|
||||
doFile(url, odn, ndn);
|
||||
|
||||
fprintf(stderr, "*** Rmdir #1 %s\n", odn);
|
||||
if (ufdio->rmdir(odn)) err(1, "Rmdir: exists %s\n", odn);
|
||||
fprintf(stderr, "*** Rmdir #1 %s fail\n", odn);
|
||||
if (!ufdio->rmdir(odn)) err(1, "Rmdir: !exists %s fail\n", odn);
|
||||
|
||||
fprintf(stderr, "*** Rmdir #3 %s\n", ndn);
|
||||
if (ufdio->rmdir(ndn)) err(1, "Rmdir: exists %s\n", ndn);
|
||||
fprintf(stderr, "*** Rmdir #4 %s fail\n", ndn);
|
||||
if (!ufdio->rmdir(ndn)) err(1, "Rmdir: !exists %s fail\n", ndn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int doUrl(const char *url)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = doDir(url);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
|
||||
_ftp_debug = -1;
|
||||
_url_debug = -1;
|
||||
_rpmio_debug = -1;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s: url ...\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = doUrl(argv[1]);
|
||||
|
||||
return 0;
|
||||
}
|
73
lib/url.c
73
lib/url.c
|
@ -15,11 +15,13 @@
|
|||
|
||||
/*@access urlinfo@*/
|
||||
|
||||
#define URL_IOBUF_SIZE 4096
|
||||
|
||||
#define RPMURL_DEBUG_IO 0x40000000
|
||||
#define RPMURL_DEBUG_REFS 0x20000000
|
||||
|
||||
static int url_debug = 0;
|
||||
#define DBG(_f, _m, _x) if ((url_debug | (_f)) & (_m)) fprintf _x
|
||||
int _url_debug = 0;
|
||||
#define DBG(_f, _m, _x) if ((_url_debug | (_f)) & (_m)) fprintf _x
|
||||
|
||||
#define DBGIO(_f, _x) DBG((_f), RPMURL_DEBUG_IO, _x)
|
||||
#define DBGREFS(_f, _x) DBG((_f), RPMURL_DEBUG_REFS, _x)
|
||||
|
@ -29,6 +31,7 @@ static int uCount = 0;
|
|||
|
||||
urlinfo XurlLink(urlinfo u, const char *msg, const char *file, unsigned line)
|
||||
{
|
||||
URLSANE(u);
|
||||
u->nrefs++;
|
||||
DBGREFS(0, (stderr, "--> url %p ++ %d %s at %s:%u\n", u, u->nrefs, msg, file, line));
|
||||
return u;
|
||||
|
@ -42,26 +45,44 @@ urlinfo XurlNew(const char *msg, const char *file, unsigned line)
|
|||
memset(u, 0, sizeof(*u));
|
||||
u->proxyp = -1;
|
||||
u->port = -1;
|
||||
u->ftpControl = fdio->new(fdio, "url ftpControl", __FILE__, __LINE__);
|
||||
u->ctrl = NULL;
|
||||
u->data = NULL;
|
||||
u->bufAlloced = 0;
|
||||
u->buf = NULL;
|
||||
u->ftpFileDoneNeeded = 0;
|
||||
u->httpVersion = 0;
|
||||
u->httpHasRange = 1;
|
||||
u->httpContentLength = 0;
|
||||
u->httpPersist = 1;
|
||||
u->httpPersist = u->httpVersion = 0;
|
||||
u->nrefs = 0;
|
||||
u->magic = URLMAGIC;
|
||||
return XurlLink(u, msg, file, line);
|
||||
}
|
||||
|
||||
void XurlFree(urlinfo u, const char *msg, const char *file, unsigned line)
|
||||
urlinfo XurlFree(urlinfo u, const char *msg, const char *file, unsigned line)
|
||||
{
|
||||
URLSANE(u);
|
||||
DBGREFS(0, (stderr, "--> url %p -- %d %s at %s:%u\n", u, u->nrefs, msg, file, line));
|
||||
if (--u->nrefs > 0)
|
||||
return;
|
||||
if (u->ftpControl) {
|
||||
if (fdio->fileno(u->ftpControl) >= 0)
|
||||
fdio->close(u->ftpControl);
|
||||
fdio->deref(u->ftpControl, "url ftpControl (from urlFree)", __FILE__, __LINE__);
|
||||
u->ftpControl = NULL;
|
||||
return u;
|
||||
if (u->ctrl) {
|
||||
if (fdio->fileno(u->ctrl) >= 0)
|
||||
fdio->close(u->ctrl);
|
||||
u->ctrl = fdio->deref(u->ctrl, "persist ctrl (urlFree)", file, line);
|
||||
if (u->ctrl)
|
||||
fprintf(stderr, "warning: ctrl nrefs != 0 (%s %s)\n",
|
||||
u->host, u->service);
|
||||
}
|
||||
if (u->data) {
|
||||
if (fdio->fileno(u->data) >= 0)
|
||||
fdio->close(u->data);
|
||||
u->data = fdio->deref(u->data, "persist data (urlFree)", file, line);
|
||||
if (u->data)
|
||||
fprintf(stderr, "warning: data nrefs != 0 (%s %s)\n",
|
||||
u->host, u->service);
|
||||
}
|
||||
if (u->buf) {
|
||||
free(u->buf);
|
||||
u->buf = NULL;
|
||||
}
|
||||
FREE(u->url);
|
||||
FREE(u->service);
|
||||
|
@ -74,6 +95,7 @@ DBGREFS(0, (stderr, "--> url %p -- %d %s at %s:%u\n", u, u->nrefs, msg, file, li
|
|||
FREE(u->proxyh);
|
||||
|
||||
/*@-refcounttrans@*/ FREE(u); /*@-refcounttrans@*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void urlFreeCache(void)
|
||||
|
@ -81,10 +103,10 @@ void urlFreeCache(void)
|
|||
int i;
|
||||
for (i = 0; i < uCount; i++) {
|
||||
if (uCache[i] == NULL) continue;
|
||||
if (uCache[i]->nrefs != 1)
|
||||
fprintf(stderr, "==> nrefs(%d) != 1 (%s %s)\n", uCache[i]->nrefs,
|
||||
uCache[i] = urlFree(uCache[i], "uCache");
|
||||
if (uCache[i])
|
||||
fprintf(stderr, "warning: nrefs(%d) != 1 (%s %s)\n", uCache[i]->nrefs,
|
||||
uCache[i]->host, uCache[i]->service);
|
||||
urlFree(uCache[i], "uCache");
|
||||
}
|
||||
if (uCache)
|
||||
free(uCache);
|
||||
|
@ -111,6 +133,7 @@ static void urlFind(urlinfo *uret, int mustAsk)
|
|||
return;
|
||||
|
||||
u = *uret;
|
||||
URLSANE(u);
|
||||
|
||||
ucx = -1;
|
||||
for (i = 0; i < uCount; i++) {
|
||||
|
@ -149,7 +172,10 @@ static void urlFind(urlinfo *uret, int mustAsk)
|
|||
uCache = xmalloc(sizeof(*uCache));
|
||||
}
|
||||
uCache[i] = urlLink(u, "uCache (miss)");
|
||||
urlFree(u, "urlSplit (from urlFind miss)");
|
||||
u->ctrl = fdNew(fdio, "persist ctrl");
|
||||
u->bufAlloced = URL_IOBUF_SIZE;
|
||||
u->buf = xcalloc(u->bufAlloced, sizeof(char));
|
||||
u = urlFree(u, "urlSplit (urlFind miss)");
|
||||
} else {
|
||||
/* XXX Swap original url and path into the cached structure */
|
||||
const char *up = uCache[i]->path;
|
||||
|
@ -159,14 +185,14 @@ static void urlFind(urlinfo *uret, int mustAsk)
|
|||
up = uCache[ucx]->url;
|
||||
uCache[ucx]->url = u->url;
|
||||
u->url = up;
|
||||
urlFree(u, "urlSplit (from urlFind hit)");
|
||||
u = urlFree(u, "urlSplit (urlFind hit)");
|
||||
}
|
||||
|
||||
/* This URL is now cached. */
|
||||
|
||||
u = urlLink(uCache[i], "uCache");
|
||||
*uret = u;
|
||||
urlFree(u, "uCache (from urlFind)");
|
||||
u = urlFree(u, "uCache (urlFind)");
|
||||
|
||||
/* Zap proxy host and port in case they have been reset */
|
||||
u->proxyp = -1;
|
||||
|
@ -283,7 +309,7 @@ int urlSplit(const char * url, urlinfo *uret)
|
|||
return -1;
|
||||
|
||||
if ((se = s = myurl = xstrdup(url)) == NULL) {
|
||||
urlFree(u, "urlSplit (error #1)");
|
||||
u = urlFree(u, "urlSplit (error #1)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -295,7 +321,7 @@ int urlSplit(const char * url, urlinfo *uret)
|
|||
if (*se == '\0') {
|
||||
/* XXX can't find path */
|
||||
if (myurl) free(myurl);
|
||||
urlFree(u, "urlSplit (error #2)");
|
||||
u = urlFree(u, "urlSplit (error #2)");
|
||||
return -1;
|
||||
}
|
||||
/* Item was service. Save service and go for the rest ...*/
|
||||
|
@ -340,7 +366,7 @@ int urlSplit(const char * url, urlinfo *uret)
|
|||
if (!(end && *end == '\0')) {
|
||||
rpmMessage(RPMMESS_ERROR, _("url port must be a number\n"));
|
||||
if (myurl) free(myurl);
|
||||
urlFree(u, "urlSplit (error #3)");
|
||||
u = urlFree(u, "urlSplit (error #3)");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +407,6 @@ int urlGetFile(const char * url, const char * dest) {
|
|||
}
|
||||
|
||||
sfu = ufdGetUrlinfo(sfd);
|
||||
|
||||
if (sfu != NULL && dest == NULL) {
|
||||
const char *fileName = sfu->path;
|
||||
if ((dest = strrchr(fileName, '/')) != NULL)
|
||||
|
@ -389,6 +414,10 @@ int urlGetFile(const char * url, const char * dest) {
|
|||
else
|
||||
dest = fileName;
|
||||
}
|
||||
if (sfu != NULL) {
|
||||
(void) urlFree(sfu, "ufdGetUrlinfo (urlGetFile)");
|
||||
sfu = NULL;
|
||||
}
|
||||
|
||||
tfd = Fopen(dest, "w.fdio");
|
||||
if (Ferror(tfd)) {
|
||||
|
|
113
po/rpm.pot
113
po/rpm.pot
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 1999-11-05 14:49-0500\n"
|
||||
"POT-Creation-Date: 1999-11-09 15:28-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"
|
||||
|
@ -2111,16 +2111,11 @@ msgstr ""
|
|||
msgid "grabData() RPM_STRING_TYPE count must be 1.\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/header.c:201
|
||||
#: lib/header.c:201 lib/header.c:764
|
||||
#, c-format
|
||||
msgid "Data type %d not supported\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/header.c:764
|
||||
#, c-format
|
||||
msgid "Data type %d not supprted\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/header.c:1121
|
||||
#, c-format
|
||||
msgid "Bad count for headerAddEntry(): %d\n"
|
||||
|
@ -2530,150 +2525,150 @@ msgid "error: could not read database record\n"
|
|||
msgstr ""
|
||||
|
||||
#. XXX Fstrerror
|
||||
#: lib/query.c:464
|
||||
#: lib/query.c:467
|
||||
#, c-format
|
||||
msgid "open of %s failed: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:477
|
||||
#: lib/query.c:480
|
||||
msgid "old format source packages cannot be queried\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:486 lib/rpminstall.c:204
|
||||
#: lib/query.c:489 lib/rpminstall.c:204
|
||||
#, c-format
|
||||
msgid "%s does not appear to be a RPM package\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:489
|
||||
#: lib/query.c:492
|
||||
#, c-format
|
||||
msgid "query of %s failed\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:516
|
||||
#: lib/query.c:520
|
||||
#, c-format
|
||||
msgid "query of specfile %s failed, can't parse\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:541
|
||||
#: lib/query.c:545
|
||||
msgid "could not read database record!\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:552
|
||||
#: lib/query.c:556
|
||||
#, c-format
|
||||
msgid "group %s does not contain any packages\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:562
|
||||
#: lib/query.c:566
|
||||
#, c-format
|
||||
msgid "no package provides %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:572
|
||||
#: lib/query.c:576
|
||||
#, c-format
|
||||
msgid "no package triggers %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:582
|
||||
#: lib/query.c:586
|
||||
#, c-format
|
||||
msgid "no package requires %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:597
|
||||
#: lib/query.c:601
|
||||
#, c-format
|
||||
msgid "file %s: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:600
|
||||
#: lib/query.c:604
|
||||
#, c-format
|
||||
msgid "file %s is not owned by any package\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:613
|
||||
#: lib/query.c:617
|
||||
#, c-format
|
||||
msgid "invalid package number: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:616
|
||||
#: lib/query.c:620
|
||||
#, c-format
|
||||
msgid "package record number: %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:619
|
||||
#: lib/query.c:623
|
||||
#, c-format
|
||||
msgid "record %d could not be read\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:631 lib/rpminstall.c:395
|
||||
#: lib/query.c:635 lib/rpminstall.c:395
|
||||
#, c-format
|
||||
msgid "package %s is not installed\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:634
|
||||
#: lib/query.c:638
|
||||
#, c-format
|
||||
msgid "error looking for package %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:656
|
||||
#: lib/query.c:660
|
||||
msgid "rpmQuery: rpmdbOpen() failed\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:715
|
||||
#: lib/query.c:719
|
||||
msgid "query package owning file"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:717
|
||||
#: lib/query.c:721
|
||||
msgid "query packages in group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:719
|
||||
#: lib/query.c:723
|
||||
msgid "query a package file"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:723
|
||||
#: lib/query.c:727
|
||||
msgid "query a spec file"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:725
|
||||
#: lib/query.c:729
|
||||
msgid "query the pacakges triggered by the package"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:727
|
||||
#: lib/query.c:731
|
||||
msgid "query the packages which require a capability"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:729
|
||||
#: lib/query.c:733
|
||||
msgid "query the packages which provide a capability"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:768
|
||||
#: lib/query.c:772
|
||||
msgid "list all configuration files"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:770
|
||||
#: lib/query.c:774
|
||||
msgid "list all documentation files"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:772
|
||||
#: lib/query.c:776
|
||||
msgid "dump basic file information"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:774
|
||||
#: lib/query.c:778
|
||||
msgid "list files in package"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:778
|
||||
#: lib/query.c:782
|
||||
msgid "use the following query format"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:780
|
||||
#: lib/query.c:784
|
||||
msgid "substitute i18n sections from the following catalogue"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:783
|
||||
#: lib/query.c:787
|
||||
msgid "display the states of the listed files"
|
||||
msgstr ""
|
||||
|
||||
#: lib/query.c:785
|
||||
#: lib/query.c:789
|
||||
msgid "display a verbose file listing"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2827,7 +2822,7 @@ msgid "opening database mode 0x%x in %s\n"
|
|||
msgstr ""
|
||||
|
||||
#. XXX Fstrerror
|
||||
#: lib/rpmdb.c:156 lib/url.c:378
|
||||
#: lib/rpmdb.c:156 lib/url.c:404
|
||||
#, c-format
|
||||
msgid "failed to open %s\n"
|
||||
msgstr ""
|
||||
|
@ -3021,59 +3016,59 @@ msgstr ""
|
|||
msgid "Installing %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:291
|
||||
#: lib/rpmio.c:327
|
||||
msgid "Success"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:294
|
||||
#: lib/rpmio.c:330
|
||||
msgid "Bad server response"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:297
|
||||
#: lib/rpmio.c:333
|
||||
msgid "Server IO error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:300
|
||||
#: lib/rpmio.c:336
|
||||
msgid "Server timeout"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:303
|
||||
#: lib/rpmio.c:339
|
||||
msgid "Unable to lookup server host address"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:306
|
||||
#: lib/rpmio.c:342
|
||||
msgid "Unable to lookup server host name"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:309
|
||||
#: lib/rpmio.c:345
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:312
|
||||
#: lib/rpmio.c:348
|
||||
msgid "Failed to establish data connection to server"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:315
|
||||
#: lib/rpmio.c:351
|
||||
msgid "IO error to local file"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:318
|
||||
#: lib/rpmio.c:354
|
||||
msgid "Error setting remote server to passive mode"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:321
|
||||
#: lib/rpmio.c:357
|
||||
msgid "File not found on server"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:324
|
||||
#: lib/rpmio.c:360
|
||||
msgid "Abort in progress"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:328
|
||||
#: lib/rpmio.c:364
|
||||
msgid "Unknown or unexpected error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/rpmio.c:368
|
||||
#: lib/rpmio.c:412
|
||||
#, c-format
|
||||
msgid "logging into %s as %s, pw %s\n"
|
||||
msgstr ""
|
||||
|
@ -3374,22 +3369,22 @@ msgstr ""
|
|||
msgid "execution of script failed"
|
||||
msgstr ""
|
||||
|
||||
#: lib/url.c:181
|
||||
#: lib/url.c:207
|
||||
#, c-format
|
||||
msgid "Password for %s@%s: "
|
||||
msgstr ""
|
||||
|
||||
#: lib/url.c:206 lib/url.c:232
|
||||
#: lib/url.c:232 lib/url.c:258
|
||||
#, c-format
|
||||
msgid "error: %sport must be a number\n"
|
||||
msgstr ""
|
||||
|
||||
#: lib/url.c:341
|
||||
#: lib/url.c:367
|
||||
msgid "url port must be a number\n"
|
||||
msgstr ""
|
||||
|
||||
#. XXX Fstrerror
|
||||
#: lib/url.c:396
|
||||
#: lib/url.c:425
|
||||
#, c-format
|
||||
msgid "failed to create %s\n"
|
||||
msgstr ""
|
||||
|
|
Loading…
Reference in New Issue