fix: typo in error message (#6858).
authorjbj <devnull@localhost>
Tue, 9 Nov 1999 20:57:38 +0000 (20:57 +0000)
committerjbj <devnull@localhost>
Tue, 9 Nov 1999 20:57:38 +0000 (20:57 +0000)
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

CHANGES
lib/Makefile.am
lib/ftp.c
lib/header.c
lib/query.c
lib/rpminstall.c
lib/rpmio.h
lib/rpmurl.h
lib/tufdio.c [new file with mode: 0644]
lib/url.c
po/rpm.pot

diff --git a/CHANGES b/CHANGES
index 87ec9d1..954d27d 100644 (file)
--- a/CHANGES
+++ b/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.
index de979e4..5b3049d 100644 (file)
@@ -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)
 
index ff3b67c..a2455a6 100644 (file)
--- a/lib/ftp.c
+++ b/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 {
+       int rc;
+
        /*
-        * 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.
+        * Read next line from server.
         */
-       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');
+       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;
 
        /*
-        * Divide the response into lines. Skip continuation lines.
+        * Process next line from server.
         */
-       for (s = se = buf; *s != '\0'; s = se) {
+       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));
 
+    if (fdio->write(u->ctrl, req, len) != len) {
+       rc = FTPERR_SERVER_IO_ERROR;
+       goto errxit;
+    }
+
   { int ec = 0;
-    int secs = fdGetRdTimeoutSecs(u->ftpControl);
-    int rc;
-    rc = checkResponse(u, sock, secs, &ec, NULL);
+    rc = checkResponse(u, &ec, NULL);
 
-    switch (ec) {
-    default:
-       if (rc == 0 && ec != 200)       /* not HTTP_OK */
-           rc = FTPERR_FILE_NOT_FOUND;
-       break;
-    }
+if (_ftp_debug && !(rc == 0 && ec == 200))
+fprintf(stderr, "*** httpOpen: rc %d ec %d\n", rc, ec);
 
-    if (rc < 0) {
-       close(sock);
-       return rc;
+    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);
+
+    if (fdio->fileno(u->ctrl) < 0) {
+       rc = tcpConnect(host, port);
+       fdSetFdno(u->ctrl, (rc >= 0 ? rc : -1));
+       if (rc < 0)
+           goto errxit;
+    }
 
-    /* ftpCheckResponse() assumes the socket is nonblocking */
-    if (fcntl(fdio->fileno(u->ftpControl), F_SETFL, O_NONBLOCK)) {
+#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;
 }
index ca7f52b..2789374 100644 (file)
@@ -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;
index f9a6b36..79d42cc 100644 (file)
@@ -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;
 }
index 11a18e8..567847e 100644 (file)
@@ -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);
index abd4d24..5f1b3c3 100644 (file)
@@ -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
 
index 03d6cb9..ff09868 100644 (file)
@@ -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);
diff --git a/lib/tufdio.c b/lib/tufdio.c
new file mode 100644 (file)
index 0000000..ab2363a
--- /dev/null
@@ -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;
+}
index 049602f..1e75ed5 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
 
 /*@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)) {
index 9ce147c..495736c 100644 (file)
@@ -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 ""