- fix: segfault with legacy packages missing RPMTAG_FILEINODES.
- require db3 in default configuration.
- create rpmio directory for librpmio.
+ - make librpmio standalone.
3.0.3 -> 3.0.4
- use compressed filenames on install side.
rpmlead.c rpmrc.c signature.c stringbuf.c stubs.c \
tagName.c tagtable.c transaction.c uninstall.c verify.c
librpm_la_LDFLAGS = -L$(top_builddir)/rpmio/.libs -lrpmio
-# -L$(top_builddir)/popt -lpopt
librpm_la_LIBADD = $(subst .c,.lo,$(DBLIBOBJS))
# XXX Drill out -L ldflags remnants until libtool-1.4 appears
/* and it shouldn't need these :-( */
#include "rpmio.h"
+#include "rpmmessages.h"
+#include "rpmerr.h"
#include "header.h"
#include "popt.h"
void rpmGetMachine( /*@out@*/ const char **arch, /*@out@*/ const char **os);
void rpmFreeRpmrc(void);
+/* ==================================================================== */
/** **/
-
typedef /*@abstract@*/ struct rpmdb_s * rpmdb;
-typedef enum rpmCallbackType_e {
- RPMCALLBACK_INST_PROGRESS, RPMCALLBACK_INST_START,
- RPMCALLBACK_INST_OPEN_FILE, RPMCALLBACK_INST_CLOSE_FILE,
- RPMCALLBACK_TRANS_PROGRESS, RPMCALLBACK_TRANS_START, RPMCALLBACK_TRANS_STOP,
- RPMCALLBACK_UNINST_PROGRESS, RPMCALLBACK_UNINST_START, RPMCALLBACK_UNINST_STOP
-} rpmCallbackType;
-
-typedef void * (*rpmCallbackFunction)(const Header h,
- const rpmCallbackType what,
- const unsigned long amount,
- const unsigned long total,
- const void * pkgKey, void * data);
-
-void urlSetCallback(rpmCallbackFunction notify, void *notifyData, int notifyCount);
-
-/* ==================================================================== */
/**
* @param dbp address of rpm database
*/
#define RPMPROB_FILTER_OLDPACKAGE (1 << 6)
#define RPMPROB_FILTER_DISKSPACE (1 << 7)
-/** messages.c **/
-
-#define RPMMESS_DEBUG 1
-#define RPMMESS_VERBOSE 2
-#define RPMMESS_NORMAL 3
-#define RPMMESS_WARNING 4
-#define RPMMESS_ERROR 5
-#define RPMMESS_FATALERROR 6
-
-#define RPMMESS_QUIET (RPMMESS_NORMAL + 1)
-
-void rpmIncreaseVerbosity(void);
-void rpmSetVerbosity(int level);
-int rpmGetVerbosity(void);
-int rpmIsVerbose(void);
-int rpmIsDebug(void);
-void rpmMessage(int level, const char * format, ...);
-
/** rpmlead.c **/
#define RPMLEAD_BINARY 0
unsigned int archiveOffset;
} ;
-/** rpmerr.c **/
-
-typedef void (*rpmErrorCallBackType)(void);
-
-#if defined(__GNUC__)
-void rpmError(int code, char * format, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
-#else
-void rpmError(int code, char * format, ...);
-#endif
-
-int rpmErrorCode(void);
-char *rpmErrorCodeString(void);
-char *rpmErrorString(void);
-rpmErrorCallBackType rpmErrorSetCallback(rpmErrorCallBackType);
-
-#define RPMERR_GDBMOPEN -2 /* gdbm open failed */
-#define RPMERR_GDBMREAD -3 /* gdbm read failed */
-#define RPMERR_GDBMWRITE -4 /* gdbm write failed */
-#define RPMERR_INTERNAL -5 /* internal RPM error */
-#define RPMERR_DBCORRUPT -6 /* rpm database is corrupt */
-#define RPMERR_OLDDBCORRUPT -7 /* old style rpm database is corrupt */
-#define RPMERR_OLDDBMISSING -8 /* old style rpm database is missing */
-#define RPMERR_NOCREATEDB -9 /* cannot create new database */
-#define RPMERR_DBOPEN -10 /* database open failed */
-#define RPMERR_DBGETINDEX -11 /* database get from index failed */
-#define RPMERR_DBPUTINDEX -12 /* database get from index failed */
-#define RPMERR_NEWPACKAGE -13 /* package is too new to handle */
-#define RPMERR_BADMAGIC -14 /* bad magic for an RPM */
-#define RPMERR_RENAME -15 /* rename(2) failed */
-#define RPMERR_UNLINK -16 /* unlink(2) failed */
-#define RPMERR_RMDIR -17 /* rmdir(2) failed */
-#define RPMERR_PKGINSTALLED -18 /* package already installed */
-#define RPMERR_CHOWN -19 /* chown() call failed */
-#define RPMERR_NOUSER -20 /* user does not exist */
-#define RPMERR_NOGROUP -21 /* group does not exist */
-#define RPMERR_MKDIR -22 /* mkdir() call failed */
-#define RPMERR_FILECONFLICT -23 /* file being installed exists */
-#define RPMERR_RPMRC -24 /* bad line in rpmrc */
-#define RPMERR_NOSPEC -25 /* .spec file is missing */
-#define RPMERR_NOTSRPM -26 /* a source rpm was expected */
-#define RPMERR_FLOCK -27 /* locking the database failed */
-#define RPMERR_OLDPACKAGE -28 /* trying upgrading to old version */
-/*#define RPMERR_BADARCH -29 bad architecture or arch mismatch */
-#define RPMERR_CREATE -30 /* failed to create a file */
-#define RPMERR_NOSPACE -31 /* out of disk space */
-#define RPMERR_NORELOCATE -32 /* tried to do improper relocatation */
-/*#define RPMERR_BADOS -33 bad architecture or arch mismatch */
-#define RPMMESS_BACKUP -34 /* backup made during [un]install */
-#define RPMERR_MTAB -35 /* failed to read mount table */
-#define RPMERR_STAT -36 /* failed to stat something */
-#define RPMERR_BADDEV -37 /* file on device not listed in mtab */
-#define RPMMESS_ALTNAME -38 /* file written as .rpmnew */
-#define RPMMESS_PREREQLOOP -39 /* loop in prerequisites */
-#define RPMERR_BADRELOCATE -40 /* bad relocation was specified */
-#define RPMERR_OLDDB -41 /* old format database */
-
-/* spec.c build.c pack.c */
-#define RPMERR_UNMATCHEDIF -107 /* unclosed %ifarch or %ifos */
-#define RPMERR_BADARG -109
-#define RPMERR_SCRIPT -110 /* errors related to script exec */
-#define RPMERR_READERROR -111
-#define RPMERR_UNKNOWNOS -112
-#define RPMERR_UNKNOWNARCH -113
-#define RPMERR_EXEC -114
-#define RPMERR_FORK -115
-#define RPMERR_CPIO -116
-#define RPMERR_GZIP -117
-#define RPMERR_BADSPEC -118
-#define RPMERR_LDD -119 /* couldn't understand ldd output */
-#define RPMERR_BADFILENAME -120
-
-#define RPMERR_BADSIGTYPE -200 /* Unknown signature type */
-#define RPMERR_SIGGEN -201 /* Error generating signature */
-
/** signature.c **/
/**************************************************/
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-06-09 15:18-0400\n"
+"POT-Creation-Date: 2000-06-09 17:03-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "opening db file %s mode 0x%x\n"
msgstr ""
-#: lib/db1.c:430 rpmio/url.c:444
+#: lib/db1.c:430 rpmio/url.c:445
#, c-format
msgid "failed to open %s: %s\n"
msgstr ""
msgid "Unsatisfied dependencies for %s-%s-%s: "
msgstr ""
-#: rpmio/rpmio.c:537
+#: rpmio/rpmio.c:532
msgid "Success"
msgstr ""
-#: rpmio/rpmio.c:540
+#: rpmio/rpmio.c:535
msgid "Bad server response"
msgstr ""
-#: rpmio/rpmio.c:543
+#: rpmio/rpmio.c:538
msgid "Server IO error"
msgstr ""
-#: rpmio/rpmio.c:546
+#: rpmio/rpmio.c:541
msgid "Server timeout"
msgstr ""
-#: rpmio/rpmio.c:549
+#: rpmio/rpmio.c:544
msgid "Unable to lookup server host address"
msgstr ""
-#: rpmio/rpmio.c:552
+#: rpmio/rpmio.c:547
msgid "Unable to lookup server host name"
msgstr ""
-#: rpmio/rpmio.c:555
+#: rpmio/rpmio.c:550
msgid "Failed to connect to server"
msgstr ""
-#: rpmio/rpmio.c:558
+#: rpmio/rpmio.c:553
msgid "Failed to establish data connection to server"
msgstr ""
-#: rpmio/rpmio.c:561
+#: rpmio/rpmio.c:556
msgid "IO error to local file"
msgstr ""
-#: rpmio/rpmio.c:564
+#: rpmio/rpmio.c:559
msgid "Error setting remote server to passive mode"
msgstr ""
-#: rpmio/rpmio.c:567
+#: rpmio/rpmio.c:562
msgid "File not found on server"
msgstr ""
-#: rpmio/rpmio.c:570
+#: rpmio/rpmio.c:565
msgid "Abort in progress"
msgstr ""
-#: rpmio/rpmio.c:574
+#: rpmio/rpmio.c:569
msgid "Unknown or unexpected error"
msgstr ""
-#: rpmio/rpmio.c:1107
+#: rpmio/rpmio.c:1164
#, c-format
msgid "logging into %s as %s, pw %s\n"
msgstr ""
-#: rpmio/macro.c:160
+#: rpmio/macro.c:161
#, c-format
msgid "======================== active %d empty %d\n"
msgstr ""
#. XXX just in case
-#: rpmio/macro.c:255
+#: rpmio/macro.c:256
#, c-format
msgid "%3d>%*s(empty)"
msgstr ""
-#: rpmio/macro.c:290
+#: rpmio/macro.c:291
#, c-format
msgid "%3d<%*s(empty)\n"
msgstr ""
-#: rpmio/macro.c:469
+#: rpmio/macro.c:470
msgid "Macro %%%s has unterminated body"
msgstr ""
-#: rpmio/macro.c:495
+#: rpmio/macro.c:496
msgid "Macro %%%s has illegal name (%%define)"
msgstr ""
-#: rpmio/macro.c:501
+#: rpmio/macro.c:502
msgid "Macro %%%s has unterminated opts"
msgstr ""
-#: rpmio/macro.c:506
+#: rpmio/macro.c:507
msgid "Macro %%%s has empty body"
msgstr ""
-#: rpmio/macro.c:511
+#: rpmio/macro.c:512
msgid "Macro %%%s failed to expand"
msgstr ""
-#: rpmio/macro.c:536
+#: rpmio/macro.c:537
msgid "Macro %%%s has illegal name (%%undefine)"
msgstr ""
-#: rpmio/macro.c:613
+#: rpmio/macro.c:614
msgid "Macro %%%s (%s) was not used below level %d"
msgstr ""
-#: rpmio/macro.c:710
+#: rpmio/macro.c:711
#, c-format
msgid "Unknown option %c in %s(%s)"
msgstr ""
-#: rpmio/macro.c:890
+#: rpmio/macro.c:891
#, c-format
msgid "Recursion depth(%d) greater than max(%d)"
msgstr ""
-#: rpmio/macro.c:956 rpmio/macro.c:972
+#: rpmio/macro.c:957 rpmio/macro.c:973
#, c-format
msgid "Unterminated %c: %s"
msgstr ""
-#: rpmio/macro.c:1012
+#: rpmio/macro.c:1013
msgid "A %% is followed by an unparseable macro"
msgstr ""
-#: rpmio/macro.c:1138
+#: rpmio/macro.c:1139
msgid "Macro %%%.*s not found, skipping"
msgstr ""
-#: rpmio/macro.c:1219
+#: rpmio/macro.c:1220
msgid "Target buffer overflow"
msgstr ""
#. XXX Fstrerror
-#: rpmio/macro.c:1399 rpmio/macro.c:1405
+#: rpmio/macro.c:1400 rpmio/macro.c:1406
#, c-format
msgid "File %s: %s"
msgstr ""
-#: rpmio/macro.c:1408
+#: rpmio/macro.c:1409
#, c-format
msgid "File %s is smaller than %d bytes"
msgstr ""
msgid "memory alloc (%u bytes) returned NULL.\n"
msgstr ""
-#: rpmio/url.c:87
+#: rpmio/url.c:88
#, c-format
msgid "warning: u %p ctrl %p nrefs != 0 (%s %s)\n"
msgstr ""
-#: rpmio/url.c:104
+#: rpmio/url.c:105
#, c-format
msgid "warning: u %p data %p nrefs != 0 (%s %s)\n"
msgstr ""
-#: rpmio/url.c:131
+#: rpmio/url.c:132
#, c-format
msgid "warning: uCache[%d] %p nrefs(%d) != 1 (%s %s)\n"
msgstr ""
-#: rpmio/url.c:217
+#: rpmio/url.c:218
#, c-format
msgid "Password for %s@%s: "
msgstr ""
-#: rpmio/url.c:242 rpmio/url.c:268
+#: rpmio/url.c:243 rpmio/url.c:269
#, c-format
msgid "error: %sport must be a number\n"
msgstr ""
-#: rpmio/url.c:404
+#: rpmio/url.c:405
msgid "url port must be a number\n"
msgstr ""
#. XXX Fstrerror
-#: rpmio/url.c:461
+#: rpmio/url.c:462
#, c-format
msgid "failed to create %s: %s\n"
msgstr ""
Name: rpm
%define version 4.0
Version: %{version}
-Release: 0.34
+Release: 0.35
Group: System Environment/Base
Source: ftp://ftp.rpm.org/pub/rpm/dist/rpm-3.0.x/rpm-%{version}.tar.gz
Copyright: GPL
-I$(top_srcdir)/popt @INCPATH@
pkgincdir = $(pkgincludedir)
-pkginc_HEADERS = rpmio.h rpmurl.h rpmmacro.h
+pkginc_HEADERS = rpmio.h rpmurl.h rpmmacro.h rpmmessages.h rpmerr.h
noinst_HEADERS = rpmio_internal.h ugid.h
lib_LTLIBRARIES = librpmio.la
-librpmio_la_SOURCES = rpmio.c url.c macro.c ugid.c rpmmalloc.c rpmerr.c messages.c
+librpmio_la_SOURCES = rpmrpc.c rpmio.c url.c macro.c \
+ ugid.c rpmmalloc.c rpmerr.c messages.c
librpmio_la_LDFLAGS = -L$(top_builddir)/popt/.libs -lpopt
librpmio_la_LIBADD = @LIBMISC@
#else
-#include <rpmlib.h>
#include <rpmio_internal.h>
+#include <rpmmessages.h>
+#include <rpmerr.h>
#endif
#include <stdarg.h>
-#include <rpmlib.h>
+#include <rpmmessages.h>
static int minLevel = RPMMESS_NORMAL;
#include <stdarg.h>
-#include <rpmlib.h>
+#include <rpmerr.h>
static struct err {
int code;
--- /dev/null
+#ifndef H_RPMERR
+#define H_RPMERR
+
+#define RPMERR_GDBMOPEN -2 /* gdbm open failed */
+#define RPMERR_GDBMREAD -3 /* gdbm read failed */
+#define RPMERR_GDBMWRITE -4 /* gdbm write failed */
+#define RPMERR_INTERNAL -5 /* internal RPM error */
+#define RPMERR_DBCORRUPT -6 /* rpm database is corrupt */
+#define RPMERR_OLDDBCORRUPT -7 /* old style rpm database is corrupt */
+#define RPMERR_OLDDBMISSING -8 /* old style rpm database is missing */
+#define RPMERR_NOCREATEDB -9 /* cannot create new database */
+#define RPMERR_DBOPEN -10 /* database open failed */
+#define RPMERR_DBGETINDEX -11 /* database get from index failed */
+#define RPMERR_DBPUTINDEX -12 /* database get from index failed */
+#define RPMERR_NEWPACKAGE -13 /* package is too new to handle */
+#define RPMERR_BADMAGIC -14 /* bad magic for an RPM */
+#define RPMERR_RENAME -15 /* rename(2) failed */
+#define RPMERR_UNLINK -16 /* unlink(2) failed */
+#define RPMERR_RMDIR -17 /* rmdir(2) failed */
+#define RPMERR_PKGINSTALLED -18 /* package already installed */
+#define RPMERR_CHOWN -19 /* chown() call failed */
+#define RPMERR_NOUSER -20 /* user does not exist */
+#define RPMERR_NOGROUP -21 /* group does not exist */
+#define RPMERR_MKDIR -22 /* mkdir() call failed */
+#define RPMERR_FILECONFLICT -23 /* file being installed exists */
+#define RPMERR_RPMRC -24 /* bad line in rpmrc */
+#define RPMERR_NOSPEC -25 /* .spec file is missing */
+#define RPMERR_NOTSRPM -26 /* a source rpm was expected */
+#define RPMERR_FLOCK -27 /* locking the database failed */
+#define RPMERR_OLDPACKAGE -28 /* trying upgrading to old version */
+/*#define RPMERR_BADARCH -29 bad architecture or arch mismatch */
+#define RPMERR_CREATE -30 /* failed to create a file */
+#define RPMERR_NOSPACE -31 /* out of disk space */
+#define RPMERR_NORELOCATE -32 /* tried to do improper relocatation */
+/*#define RPMERR_BADOS -33 bad architecture or arch mismatch */
+#define RPMMESS_BACKUP -34 /* backup made during [un]install */
+#define RPMERR_MTAB -35 /* failed to read mount table */
+#define RPMERR_STAT -36 /* failed to stat something */
+#define RPMERR_BADDEV -37 /* file on device not listed in mtab */
+#define RPMMESS_ALTNAME -38 /* file written as .rpmnew */
+#define RPMMESS_PREREQLOOP -39 /* loop in prerequisites */
+#define RPMERR_BADRELOCATE -40 /* bad relocation was specified */
+#define RPMERR_OLDDB -41 /* old format database */
+
+/* spec.c build.c pack.c */
+#define RPMERR_UNMATCHEDIF -107 /* unclosed %ifarch or %ifos */
+#define RPMERR_BADARG -109
+#define RPMERR_SCRIPT -110 /* errors related to script exec */
+#define RPMERR_READERROR -111
+#define RPMERR_UNKNOWNOS -112
+#define RPMERR_UNKNOWNARCH -113
+#define RPMERR_EXEC -114
+#define RPMERR_FORK -115
+#define RPMERR_CPIO -116
+#define RPMERR_GZIP -117
+#define RPMERR_BADSPEC -118
+#define RPMERR_LDD -119 /* couldn't understand ldd output */
+#define RPMERR_BADFILENAME -120
+
+#define RPMERR_BADSIGTYPE -200 /* Unknown signature type */
+#define RPMERR_SIGGEN -201 /* Error generating signature */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*rpmErrorCallBackType)(void);
+
+#if defined(__GNUC__)
+void rpmError(int code, char * format, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
+#else
+void rpmError(int code, char * format, ...);
+#endif
+
+int rpmErrorCode(void);
+char *rpmErrorCodeString(void);
+char *rpmErrorString(void);
+rpmErrorCallBackType rpmErrorSetCallback(rpmErrorCallBackType);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_RPMERR */
#include "dns.h"
#endif
-#include <rpmlib.h>
#include <rpmio_internal.h>
-#include "misc.h"
+#include "ugid.h"
+#include "rpmmessages.h"
#define FDNREFS(fd) (fd ? ((FD_t)fd)->nrefs : -9)
#define FDTO(fd) (fd ? ((FD_t)fd)->rd_timeoutsecs : -99)
int _ftp_debug = 0;
int _rpmio_debug = 0;
-#define DBG(_f, _m, _x) \
- if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
-
-#define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
-#define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
/* =============================================================== */
/*@notreached@*/
}
-static int fdFgets(FD_t fd, char * buf, size_t len)
+int fdFgets(FD_t fd, char * buf, size_t len)
{
int fdno;
int secs = fd->rd_timeoutsecs;
return rc;
}
-static int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
+int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
{
urlinfo u = data->url;
struct sockaddr_in dataAddress;
return rc;
}
-static int urlConnect(const char * url, /*@out@*/ urlinfo * uret)
-{
- urlinfo u;
- int rc = 0;
-
- if (urlSplit(url, &u) < 0)
- return -1;
-
- if (u->urltype == URL_IS_FTP) {
- FD_t fd;
-
- if ((fd = u->ctrl) == NULL) {
- fd = u->ctrl = fdNew("persist ctrl (urlConnect FTP)");
- fdSetIo(u->ctrl, ufdio);
- }
-
- fd->rd_timeoutsecs = ftpTimeoutSecs;
- fd->contentLength = fd->bytesRemain = -1;
- fd->url = NULL; /* XXX FTP ctrl has not */
- fd->ftpFileDoneNeeded = 0;
- fd = fdLink(fd, "grab ctrl (urlConnect FTP)");
-
- if (fdFileno(u->ctrl) < 0) {
- rpmMessage(RPMMESS_DEBUG, _("logging into %s as %s, pw %s\n"),
- u->host,
- u->user ? u->user : "ftp",
- u->password ? u->password : "(username)");
-
- if ((rc = ftpLogin(u)) < 0) { /* XXX save ftpLogin error */
- u->ctrl = fdFree(fd, "grab ctrl (urlConnect FTP)");
- u->openError = rc;
- }
- }
- }
-
- if (uret != NULL)
- *uret = urlLink(u, "urlConnect");
- u = urlFree(u, "urlSplit (urlConnect)");
-
- return rc;
-}
-
/*@null@*/ static rpmCallbackFunction urlNotify = NULL;
/*@null@*/ static void * urlNotifyData = NULL;
static int urlNotifyCount = -1;
return rc;
}
+static int urlConnect(const char * url, /*@out@*/ urlinfo * uret)
+{
+ urlinfo u;
+ int rc = 0;
+
+ if (urlSplit(url, &u) < 0)
+ return -1;
+
+ if (u->urltype == URL_IS_FTP) {
+ FD_t fd;
+
+ if ((fd = u->ctrl) == NULL) {
+ fd = u->ctrl = fdNew("persist ctrl (urlConnect FTP)");
+ fdSetIo(u->ctrl, ufdio);
+ }
+
+ fd->rd_timeoutsecs = ftpTimeoutSecs;
+ fd->contentLength = fd->bytesRemain = -1;
+ fd->url = NULL; /* XXX FTP ctrl has not */
+ fd->ftpFileDoneNeeded = 0;
+ fd = fdLink(fd, "grab ctrl (urlConnect FTP)");
+
+ if (fdFileno(u->ctrl) < 0) {
+ rpmMessage(RPMMESS_DEBUG, _("logging into %s as %s, pw %s\n"),
+ u->host,
+ u->user ? u->user : "ftp",
+ u->password ? u->password : "(username)");
+
+ if ((rc = ftpLogin(u)) < 0) { /* XXX save ftpLogin error */
+ u->ctrl = fdFree(fd, "grab ctrl (urlConnect FTP)");
+ u->openError = rc;
+ }
+ }
+ }
+
+ if (uret != NULL)
+ *uret = urlLink(u, "urlConnect");
+ u = urlFree(u, "urlSplit (urlConnect)");
+
+ return rc;
+}
+
int ufdGetFile(FD_t sfd, FD_t tfd)
{
int rc;
return rc;
}
-static int ftpCmd(const char * cmd, const char * url, const char * arg2) {
+int ftpCmd(const char * cmd, const char * url, const char * arg2) {
urlinfo u;
int rc;
const char * path;
return rc;
}
-static int ftpMkdir(const char * path, /*@unused@*/ mode_t mode) {
- int rc;
- if ((rc = ftpCmd("MKD", path, NULL)) != 0)
- return rc;
-#if NOTYET
- { char buf[20];
- sprintf(buf, " 0%o", mode);
- (void) ftpCmd("SITE CHMOD", path, buf);
- }
-#endif
- return rc;
-}
-
-static int ftpChdir(const char * path) {
- return ftpCmd("CWD", path, NULL);
-}
-
-static int ftpRmdir(const char * path) {
- return ftpCmd("RMD", path, NULL);
-}
-
-static int ftpRename(const char * oldpath, const char * newpath) {
- int rc;
- if ((rc = ftpCmd("RNFR", oldpath, NULL)) != 0)
- return rc;
- return ftpCmd("RNTO", newpath, NULL);
-}
-
-static int ftpUnlink(const char * path) {
- return ftpCmd("DELE", path, NULL);
-}
-
/* XXX these aren't worth the pain of including correctly */
#if !defined(IAC)
#define IAC 255 /* interpret as command: */
return fdSeek(cookie, pos, whence);
}
-static int ufdClose( /*@only@*/ void * cookie)
+int ufdClose( /*@only@*/ void * cookie)
{
FD_t fd = c2f(cookie);
return fdClose(fd);
}
-static /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
+/*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
/*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret)
{
urlinfo u = NULL;
return Fwrite(buf, sizeof(char), count, fd);
}
-/* XXX rebuilddb.c: analogues to mkdir(2)/rmdir(2). */
-int Mkdir (const char *path, mode_t mode) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
- switch (ut) {
- case URL_IS_FTP:
- return ftpMkdir(path, mode);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return mkdir(path, mode);
-}
-
-int Chdir (const char *path) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
- switch (ut) {
- case URL_IS_FTP:
- return ftpChdir(path);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return chdir(path);
-}
-
-int Rmdir (const char *path) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
- switch (ut) {
- case URL_IS_FTP:
- return ftpRmdir(path);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return rmdir(path);
-}
-
-/* XXX rpmdb.c: analogue to rename(2). */
-
-int Rename (const char *oldpath, const char * newpath) {
- const char *oe = NULL;
- const char *ne = NULL;
- int oldut, newut;
-
- /* XXX lib/install.c used to rely on this behavior. */
- if (!strcmp(oldpath, newpath)) return 0;
-
- oldut = urlPath(oldpath, &oe);
- switch (oldut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
-
- newut = urlPath(newpath, &ne);
- switch (newut) {
- case URL_IS_FTP:
-if (_rpmio_debug)
-fprintf(stderr, "*** rename old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
- if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
- !strncasecmp(oldpath, newpath, (oe - oldpath))))
- return -2;
- return ftpRename(oldpath, newpath);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- oldpath = oe;
- newpath = ne;
- break;
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return rename(oldpath, newpath);
-}
-
-int Link (const char *oldpath, const char * newpath) {
- const char *oe = NULL;
- const char *ne = NULL;
- int oldut, newut;
-
- oldut = urlPath(oldpath, &oe);
- switch (oldut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
-
- newut = urlPath(newpath, &ne);
- switch (newut) {
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
-if (_rpmio_debug)
-fprintf(stderr, "*** link old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
- if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
- !strncasecmp(oldpath, newpath, (oe - oldpath))))
- return -2;
- oldpath = oe;
- newpath = ne;
- break;
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return link(oldpath, newpath);
-}
-
-/* XXX build/build.c: analogue to unlink(2). */
-
-int Unlink(const char * path) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
- switch (ut) {
- case URL_IS_FTP:
- return ftpUnlink(path);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return unlink(path);
-}
-
-/* XXX swiped from mc-4.5.39-pre9 vfs/ftpfs.c */
-
-#define g_strdup xstrdup
-#define g_free xfree
-
-/*
- * FIXME: this is broken. It depends on mc not crossing border on month!
- */
-static int current_mday;
-static int current_mon;
-static int current_year;
-
-/* Following stuff (parse_ls_lga) is used by ftpfs and extfs */
-#define MAXCOLS 30
-
-static char *columns [MAXCOLS]; /* Points to the string in column n */
-static int column_ptr [MAXCOLS]; /* Index from 0 to the starting positions of the columns */
-
-static int
-vfs_split_text (char *p)
-{
- char *original = p;
- int numcols;
-
-
- for (numcols = 0; *p && numcols < MAXCOLS; numcols++){
- while (*p == ' ' || *p == '\r' || *p == '\n'){
- *p = 0;
- p++;
- }
- columns [numcols] = p;
- column_ptr [numcols] = p - original;
- while (*p && *p != ' ' && *p != '\r' && *p != '\n')
- p++;
- }
- return numcols;
-}
-
-static int
-is_num (int idx)
-{
- if (!columns [idx] || columns [idx][0] < '0' || columns [idx][0] > '9')
- return 0;
- return 1;
-}
-
-static int
-is_dos_date(char *str)
-{
- if (strlen(str) == 8 && str[2] == str[5] && strchr("\\-/", (int)str[2]) != NULL)
- return (1);
-
- return (0);
-}
-
-static int
-is_week (char *str, struct tm *tim)
-{
- static char *week = "SunMonTueWedThuFriSat";
- char *pos;
-
- if((pos=strstr(week, str)) != NULL){
- if(tim != NULL)
- tim->tm_wday = (pos - week)/3;
- return (1);
- }
- return (0);
-}
-
-static int
-is_month (char *str, struct tm *tim)
-{
- static char *month = "JanFebMarAprMayJunJulAugSepOctNovDec";
- char *pos;
-
- if((pos=strstr(month, str)) != NULL){
- if(tim != NULL)
- tim->tm_mon = (pos - month)/3;
- return (1);
- }
- return (0);
-}
-
-static int
-is_time (char *str, struct tm *tim)
-{
- char *p, *p2;
-
- if ((p=strchr(str, ':')) && (p2=strrchr(str, ':'))) {
- if (p != p2) {
- if (sscanf (str, "%2d:%2d:%2d", &tim->tm_hour, &tim->tm_min, &tim->tm_sec) != 3)
- return (0);
- }
- else {
- if (sscanf (str, "%2d:%2d", &tim->tm_hour, &tim->tm_min) != 2)
- return (0);
- }
- }
- else
- return (0);
-
- return (1);
-}
-
-static int is_year(char *str, struct tm *tim)
-{
- long year;
-
- if (strchr(str,':'))
- return (0);
-
- if (strlen(str)!=4)
- return (0);
-
- if (sscanf(str, "%ld", &year) != 1)
- return (0);
-
- if (year < 1900 || year > 3000)
- return (0);
-
- tim->tm_year = (int) (year - 1900);
-
- return (1);
-}
-
-/*
- * FIXME: this is broken. Consider following entry:
- * -rwx------ 1 root root 1 Aug 31 10:04 2904 1234
- * where "2904 1234" is filename. Well, this code decodes it as year :-(.
- */
-
-static int
-vfs_parse_filetype (char c)
-{
- switch (c){
- case 'd': return S_IFDIR;
- case 'b': return S_IFBLK;
- case 'c': return S_IFCHR;
- case 'l': return S_IFLNK;
- case 's':
-#ifdef IS_IFSOCK /* And if not, we fall through to IFIFO, which is pretty close */
- return S_IFSOCK;
-#endif
- case 'p': return S_IFIFO;
- case 'm': case 'n': /* Don't know what these are :-) */
- case '-': case '?': return S_IFREG;
- default: return -1;
- }
-}
-
-static int vfs_parse_filemode (char *p)
-{ /* converts rw-rw-rw- into 0666 */
- int res = 0;
- switch (*(p++)){
- case 'r': res |= 0400; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'w': res |= 0200; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'x': res |= 0100; break;
- case 's': res |= 0100 | S_ISUID; break;
- case 'S': res |= S_ISUID; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'r': res |= 0040; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'w': res |= 0020; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'x': res |= 0010; break;
- case 's': res |= 0010 | S_ISGID; break;
- case 'l': /* Solaris produces these */
- case 'S': res |= S_ISGID; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'r': res |= 0004; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'w': res |= 0002; break;
- case '-': break;
- default: return -1;
- }
- switch (*(p++)){
- case 'x': res |= 0001; break;
- case 't': res |= 0001 | S_ISVTX; break;
- case 'T': res |= S_ISVTX; break;
- case '-': break;
- default: return -1;
- }
- return res;
-}
-
-static int vfs_parse_filedate(int idx, time_t *t)
-{ /* This thing parses from idx in columns[] array */
-
- char *p;
- struct tm tim;
- int d[3];
- int got_year = 0;
-
- /* Let's setup default time values */
- tim.tm_year = current_year;
- tim.tm_mon = current_mon;
- tim.tm_mday = current_mday;
- tim.tm_hour = 0;
- tim.tm_min = 0;
- tim.tm_sec = 0;
- tim.tm_isdst = -1; /* Let mktime() try to guess correct dst offset */
-
- p = columns [idx++];
-
- /* We eat weekday name in case of extfs */
- if(is_week(p, &tim))
- p = columns [idx++];
-
- /* Month name */
- if(is_month(p, &tim)){
- /* And we expect, it followed by day number */
- if (is_num (idx))
- tim.tm_mday = (int)atol (columns [idx++]);
- else
- return 0; /* No day */
-
- } else {
- /* We usually expect:
- Mon DD hh:mm
- Mon DD YYYY
- But in case of extfs we allow these date formats:
- Mon DD YYYY hh:mm
- Mon DD hh:mm YYYY
- Wek Mon DD hh:mm:ss YYYY
- MM-DD-YY hh:mm
- where Mon is Jan-Dec, DD, MM, YY two digit day, month, year,
- YYYY four digit year, hh, mm, ss two digit hour, minute or second. */
-
- /* Here just this special case with MM-DD-YY */
- if (is_dos_date(p)){
- p[2] = p[5] = '-';
-
- if(sscanf(p, "%2d-%2d-%2d", &d[0], &d[1], &d[2]) == 3){
- /* We expect to get:
- 1. MM-DD-YY
- 2. DD-MM-YY
- 3. YY-MM-DD
- 4. YY-DD-MM */
-
- /* Hmm... maybe, next time :)*/
-
- /* At last, MM-DD-YY */
- d[0]--; /* Months are zerobased */
- /* Y2K madness */
- if(d[2] < 70)
- d[2] += 100;
-
- tim.tm_mon = d[0];
- tim.tm_mday = d[1];
- tim.tm_year = d[2];
- got_year = 1;
- } else
- return 0; /* sscanf failed */
- } else
- return 0; /* unsupported format */
- }
-
- /* Here we expect to find time and/or year */
-
- if (is_num (idx)) {
- if(is_time(columns[idx], &tim) || (got_year = is_year(columns[idx], &tim))) {
- idx++;
-
- /* This is a special case for ctime() or Mon DD YYYY hh:mm */
- if(is_num (idx) &&
- ((got_year = is_year(columns[idx], &tim)) || is_time(columns[idx], &tim)))
- idx++; /* time & year or reverse */
- } /* only time or date */
- }
- else
- return 0; /* Nor time or date */
-
- /*
- * If the date is less than 6 months in the past, it is shown without year
- * other dates in the past or future are shown with year but without time
- * This does not check for years before 1900 ... I don't know, how
- * to represent them at all
- */
- if (!got_year &&
- current_mon < 6 && current_mon < tim.tm_mon &&
- tim.tm_mon - current_mon >= 6)
-
- tim.tm_year--;
-
- if ((*t = mktime(&tim)) < 0)
- *t = 0;
- return idx;
-}
-
-static int
-vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
-{
- int idx, idx2, num_cols;
- int i;
- char *p_copy;
-
- if (strncmp (p, "total", 5) == 0)
- return 0;
-
- p_copy = g_strdup(p);
-/* XXX FIXME: parse out inode number from "NLST -lai ." */
-/* XXX FIXME: parse out sizein blocks from "NLST -lais ." */
-
- if ((i = vfs_parse_filetype(*(p++))) == -1)
- goto error;
-
- s->st_mode = i;
- if (*p == ' ') /* Notwell 4 */
- p++;
- if (*p == '['){
- if (strlen (p) <= 8 || p [8] != ']')
- goto error;
- /* Should parse here the Notwell permissions :) */
- if (S_ISDIR (s->st_mode))
- s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH);
- else
- s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
- p += 9;
- } else {
- if ((i = vfs_parse_filemode(p)) == -1)
- goto error;
- s->st_mode |= i;
- p += 9;
-
- /* This is for an extra ACL attribute (HP-UX) */
- if (*p == '+')
- p++;
- }
-
- g_free(p_copy);
- p_copy = g_strdup(p);
- num_cols = vfs_split_text (p);
-
- s->st_nlink = atol (columns [0]);
- if (s->st_nlink < 0)
- goto error;
-
- if (!is_num (1))
-#ifdef HACK
- s->st_uid = finduid (columns [1]);
-#else
- unameToUid (columns [1], &s->st_uid);
-#endif
- else
- s->st_uid = (uid_t) atol (columns [1]);
-
- /* Mhm, the ls -lg did not produce a group field */
- for (idx = 3; idx <= 5; idx++)
- if (is_month(columns [idx], NULL) || is_week(columns [idx], NULL) || is_dos_date(columns[idx]))
- break;
-
- if (idx == 6 || (idx == 5 && !S_ISCHR (s->st_mode) && !S_ISBLK (s->st_mode)))
- goto error;
-
- /* We don't have gid */
- if (idx == 3 || (idx == 4 && (S_ISCHR(s->st_mode) || S_ISBLK (s->st_mode))))
- idx2 = 2;
- else {
- /* We have gid field */
- if (is_num (2))
- s->st_gid = (gid_t) atol (columns [2]);
- else
-#ifdef HACK
- s->st_gid = findgid (columns [2]);
-#else
- gnameToGid (columns [1], &s->st_gid);
-#endif
- idx2 = 3;
- }
-
- /* This is device */
- if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)){
- int maj, min;
-
- if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
- goto error;
-
- if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
- goto error;
-
-#ifdef HAVE_ST_RDEV
- s->st_rdev = ((maj & 0xff) << 8) | (min & 0xffff00ff);
-#endif
- s->st_size = 0;
-
- } else {
- /* Common file size */
- if (!is_num (idx2))
- goto error;
-
- s->st_size = (size_t) atol (columns [idx2]);
-#ifdef HAVE_ST_RDEV
- s->st_rdev = 0;
-#endif
- }
-
- idx = vfs_parse_filedate(idx, &s->st_mtime);
- if (!idx)
- goto error;
- /* Use resulting time value */
- s->st_atime = s->st_ctime = s->st_mtime;
- s->st_dev = 0;
- s->st_ino = 0;
-#ifdef HAVE_ST_BLKSIZE
- s->st_blksize = 512;
-#endif
-#ifdef HAVE_ST_BLOCKS
- s->st_blocks = (s->st_size + 511) / 512;
-#endif
-
- for (i = idx + 1, idx2 = 0; i < num_cols; i++ )
- if (strcmp (columns [i], "->") == 0){
- idx2 = i;
- break;
- }
-
- if (((S_ISLNK (s->st_mode) ||
- (num_cols == idx + 3 && s->st_nlink > 1))) /* Maybe a hardlink? (in extfs) */
- && idx2){
- int p;
- char *s;
-
- if (filename){
-#ifdef HACK
- s = g_strndup (p_copy + column_ptr [idx], column_ptr [idx2] - column_ptr [idx] - 1);
-#else
- int nb = column_ptr [idx2] - column_ptr [idx] - 1;
- s = xmalloc(nb+1);
- strncpy(s, p_copy + column_ptr [idx], nb);
-#endif
- *filename = s;
- }
- if (linkname){
- s = g_strdup (p_copy + column_ptr [idx2+1]);
- p = strlen (s);
- if (s [p-1] == '\r' || s [p-1] == '\n')
- s [p-1] = 0;
- if (s [p-2] == '\r' || s [p-2] == '\n')
- s [p-2] = 0;
-
- *linkname = s;
- }
- } else {
- /* Extract the filename from the string copy, not from the columns
- * this way we have a chance of entering hidden directories like ". ."
- */
- if (filename){
- /*
- *filename = g_strdup (columns [idx++]);
- */
- int p;
- char *s;
-
- s = g_strdup (p_copy + column_ptr [idx++]);
- p = strlen (s);
- /* g_strchomp(); */
- if (s [p-1] == '\r' || s [p-1] == '\n')
- s [p-1] = 0;
- if (s [p-2] == '\r' || s [p-2] == '\n')
- s [p-2] = 0;
-
- *filename = s;
- }
- if (linkname)
- *linkname = NULL;
- }
- g_free (p_copy);
- return 1;
-
-error:
-#ifdef HACK
- {
- static int errorcount = 0;
-
- if (++errorcount < 5) {
- message_1s (1, "Could not parse:", p_copy);
- } else if (errorcount == 5)
- message_1s (1, "More parsing errors will be ignored.", "(sorry)" );
- }
-#endif
-
- if (p_copy != p) /* Carefull! */
- g_free (p_copy);
- return 0;
-}
-
-typedef enum {
- DO_FTP_STAT = 1,
- DO_FTP_LSTAT = 2,
- DO_FTP_READLINK = 3,
- DO_FTP_ACCESS = 4,
- DO_FTP_GLOB = 5
-} ftpSysCall_t;
-static size_t ftpBufAlloced = 0;
-static char * ftpBuf = NULL;
-
-#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
-
-static int ftpNLST(const char * url, ftpSysCall_t ftpSysCall,
- struct stat * st, char * rlbuf, size_t rlbufsiz)
-{
- FD_t fd;
- const char * path;
- int bufLength, moretodo;
- const char *n, *ne, *o, *oe;
- char * s;
- char * se;
- const char * urldn;
- char * bn = NULL;
- int nbn = 0;
- urlinfo u;
- int rc;
-
- n = ne = o = oe = NULL;
- (void) urlPath(url, &path);
- if (*path == '\0')
- return -2;
-
- switch (ftpSysCall) {
- case DO_FTP_GLOB:
- fd = ftpOpen(url, 0, 0, &u);
- if (fd == NULL || u == NULL)
- return -1;
-
- u->openError = ftpReq(fd, "NLST", path);
- break;
- default:
- urldn = alloca_strdup(url);
- if ((bn = strrchr(urldn, '/')) == NULL)
- return -2;
- else if (bn == path)
- bn = ".";
- else
- *bn++ = '\0';
- nbn = strlen(bn);
-
- rc = ftpChdir(urldn); /* XXX don't care about CWD */
- if (rc < 0)
- return rc;
-
- fd = ftpOpen(url, 0, 0, &u);
- if (fd == NULL || u == NULL)
- return -1;
-
- /* XXX possibly should do "NLST -lais" to get st_ino/st_blocks also */
- u->openError = ftpReq(fd, "NLST", "-la");
- break;
- }
-
- if (u->openError < 0) {
- fd = fdLink(fd, "error data (ftpStat)");
- rc = -2;
- goto exit;
- }
-
- if (ftpBufAlloced == 0 || ftpBuf == NULL) {
- ftpBufAlloced = url_iobuf_size;
- ftpBuf = xcalloc(ftpBufAlloced, sizeof(ftpBuf[0]));
- }
- *ftpBuf = '\0';
-
- bufLength = 0;
- moretodo = 1;
-
- do {
-
- /* XXX FIXME: realloc ftpBuf is < ~128 chars remain */
- if ((ftpBufAlloced - bufLength) < (1024+80)) {
- ftpBufAlloced <<= 2;
- ftpBuf = xrealloc(ftpBuf, ftpBufAlloced);
- }
- s = se = ftpBuf + bufLength;
- *se = '\0';
-
- rc = fdFgets(fd, se, (ftpBufAlloced - bufLength));
- if (rc <= 0) {
- moretodo = 0;
- break;
- }
- if (ftpSysCall == DO_FTP_GLOB) { /* XXX HACK */
- bufLength += strlen(se);
- continue;
- }
-
- for (s = se; *s != '\0'; s = se) {
- int bingo;
-
- while (*se && *se != '\n') se++;
- if (se > s && se[-1] == '\r') se[-1] = '\0';
- if (*se == '\0') break;
- *se++ = '\0';
-
- if (!strncmp(s, "total ", sizeof("total ")-1)) continue;
-
- o = NULL;
- for (bingo = 0, n = se; n >= s; n--) {
- switch (*n) {
- case '\0':
- oe = ne = n;
- break;
- case ' ':
- if (o || !(n[-3] == ' ' && n[-2] == '-' && n[-1] == '>')) {
- while (*(++n) == ' ');
- bingo++;
- break;
- }
- for (o = n + 1; *o == ' '; o++);
- n -= 3;
- ne = n;
- break;
- default:
- break;
- }
- if (bingo) break;
- }
-
- if (nbn != (ne - n)) continue; /* Same name length? */
- if (strncmp(n, bn, nbn)) continue; /* Same name? */
-
- moretodo = 0;
- break;
- }
-
- if (moretodo && se > s) {
- bufLength = se - s - 1;
- if (s != ftpBuf)
- memmove(ftpBuf, s, bufLength);
- } else {
- bufLength = 0;
- }
- } while (moretodo);
-
- switch (ftpSysCall) {
- case DO_FTP_STAT:
- if (o && oe) {
- /* XXX FIXME: symlink, replace urldn/bn from [o,oe) and restart */
- }
- /*@fallthrough@*/
- case DO_FTP_LSTAT:
- if (st == NULL || !(n && ne)) {
- rc = -1;
- } else {
- rc = ((vfs_parse_ls_lga(s, st, NULL, NULL) > 0) ? 0 : -1);
- }
- break;
- case DO_FTP_READLINK:
- if (rlbuf == NULL || !(o && oe)) {
- rc = -1;
- } else {
- rc = oe - o;
- if (rc > rlbufsiz)
- rc = rlbufsiz;
- memcpy(rlbuf, o, rc);
- if (rc < rlbufsiz)
- rlbuf[rc] = '\0';
- }
- break;
- case DO_FTP_ACCESS:
- rc = 0; /* XXX WRONG WRONG WRONG */
- break;
- case DO_FTP_GLOB:
- rc = 0; /* XXX WRONG WRONG WRONG */
- break;
- }
-
-exit:
- ufdClose(fd);
- return rc;
-}
-
-static int ftpStat(const char * path, struct stat *st)
-{
- return ftpNLST(path, DO_FTP_STAT, st, NULL, 0);
-}
-
-static int ftpLstat(const char * path, struct stat *st) {
- int rc;
- rc = ftpNLST(path, DO_FTP_LSTAT, st, NULL, 0);
-if (_rpmio_debug)
-fprintf(stderr, "*** ftpLstat(%s) rc %d\n", path, rc);
- return rc;
-}
-
-static int ftpReadlink(const char * path, char * buf, size_t bufsiz) {
- return ftpNLST(path, DO_FTP_READLINK, NULL, buf, bufsiz);
-}
-
-static int ftpGlob(const char * path, int flags,
- int errfunc(const char * epath, int eerno), glob_t * pglob)
-{
- int rc;
-
- if (pglob == NULL)
- return -2;
- rc = ftpNLST(path, DO_FTP_GLOB, NULL, NULL, 0);
-if (_rpmio_debug)
-fprintf(stderr, "*** ftpGlob(%s,0x%x,%p,%p) ftpNLST rc %d\n", path, flags, errfunc, pglob, rc);
- if (rc)
- return rc;
- rc = poptParseArgvString(ftpBuf, &pglob->gl_pathc, (const char ***)&pglob->gl_pathv);
- pglob->gl_offs = -1; /* XXX HACK HACK HACK */
- return rc;
-}
-
-static void ftpGlobfree(glob_t * pglob) {
-if (_rpmio_debug)
-fprintf(stderr, "*** ftpGlobfree(%p)\n", pglob);
- if (pglob->gl_offs == -1) /* XXX HACK HACK HACK */
- xfree(pglob->gl_pathv);
-}
-
-int Stat(const char * path, struct stat * st) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
-if (_rpmio_debug)
-fprintf(stderr, "*** Stat(%s,%p)\n", path, st);
- switch (ut) {
- case URL_IS_FTP:
- return ftpStat(path, st);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return stat(path, st);
-}
-
-int Lstat(const char * path, struct stat * st) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
-if (_rpmio_debug)
-fprintf(stderr, "*** Lstat(%s,%p)\n", path, st);
- switch (ut) {
- case URL_IS_FTP:
- return ftpLstat(path, st);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return lstat(path, st);
-}
-
-int Readlink(const char * path, char * buf, size_t bufsiz) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
- switch (ut) {
- case URL_IS_FTP:
- return ftpReadlink(path, buf, bufsiz);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return readlink(path, buf, bufsiz);
-}
-
-int Access(const char * path, int amode) {
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
-if (_rpmio_debug)
-fprintf(stderr, "*** Access(%s,%d)\n", path, amode);
- switch (ut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return access(path, amode);
-}
-
-int Glob(const char *path, int flags,
- int errfunc(const char * epath, int eerrno), glob_t *pglob)
-{
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
-if (_rpmio_debug)
-fprintf(stderr, "*** Glob(%s,0x%x,%p,%p)\n", path, flags, errfunc, pglob);
- switch (ut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- return ftpGlob(path, flags, errfunc, pglob);
- /*@notreached@*/ break;
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return -2;
- /*@notreached@*/ break;
- }
- return glob(path, flags, errfunc, pglob);
-}
-
-void Globfree(glob_t *pglob)
-{
-if (_rpmio_debug)
-fprintf(stderr, "*** Globfree(%p)\n", pglob);
- if (pglob->gl_offs == -1) /* XXX HACK HACK HACK */
- ftpGlobfree(pglob);
- else
- globfree(pglob);
-}
-
-DIR * Opendir(const char * path)
-{
- const char * lpath;
- int ut = urlPath(path, &lpath);
-
-if (_rpmio_debug)
-fprintf(stderr, "*** Opendir(%s)\n", path);
- switch (ut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
- case URL_IS_PATH:
- path = lpath;
- /*@fallthrough@*/
- case URL_IS_UNKNOWN:
- break;
- case URL_IS_DASH:
- default:
- return NULL;
- /*@notreached@*/ break;
- }
- return opendir(path);
-}
-
-struct dirent * Readdir(DIR * dir)
-{
-if (_rpmio_debug)
-fprintf(stderr, "*** Readdir(%p)\n", dir);
- return readdir(dir);
-}
-
-int Closedir(DIR * dir)
-{
-if (_rpmio_debug)
-fprintf(stderr, "*** Closedir(%p)\n", dir);
- return closedir(dir);
-}
-
static struct FDIO_s fpio_s = {
ufdRead, ufdWrite, fdSeek, ufdClose, XfdLink, XfdFree, XfdNew, fdFileno,
ufdOpen, NULL, fdGetFp, NULL, Mkdir, Chdir, Rmdir, Rename, Unlink
#include <rpmio.h>
#include <rpmurl.h>
+#include <assert.h>
typedef struct _FDSTACK_s {
FDIO_t io;
};
/*@access FD_t */
-#include <assert.h>
#define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
+extern int _rpmio_debug;
+
+#define DBG(_f, _m, _x) \
+ if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x
+
+#define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
+#define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
+
+#define xfree(_p) free((void *)_p)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int fdFgets(FD_t fd, char * buf, size_t len);
+
+/*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags,
+ /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret);
+int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg);
+int ftpCmd(const char * cmd, const char * url, const char * arg2);
+
+int ufdClose( /*@only@*/ void * cookie);
+
static inline /*@null@*/ const FDIO_t fdGetIo(FD_t fd) {
FDSANE(fd);
return fd->fps[fd->nfps].io;
fd->firstFree = firstFree;
}
+#ifdef __cplusplus
+}
+#endif
+
#endif /* H_RPMIO_INTERNAL */
--- /dev/null
+#ifndef H_RPMMESSAGES
+#define H_RPMMESSAGES
+
+#define RPMMESS_DEBUG 1
+#define RPMMESS_VERBOSE 2
+#define RPMMESS_NORMAL 3
+#define RPMMESS_WARNING 4
+#define RPMMESS_ERROR 5
+#define RPMMESS_FATALERROR 6
+
+#define RPMMESS_QUIET (RPMMESS_NORMAL + 1)
+
+typedef enum rpmCallbackType_e {
+ RPMCALLBACK_INST_PROGRESS, RPMCALLBACK_INST_START,
+ RPMCALLBACK_INST_OPEN_FILE, RPMCALLBACK_INST_CLOSE_FILE,
+ RPMCALLBACK_TRANS_PROGRESS, RPMCALLBACK_TRANS_START, RPMCALLBACK_TRANS_STOP,
+ RPMCALLBACK_UNINST_PROGRESS, RPMCALLBACK_UNINST_START, RPMCALLBACK_UNINST_STOP
+} rpmCallbackType;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void * (*rpmCallbackFunction)(const void * h,
+ const rpmCallbackType what,
+ const unsigned long amount,
+ const unsigned long total,
+ const void * pkgKey, void * data);
+
+void urlSetCallback(rpmCallbackFunction notify, void *notifyData, int notifyCount);
+
+void rpmIncreaseVerbosity(void);
+void rpmSetVerbosity(int level);
+int rpmGetVerbosity(void);
+int rpmIsVerbose(void);
+int rpmIsDebug(void);
+void rpmMessage(int level, const char * format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_RPMMESSAGES */
--- /dev/null
+#include "system.h"
+
+#include <rpmio_internal.h>
+#include <popt.h>
+#include "ugid.h"
+
+extern int _rpmio_debug;
+
+/* =============================================================== */
+static int ftpMkdir(const char * path, /*@unused@*/ mode_t mode) {
+ int rc;
+ if ((rc = ftpCmd("MKD", path, NULL)) != 0)
+ return rc;
+#if NOTYET
+ { char buf[20];
+ sprintf(buf, " 0%o", mode);
+ (void) ftpCmd("SITE CHMOD", path, buf);
+ }
+#endif
+ return rc;
+}
+
+static int ftpChdir(const char * path) {
+ return ftpCmd("CWD", path, NULL);
+}
+
+static int ftpRmdir(const char * path) {
+ return ftpCmd("RMD", path, NULL);
+}
+
+static int ftpRename(const char * oldpath, const char * newpath) {
+ int rc;
+ if ((rc = ftpCmd("RNFR", oldpath, NULL)) != 0)
+ return rc;
+ return ftpCmd("RNTO", newpath, NULL);
+}
+
+static int ftpUnlink(const char * path) {
+ return ftpCmd("DELE", path, NULL);
+}
+
+/* =============================================================== */
+/* XXX rebuilddb.c: analogues to mkdir(2)/rmdir(2). */
+int Mkdir (const char *path, mode_t mode) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpMkdir(path, mode);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return mkdir(path, mode);
+}
+
+int Chdir (const char *path) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpChdir(path);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return chdir(path);
+}
+
+int Rmdir (const char *path) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpRmdir(path);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return rmdir(path);
+}
+
+/* XXX rpmdb.c: analogue to rename(2). */
+
+int Rename (const char *oldpath, const char * newpath) {
+ const char *oe = NULL;
+ const char *ne = NULL;
+ int oldut, newut;
+
+ /* XXX lib/install.c used to rely on this behavior. */
+ if (!strcmp(oldpath, newpath)) return 0;
+
+ oldut = urlPath(oldpath, &oe);
+ switch (oldut) {
+ case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+
+ newut = urlPath(newpath, &ne);
+ switch (newut) {
+ case URL_IS_FTP:
+if (_rpmio_debug)
+fprintf(stderr, "*** rename old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
+ if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
+ !strncasecmp(oldpath, newpath, (oe - oldpath))))
+ return -2;
+ return ftpRename(oldpath, newpath);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ oldpath = oe;
+ newpath = ne;
+ break;
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return rename(oldpath, newpath);
+}
+
+int Link (const char *oldpath, const char * newpath) {
+ const char *oe = NULL;
+ const char *ne = NULL;
+ int oldut, newut;
+
+ oldut = urlPath(oldpath, &oe);
+ switch (oldut) {
+ case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+
+ newut = urlPath(newpath, &ne);
+ switch (newut) {
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+if (_rpmio_debug)
+fprintf(stderr, "*** link old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
+ if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
+ !strncasecmp(oldpath, newpath, (oe - oldpath))))
+ return -2;
+ oldpath = oe;
+ newpath = ne;
+ break;
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return link(oldpath, newpath);
+}
+
+/* XXX build/build.c: analogue to unlink(2). */
+
+int Unlink(const char * path) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpUnlink(path);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return unlink(path);
+}
+
+/* XXX swiped from mc-4.5.39-pre9 vfs/ftpfs.c */
+
+#define g_strdup xstrdup
+#define g_free xfree
+
+/*
+ * FIXME: this is broken. It depends on mc not crossing border on month!
+ */
+static int current_mday;
+static int current_mon;
+static int current_year;
+
+/* Following stuff (parse_ls_lga) is used by ftpfs and extfs */
+#define MAXCOLS 30
+
+static char *columns [MAXCOLS]; /* Points to the string in column n */
+static int column_ptr [MAXCOLS]; /* Index from 0 to the starting positions of the columns */
+
+static int
+vfs_split_text (char *p)
+{
+ char *original = p;
+ int numcols;
+
+
+ for (numcols = 0; *p && numcols < MAXCOLS; numcols++){
+ while (*p == ' ' || *p == '\r' || *p == '\n'){
+ *p = 0;
+ p++;
+ }
+ columns [numcols] = p;
+ column_ptr [numcols] = p - original;
+ while (*p && *p != ' ' && *p != '\r' && *p != '\n')
+ p++;
+ }
+ return numcols;
+}
+
+static int
+is_num (int idx)
+{
+ if (!columns [idx] || columns [idx][0] < '0' || columns [idx][0] > '9')
+ return 0;
+ return 1;
+}
+
+static int
+is_dos_date(char *str)
+{
+ if (strlen(str) == 8 && str[2] == str[5] && strchr("\\-/", (int)str[2]) != NULL)
+ return (1);
+
+ return (0);
+}
+
+static int
+is_week (char *str, struct tm *tim)
+{
+ static char *week = "SunMonTueWedThuFriSat";
+ char *pos;
+
+ if((pos=strstr(week, str)) != NULL){
+ if(tim != NULL)
+ tim->tm_wday = (pos - week)/3;
+ return (1);
+ }
+ return (0);
+}
+
+static int
+is_month (char *str, struct tm *tim)
+{
+ static char *month = "JanFebMarAprMayJunJulAugSepOctNovDec";
+ char *pos;
+
+ if((pos=strstr(month, str)) != NULL){
+ if(tim != NULL)
+ tim->tm_mon = (pos - month)/3;
+ return (1);
+ }
+ return (0);
+}
+
+static int
+is_time (char *str, struct tm *tim)
+{
+ char *p, *p2;
+
+ if ((p=strchr(str, ':')) && (p2=strrchr(str, ':'))) {
+ if (p != p2) {
+ if (sscanf (str, "%2d:%2d:%2d", &tim->tm_hour, &tim->tm_min, &tim->tm_sec) != 3)
+ return (0);
+ }
+ else {
+ if (sscanf (str, "%2d:%2d", &tim->tm_hour, &tim->tm_min) != 2)
+ return (0);
+ }
+ }
+ else
+ return (0);
+
+ return (1);
+}
+
+static int is_year(char *str, struct tm *tim)
+{
+ long year;
+
+ if (strchr(str,':'))
+ return (0);
+
+ if (strlen(str)!=4)
+ return (0);
+
+ if (sscanf(str, "%ld", &year) != 1)
+ return (0);
+
+ if (year < 1900 || year > 3000)
+ return (0);
+
+ tim->tm_year = (int) (year - 1900);
+
+ return (1);
+}
+
+/*
+ * FIXME: this is broken. Consider following entry:
+ * -rwx------ 1 root root 1 Aug 31 10:04 2904 1234
+ * where "2904 1234" is filename. Well, this code decodes it as year :-(.
+ */
+
+static int
+vfs_parse_filetype (char c)
+{
+ switch (c){
+ case 'd': return S_IFDIR;
+ case 'b': return S_IFBLK;
+ case 'c': return S_IFCHR;
+ case 'l': return S_IFLNK;
+ case 's':
+#ifdef IS_IFSOCK /* And if not, we fall through to IFIFO, which is pretty close */
+ return S_IFSOCK;
+#endif
+ case 'p': return S_IFIFO;
+ case 'm': case 'n': /* Don't know what these are :-) */
+ case '-': case '?': return S_IFREG;
+ default: return -1;
+ }
+}
+
+static int vfs_parse_filemode (char *p)
+{ /* converts rw-rw-rw- into 0666 */
+ int res = 0;
+ switch (*(p++)){
+ case 'r': res |= 0400; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'w': res |= 0200; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'x': res |= 0100; break;
+ case 's': res |= 0100 | S_ISUID; break;
+ case 'S': res |= S_ISUID; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'r': res |= 0040; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'w': res |= 0020; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'x': res |= 0010; break;
+ case 's': res |= 0010 | S_ISGID; break;
+ case 'l': /* Solaris produces these */
+ case 'S': res |= S_ISGID; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'r': res |= 0004; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'w': res |= 0002; break;
+ case '-': break;
+ default: return -1;
+ }
+ switch (*(p++)){
+ case 'x': res |= 0001; break;
+ case 't': res |= 0001 | S_ISVTX; break;
+ case 'T': res |= S_ISVTX; break;
+ case '-': break;
+ default: return -1;
+ }
+ return res;
+}
+
+static int vfs_parse_filedate(int idx, time_t *t)
+{ /* This thing parses from idx in columns[] array */
+
+ char *p;
+ struct tm tim;
+ int d[3];
+ int got_year = 0;
+
+ /* Let's setup default time values */
+ tim.tm_year = current_year;
+ tim.tm_mon = current_mon;
+ tim.tm_mday = current_mday;
+ tim.tm_hour = 0;
+ tim.tm_min = 0;
+ tim.tm_sec = 0;
+ tim.tm_isdst = -1; /* Let mktime() try to guess correct dst offset */
+
+ p = columns [idx++];
+
+ /* We eat weekday name in case of extfs */
+ if(is_week(p, &tim))
+ p = columns [idx++];
+
+ /* Month name */
+ if(is_month(p, &tim)){
+ /* And we expect, it followed by day number */
+ if (is_num (idx))
+ tim.tm_mday = (int)atol (columns [idx++]);
+ else
+ return 0; /* No day */
+
+ } else {
+ /* We usually expect:
+ Mon DD hh:mm
+ Mon DD YYYY
+ But in case of extfs we allow these date formats:
+ Mon DD YYYY hh:mm
+ Mon DD hh:mm YYYY
+ Wek Mon DD hh:mm:ss YYYY
+ MM-DD-YY hh:mm
+ where Mon is Jan-Dec, DD, MM, YY two digit day, month, year,
+ YYYY four digit year, hh, mm, ss two digit hour, minute or second. */
+
+ /* Here just this special case with MM-DD-YY */
+ if (is_dos_date(p)){
+ p[2] = p[5] = '-';
+
+ if(sscanf(p, "%2d-%2d-%2d", &d[0], &d[1], &d[2]) == 3){
+ /* We expect to get:
+ 1. MM-DD-YY
+ 2. DD-MM-YY
+ 3. YY-MM-DD
+ 4. YY-DD-MM */
+
+ /* Hmm... maybe, next time :)*/
+
+ /* At last, MM-DD-YY */
+ d[0]--; /* Months are zerobased */
+ /* Y2K madness */
+ if(d[2] < 70)
+ d[2] += 100;
+
+ tim.tm_mon = d[0];
+ tim.tm_mday = d[1];
+ tim.tm_year = d[2];
+ got_year = 1;
+ } else
+ return 0; /* sscanf failed */
+ } else
+ return 0; /* unsupported format */
+ }
+
+ /* Here we expect to find time and/or year */
+
+ if (is_num (idx)) {
+ if(is_time(columns[idx], &tim) || (got_year = is_year(columns[idx], &tim))) {
+ idx++;
+
+ /* This is a special case for ctime() or Mon DD YYYY hh:mm */
+ if(is_num (idx) &&
+ ((got_year = is_year(columns[idx], &tim)) || is_time(columns[idx], &tim)))
+ idx++; /* time & year or reverse */
+ } /* only time or date */
+ }
+ else
+ return 0; /* Nor time or date */
+
+ /*
+ * If the date is less than 6 months in the past, it is shown without year
+ * other dates in the past or future are shown with year but without time
+ * This does not check for years before 1900 ... I don't know, how
+ * to represent them at all
+ */
+ if (!got_year &&
+ current_mon < 6 && current_mon < tim.tm_mon &&
+ tim.tm_mon - current_mon >= 6)
+
+ tim.tm_year--;
+
+ if ((*t = mktime(&tim)) < 0)
+ *t = 0;
+ return idx;
+}
+
+static int
+vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
+{
+ int idx, idx2, num_cols;
+ int i;
+ char *p_copy;
+
+ if (strncmp (p, "total", 5) == 0)
+ return 0;
+
+ p_copy = g_strdup(p);
+/* XXX FIXME: parse out inode number from "NLST -lai ." */
+/* XXX FIXME: parse out sizein blocks from "NLST -lais ." */
+
+ if ((i = vfs_parse_filetype(*(p++))) == -1)
+ goto error;
+
+ s->st_mode = i;
+ if (*p == ' ') /* Notwell 4 */
+ p++;
+ if (*p == '['){
+ if (strlen (p) <= 8 || p [8] != ']')
+ goto error;
+ /* Should parse here the Notwell permissions :) */
+ if (S_ISDIR (s->st_mode))
+ s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH);
+ else
+ s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
+ p += 9;
+ } else {
+ if ((i = vfs_parse_filemode(p)) == -1)
+ goto error;
+ s->st_mode |= i;
+ p += 9;
+
+ /* This is for an extra ACL attribute (HP-UX) */
+ if (*p == '+')
+ p++;
+ }
+
+ g_free(p_copy);
+ p_copy = g_strdup(p);
+ num_cols = vfs_split_text (p);
+
+ s->st_nlink = atol (columns [0]);
+ if (s->st_nlink < 0)
+ goto error;
+
+ if (!is_num (1))
+#ifdef HACK
+ s->st_uid = finduid (columns [1]);
+#else
+ unameToUid (columns [1], &s->st_uid);
+#endif
+ else
+ s->st_uid = (uid_t) atol (columns [1]);
+
+ /* Mhm, the ls -lg did not produce a group field */
+ for (idx = 3; idx <= 5; idx++)
+ if (is_month(columns [idx], NULL) || is_week(columns [idx], NULL) || is_dos_date(columns[idx]))
+ break;
+
+ if (idx == 6 || (idx == 5 && !S_ISCHR (s->st_mode) && !S_ISBLK (s->st_mode)))
+ goto error;
+
+ /* We don't have gid */
+ if (idx == 3 || (idx == 4 && (S_ISCHR(s->st_mode) || S_ISBLK (s->st_mode))))
+ idx2 = 2;
+ else {
+ /* We have gid field */
+ if (is_num (2))
+ s->st_gid = (gid_t) atol (columns [2]);
+ else
+#ifdef HACK
+ s->st_gid = findgid (columns [2]);
+#else
+ gnameToGid (columns [1], &s->st_gid);
+#endif
+ idx2 = 3;
+ }
+
+ /* This is device */
+ if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)){
+ int maj, min;
+
+ if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
+ goto error;
+
+ if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
+ goto error;
+
+#ifdef HAVE_ST_RDEV
+ s->st_rdev = ((maj & 0xff) << 8) | (min & 0xffff00ff);
+#endif
+ s->st_size = 0;
+
+ } else {
+ /* Common file size */
+ if (!is_num (idx2))
+ goto error;
+
+ s->st_size = (size_t) atol (columns [idx2]);
+#ifdef HAVE_ST_RDEV
+ s->st_rdev = 0;
+#endif
+ }
+
+ idx = vfs_parse_filedate(idx, &s->st_mtime);
+ if (!idx)
+ goto error;
+ /* Use resulting time value */
+ s->st_atime = s->st_ctime = s->st_mtime;
+ s->st_dev = 0;
+ s->st_ino = 0;
+#ifdef HAVE_ST_BLKSIZE
+ s->st_blksize = 512;
+#endif
+#ifdef HAVE_ST_BLOCKS
+ s->st_blocks = (s->st_size + 511) / 512;
+#endif
+
+ for (i = idx + 1, idx2 = 0; i < num_cols; i++ )
+ if (strcmp (columns [i], "->") == 0){
+ idx2 = i;
+ break;
+ }
+
+ if (((S_ISLNK (s->st_mode) ||
+ (num_cols == idx + 3 && s->st_nlink > 1))) /* Maybe a hardlink? (in extfs) */
+ && idx2){
+ int p;
+ char *s;
+
+ if (filename){
+#ifdef HACK
+ s = g_strndup (p_copy + column_ptr [idx], column_ptr [idx2] - column_ptr [idx] - 1);
+#else
+ int nb = column_ptr [idx2] - column_ptr [idx] - 1;
+ s = xmalloc(nb+1);
+ strncpy(s, p_copy + column_ptr [idx], nb);
+#endif
+ *filename = s;
+ }
+ if (linkname){
+ s = g_strdup (p_copy + column_ptr [idx2+1]);
+ p = strlen (s);
+ if (s [p-1] == '\r' || s [p-1] == '\n')
+ s [p-1] = 0;
+ if (s [p-2] == '\r' || s [p-2] == '\n')
+ s [p-2] = 0;
+
+ *linkname = s;
+ }
+ } else {
+ /* Extract the filename from the string copy, not from the columns
+ * this way we have a chance of entering hidden directories like ". ."
+ */
+ if (filename){
+ /*
+ *filename = g_strdup (columns [idx++]);
+ */
+ int p;
+ char *s;
+
+ s = g_strdup (p_copy + column_ptr [idx++]);
+ p = strlen (s);
+ /* g_strchomp(); */
+ if (s [p-1] == '\r' || s [p-1] == '\n')
+ s [p-1] = 0;
+ if (s [p-2] == '\r' || s [p-2] == '\n')
+ s [p-2] = 0;
+
+ *filename = s;
+ }
+ if (linkname)
+ *linkname = NULL;
+ }
+ g_free (p_copy);
+ return 1;
+
+error:
+#ifdef HACK
+ {
+ static int errorcount = 0;
+
+ if (++errorcount < 5) {
+ message_1s (1, "Could not parse:", p_copy);
+ } else if (errorcount == 5)
+ message_1s (1, "More parsing errors will be ignored.", "(sorry)" );
+ }
+#endif
+
+ if (p_copy != p) /* Carefull! */
+ g_free (p_copy);
+ return 0;
+}
+
+typedef enum {
+ DO_FTP_STAT = 1,
+ DO_FTP_LSTAT = 2,
+ DO_FTP_READLINK = 3,
+ DO_FTP_ACCESS = 4,
+ DO_FTP_GLOB = 5
+} ftpSysCall_t;
+static size_t ftpBufAlloced = 0;
+static char * ftpBuf = NULL;
+
+#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
+
+static int ftpNLST(const char * url, ftpSysCall_t ftpSysCall,
+ struct stat * st, char * rlbuf, size_t rlbufsiz)
+{
+ FD_t fd;
+ const char * path;
+ int bufLength, moretodo;
+ const char *n, *ne, *o, *oe;
+ char * s;
+ char * se;
+ const char * urldn;
+ char * bn = NULL;
+ int nbn = 0;
+ urlinfo u;
+ int rc;
+
+ n = ne = o = oe = NULL;
+ (void) urlPath(url, &path);
+ if (*path == '\0')
+ return -2;
+
+ switch (ftpSysCall) {
+ case DO_FTP_GLOB:
+ fd = ftpOpen(url, 0, 0, &u);
+ if (fd == NULL || u == NULL)
+ return -1;
+
+ u->openError = ftpReq(fd, "NLST", path);
+ break;
+ default:
+ urldn = alloca_strdup(url);
+ if ((bn = strrchr(urldn, '/')) == NULL)
+ return -2;
+ else if (bn == path)
+ bn = ".";
+ else
+ *bn++ = '\0';
+ nbn = strlen(bn);
+
+ rc = ftpChdir(urldn); /* XXX don't care about CWD */
+ if (rc < 0)
+ return rc;
+
+ fd = ftpOpen(url, 0, 0, &u);
+ if (fd == NULL || u == NULL)
+ return -1;
+
+ /* XXX possibly should do "NLST -lais" to get st_ino/st_blocks also */
+ u->openError = ftpReq(fd, "NLST", "-la");
+ break;
+ }
+
+ if (u->openError < 0) {
+ fd = fdLink(fd, "error data (ftpStat)");
+ rc = -2;
+ goto exit;
+ }
+
+ if (ftpBufAlloced == 0 || ftpBuf == NULL) {
+ ftpBufAlloced = url_iobuf_size;
+ ftpBuf = xcalloc(ftpBufAlloced, sizeof(ftpBuf[0]));
+ }
+ *ftpBuf = '\0';
+
+ bufLength = 0;
+ moretodo = 1;
+
+ do {
+
+ /* XXX FIXME: realloc ftpBuf is < ~128 chars remain */
+ if ((ftpBufAlloced - bufLength) < (1024+80)) {
+ ftpBufAlloced <<= 2;
+ ftpBuf = xrealloc(ftpBuf, ftpBufAlloced);
+ }
+ s = se = ftpBuf + bufLength;
+ *se = '\0';
+
+ rc = fdFgets(fd, se, (ftpBufAlloced - bufLength));
+ if (rc <= 0) {
+ moretodo = 0;
+ break;
+ }
+ if (ftpSysCall == DO_FTP_GLOB) { /* XXX HACK */
+ bufLength += strlen(se);
+ continue;
+ }
+
+ for (s = se; *s != '\0'; s = se) {
+ int bingo;
+
+ while (*se && *se != '\n') se++;
+ if (se > s && se[-1] == '\r') se[-1] = '\0';
+ if (*se == '\0') break;
+ *se++ = '\0';
+
+ if (!strncmp(s, "total ", sizeof("total ")-1)) continue;
+
+ o = NULL;
+ for (bingo = 0, n = se; n >= s; n--) {
+ switch (*n) {
+ case '\0':
+ oe = ne = n;
+ break;
+ case ' ':
+ if (o || !(n[-3] == ' ' && n[-2] == '-' && n[-1] == '>')) {
+ while (*(++n) == ' ');
+ bingo++;
+ break;
+ }
+ for (o = n + 1; *o == ' '; o++);
+ n -= 3;
+ ne = n;
+ break;
+ default:
+ break;
+ }
+ if (bingo) break;
+ }
+
+ if (nbn != (ne - n)) continue; /* Same name length? */
+ if (strncmp(n, bn, nbn)) continue; /* Same name? */
+
+ moretodo = 0;
+ break;
+ }
+
+ if (moretodo && se > s) {
+ bufLength = se - s - 1;
+ if (s != ftpBuf)
+ memmove(ftpBuf, s, bufLength);
+ } else {
+ bufLength = 0;
+ }
+ } while (moretodo);
+
+ switch (ftpSysCall) {
+ case DO_FTP_STAT:
+ if (o && oe) {
+ /* XXX FIXME: symlink, replace urldn/bn from [o,oe) and restart */
+ }
+ /*@fallthrough@*/
+ case DO_FTP_LSTAT:
+ if (st == NULL || !(n && ne)) {
+ rc = -1;
+ } else {
+ rc = ((vfs_parse_ls_lga(s, st, NULL, NULL) > 0) ? 0 : -1);
+ }
+ break;
+ case DO_FTP_READLINK:
+ if (rlbuf == NULL || !(o && oe)) {
+ rc = -1;
+ } else {
+ rc = oe - o;
+ if (rc > rlbufsiz)
+ rc = rlbufsiz;
+ memcpy(rlbuf, o, rc);
+ if (rc < rlbufsiz)
+ rlbuf[rc] = '\0';
+ }
+ break;
+ case DO_FTP_ACCESS:
+ rc = 0; /* XXX WRONG WRONG WRONG */
+ break;
+ case DO_FTP_GLOB:
+ rc = 0; /* XXX WRONG WRONG WRONG */
+ break;
+ }
+
+exit:
+ ufdClose(fd);
+ return rc;
+}
+
+static int ftpStat(const char * path, struct stat *st)
+{
+ return ftpNLST(path, DO_FTP_STAT, st, NULL, 0);
+}
+
+static int ftpLstat(const char * path, struct stat *st) {
+ int rc;
+ rc = ftpNLST(path, DO_FTP_LSTAT, st, NULL, 0);
+if (_rpmio_debug)
+fprintf(stderr, "*** ftpLstat(%s) rc %d\n", path, rc);
+ return rc;
+}
+
+static int ftpReadlink(const char * path, char * buf, size_t bufsiz) {
+ return ftpNLST(path, DO_FTP_READLINK, NULL, buf, bufsiz);
+}
+
+static int ftpGlob(const char * path, int flags,
+ int errfunc(const char * epath, int eerno), glob_t * pglob)
+{
+ int rc;
+
+ if (pglob == NULL)
+ return -2;
+ rc = ftpNLST(path, DO_FTP_GLOB, NULL, NULL, 0);
+if (_rpmio_debug)
+fprintf(stderr, "*** ftpGlob(%s,0x%x,%p,%p) ftpNLST rc %d\n", path, flags, errfunc, pglob, rc);
+ if (rc)
+ return rc;
+ rc = poptParseArgvString(ftpBuf, &pglob->gl_pathc, (const char ***)&pglob->gl_pathv);
+ pglob->gl_offs = -1; /* XXX HACK HACK HACK */
+ return rc;
+}
+
+static void ftpGlobfree(glob_t * pglob) {
+if (_rpmio_debug)
+fprintf(stderr, "*** ftpGlobfree(%p)\n", pglob);
+ if (pglob->gl_offs == -1) /* XXX HACK HACK HACK */
+ xfree(pglob->gl_pathv);
+}
+
+int Stat(const char * path, struct stat * st) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+if (_rpmio_debug)
+fprintf(stderr, "*** Stat(%s,%p)\n", path, st);
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpStat(path, st);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return stat(path, st);
+}
+
+int Lstat(const char * path, struct stat * st) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+if (_rpmio_debug)
+fprintf(stderr, "*** Lstat(%s,%p)\n", path, st);
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpLstat(path, st);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return lstat(path, st);
+}
+
+int Readlink(const char * path, char * buf, size_t bufsiz) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+ switch (ut) {
+ case URL_IS_FTP:
+ return ftpReadlink(path, buf, bufsiz);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return readlink(path, buf, bufsiz);
+}
+
+int Access(const char * path, int amode) {
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+if (_rpmio_debug)
+fprintf(stderr, "*** Access(%s,%d)\n", path, amode);
+ switch (ut) {
+ case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return access(path, amode);
+}
+
+int Glob(const char *path, int flags,
+ int errfunc(const char * epath, int eerrno), glob_t *pglob)
+{
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+if (_rpmio_debug)
+fprintf(stderr, "*** Glob(%s,0x%x,%p,%p)\n", path, flags, errfunc, pglob);
+ switch (ut) {
+ case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ return ftpGlob(path, flags, errfunc, pglob);
+ /*@notreached@*/ break;
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return -2;
+ /*@notreached@*/ break;
+ }
+ return glob(path, flags, errfunc, pglob);
+}
+
+void Globfree(glob_t *pglob)
+{
+if (_rpmio_debug)
+fprintf(stderr, "*** Globfree(%p)\n", pglob);
+ if (pglob->gl_offs == -1) /* XXX HACK HACK HACK */
+ ftpGlobfree(pglob);
+ else
+ globfree(pglob);
+}
+
+DIR * Opendir(const char * path)
+{
+ const char * lpath;
+ int ut = urlPath(path, &lpath);
+
+if (_rpmio_debug)
+fprintf(stderr, "*** Opendir(%s)\n", path);
+ switch (ut) {
+ case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_PATH:
+ path = lpath;
+ /*@fallthrough@*/
+ case URL_IS_UNKNOWN:
+ break;
+ case URL_IS_DASH:
+ default:
+ return NULL;
+ /*@notreached@*/ break;
+ }
+ return opendir(path);
+}
+
+struct dirent * Readdir(DIR * dir)
+{
+if (_rpmio_debug)
+fprintf(stderr, "*** Readdir(%p)\n", dir);
+ return readdir(dir);
+}
+
+int Closedir(DIR * dir)
+{
+if (_rpmio_debug)
+fprintf(stderr, "*** Closedir(%p)\n", dir);
+ return closedir(dir);
+}
#include <netinet/in.h>
#endif /* __LCLINT__ */
-#include <rpmbuild.h>
+#include <rpmmacro.h>
+#include <rpmmessages.h>
#include <rpmio_internal.h>
#ifndef IPPORT_FTP
#define RPMURL_DEBUG_REFS 0x20000000
int _url_debug = 0;
-#define DBG(_f, _m, _x) if ((_url_debug | (_f)) & (_m)) fprintf _x
+#define URLDBG(_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)
+#define URLDBGIO(_f, _x) URLDBG((_f), RPMURL_DEBUG_IO, _x)
+#define URLDBGREFS(_f, _x) URLDBG((_f), RPMURL_DEBUG_REFS, _x)
/*@only@*/ /*@null@*/ static urlinfo *uCache = NULL;
static int uCount = 0;
{
URLSANE(u);
u->nrefs++;
-DBGREFS(0, (stderr, "--> url %p ++ %d %s at %s:%u\n", u, u->nrefs, msg, file, line));
+URLDBGREFS(0, (stderr, "--> url %p ++ %d %s at %s:%u\n", u, u->nrefs, msg, file, line));
return u;
}
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));
+URLDBGREFS(0, (stderr, "--> url %p -- %d %s at %s:%u\n", u, u->nrefs, msg, file, line));
if (--u->nrefs > 0)
return u;
if (u->ctrl) {
free(u->buf);
u->buf = NULL;
}
- FREE(u->url);
- FREE(u->service);
- FREE(u->user);
- FREE(u->password);
- FREE(u->host);
- FREE(u->portstr);
- FREE(u->proxyu);
- FREE(u->proxyh);
-
- /*@-refcounttrans@*/ FREE(u); /*@-refcounttrans@*/
+ if (u->url) xfree(u->url);
+ if (u->service) xfree(u->service);
+ if (u->user) xfree(u->user);
+ if (u->password) xfree(u->password);
+ if (u->host) xfree(u->host);
+ if (u->portstr) xfree(u->portstr);
+ if (u->proxyu) xfree(u->proxyu);
+ if (u->proxyh) xfree(u->proxyh);
+
+ /*@-refcounttrans@*/ xfree(u); /*@-refcounttrans@*/
return NULL;
}
/* Zap proxy host and port in case they have been reset */
u->proxyp = -1;
- FREE(u->proxyh);
+ if (u->proxyh) xfree(u->proxyh);
/* Perform one-time FTP initialization */
if (u->urltype == URL_IS_FTP) {
char * prompt;
prompt = alloca(strlen(u->host) + strlen(u->user) + 256);
sprintf(prompt, _("Password for %s@%s: "), u->user, u->host);
- FREE(u->password);
+ if (u->password) xfree(u->password);
u->password = xstrdup( /*@-unrecog@*/ getpass(prompt) /*@=unrecog@*/ );
}