summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2002-02-23 21:24:37 +0000
committerjbj <devnull@localhost>2002-02-23 21:24:37 +0000
commit6df10492d972520c7be51ae7ccf9b02780e5693b (patch)
tree89a5125925b4af142e1588d7f804fd9c30b7cf23
parent4e34d9ebf749b0db380380b0de7b3f82b4c151bc (diff)
downloadlibrpm-tizen-6df10492d972520c7be51ae7ccf9b02780e5693b.tar.gz
librpm-tizen-6df10492d972520c7be51ae7ccf9b02780e5693b.tar.bz2
librpm-tizen-6df10492d972520c7be51ae7ccf9b02780e5693b.zip
fix: opendir(3) et al functional with FTP.
Use GNU extensions to apply glob(3) to ftp:// URL's. CVS patchset: 5333 CVS date: 2002/02/23 21:24:37
-rw-r--r--Doxyfile.in4
-rw-r--r--rpmio/Makefile.am19
-rw-r--r--rpmio/rpmrpc.c230
-rw-r--r--rpmio/tdir.c81
-rw-r--r--rpmio/tglob.c84
-rw-r--r--tools/tpkgid.c13
6 files changed, 386 insertions, 45 deletions
diff --git a/Doxyfile.in b/Doxyfile.in
index 515a65eea..a5a6bb003 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -415,8 +415,11 @@ INPUT = \
@top_srcdir@/rpmdb/tagname.c \
@top_srcdir@/rpmdb/tagtbl.c \
@top_srcdir@/rpmio/digest.c \
+ @top_srcdir@/rpmio/fts.c \
+ @top_srcdir@/rpmio/fts.h \
@top_srcdir@/rpmio/macro.c \
@top_srcdir@/rpmio/rpmlog.c \
+ @top_srcdir@/rpmio/rpmlog.h \
@top_srcdir@/rpmio/rpmerr.h \
@top_srcdir@/rpmio/rpmio.c \
@top_srcdir@/rpmio/rpmio.h \
@@ -450,7 +453,6 @@ INPUT = \
@top_srcdir@/tools/dumpdb.c \
@top_srcdir@/tools/javadeps.c \
@top_srcdir@/tools/rpmarchive.c \
- @top_srcdir@/tools/rpmchecksig.c \
@top_srcdir@/tools/rpmheader.c \
@top_srcdir@/tools/rpminject.c \
@top_srcdir@/tools/rpmlead.c \
diff --git a/rpmio/Makefile.am b/rpmio/Makefile.am
index 5f67038be..8ce483280 100644
--- a/rpmio/Makefile.am
+++ b/rpmio/Makefile.am
@@ -2,9 +2,9 @@
AUTOMAKE_OPTIONS = 1.4 foreign
-EXTRA_DIST = tdigest.c tficl.c tkey.c trpmio.c
+EXTRA_DIST = tdigest.c tdir.c tficl.c tglob.c tkey.c trpmio.c
-EXTRA_PROGRAMS = tdigest tkey tring trpmio dumpasn1
+EXTRA_PROGRAMS = tdigest tdir tglob tkey tring trpmio dumpasn1
INCLUDES = \
-I$(top_srcdir) \
@@ -26,7 +26,8 @@ LIBS += @WITH_ZLIB_LIB@ -lrt -lpthread
BEECRYPTLOBJS = $(shell cat $(top_builddir)/beecrypt/listobjs)
lib_LTLIBRARIES = librpmio.la
-librpmio_la_SOURCES = digest.c fts.c macro.c rpmio.c rpmlog.c rpmmalloc.c \
+librpmio_la_SOURCES = digest.c fts.c macro.c \
+ rpmio.c rpmlog.c rpmmalloc.c \
rpmpgp.c rpmrpc.c strcasecmp.c stubs.c url.c ugid.c
librpmio_la_LDFLAGS = -release @VERSION@
librpmio_la_LIBADD = $(BEECRYPTLOBJS)
@@ -53,13 +54,21 @@ clean-local:
tdigest_SOURCES = tdigest.c
tdigest_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
-trpmio_SOURCES = trpmio.c
-trpmio_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
+tdir_SOURCES = tdir.c
+tdir_LDFLAGS = -all-static
+tdir_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
+
+tglob_SOURCES = tglob.c
+tglob_LDFLAGS = -all-static
+tglob_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
tkey_SOURCES = tkey.c
tkey_LDFLAGS = -all-static
tkey_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
+trpmio_SOURCES = trpmio.c
+trpmio_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
+
tring_SOURCES = tring.c
tring_LDFLAGS = -all-static
tring_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
diff --git a/rpmio/rpmrpc.c b/rpmio/rpmrpc.c
index df4dcd13a..1b36eb8ea 100644
--- a/rpmio/rpmrpc.c
+++ b/rpmio/rpmrpc.c
@@ -4,6 +4,7 @@
*/
#include "system.h"
+#include <pthread.h>
#include <rpmio_internal.h>
#include <popt.h>
#include "ugid.h"
@@ -13,6 +14,10 @@
/*@access urlinfo@*/
/*@-redecl@*/
+extern int _ftp_debug;
+/*@=redecl@*/
+
+/*@-redecl@*/
extern int _rpmio_debug;
/*@=redecl@*/
@@ -840,7 +845,7 @@ static int ftpNLST(const char * url, ftpSysCall_t ftpSysCall,
if (fd == NULL || u == NULL)
return -1;
- u->openError = ftpReq(fd, "NLST", path);
+ u->openError = ftpReq(fd, "LIST", path);
break;
default:
urldn = alloca_strdup(url);
@@ -1005,7 +1010,11 @@ static int ftpStat(const char * path, /*@out@*/ struct stat *st)
/*@globals fileSystem @*/
/*@modifies *st, fileSystem @*/
{
- return ftpNLST(path, DO_FTP_STAT, st, NULL, 0);
+ int rc;
+ rc = ftpNLST(path, DO_FTP_STAT, st, NULL, 0);
+if (_ftp_debug)
+fprintf(stderr, "*** ftpStat(%s) rc %d\n", path, rc);
+ return rc;
}
static int ftpLstat(const char * path, /*@out@*/ struct stat *st)
@@ -1014,7 +1023,7 @@ static int ftpLstat(const char * path, /*@out@*/ struct stat *st)
{
int rc;
rc = ftpNLST(path, DO_FTP_LSTAT, st, NULL, 0);
-if (_rpmio_debug)
+if (_ftp_debug)
fprintf(stderr, "*** ftpLstat(%s) rc %d\n", path, rc);
return rc;
}
@@ -1023,42 +1032,181 @@ static int ftpReadlink(const char * path, /*@out@*/ char * buf, size_t bufsiz)
/*@globals fileSystem @*/
/*@modifies *buf, fileSystem @*/
{
- return ftpNLST(path, DO_FTP_READLINK, NULL, buf, bufsiz);
+ int rc;
+ rc = ftpNLST(path, DO_FTP_READLINK, NULL, buf, bufsiz);
+if (_ftp_debug)
+fprintf(stderr, "*** ftpReadlink(%s) rc %d\n", path, rc);
+ return rc;
}
-static int ftpGlob(const char * path, int flags,
- int errfunc(const char * epath, int eerno),
- /*@out@*/ glob_t * pglob)
- /*@globals fileSystem @*/
- /*@modifies *pglob, fileSystem @*/
+struct __dirstream {
+ int fd; /* File descriptor. */
+ char * data; /* Directory block. */
+ size_t allocation; /* Space allocated for the block. */
+ size_t size; /* Total valid data in the block. */
+ size_t offset; /* Current offset into the block. */
+ off_t filepos; /* Position of next entry to read. */
+ pthread_mutex_t lock; /* Mutex lock for this structure. */
+};
+
+static int ftpmagicdir = 0x8440291;
+#define ISFTPMAGIC(_dir) (!memcmp((_dir), &ftpmagicdir, sizeof(ftpmagicdir)))
+
+static DIR * ftpOpendir(const char * path)
{
+ DIR * dir;
+ struct dirent * dp;
+ size_t nb;
+ const char * s, * sb, * se;
+ const char ** av;
+ unsigned char * dt;
+ char * t;
+ int ac;
+ int c;
int rc;
- if (pglob == NULL)
- return -2;
+if (_ftp_debug)
+fprintf(stderr, "*** ftpOpendir(%s)\n", path);
rc = ftpNLST(path, DO_FTP_GLOB, NULL, NULL, 0);
-/*@-castfcnptr@*/
-if (_rpmio_debug)
-fprintf(stderr, "*** ftpGlob(%s,0x%x,%p,%p) ftpNLST rc %d\n", path, (unsigned)flags, (void *)errfunc, pglob, rc);
-/*@=castfcnptr@*/
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;
+ return NULL;
+
+ /*
+ * ftpBuf now contains absolute paths, newline terminated.
+ * Calculate the number of bytes to hold the directory info.
+ */
+ nb = sizeof(".") + sizeof("..");
+ ac = 2;
+ sb = NULL;
+ s = se = ftpBuf;
+ while ((c = *se) != '\0') {
+ se++;
+ switch (c) {
+ case '/':
+ sb = se;
+ break;
+ case '\r':
+ if (sb == NULL) {
+ for (sb = se; sb > s && sb[-1] != ' '; sb--)
+ ;
+ }
+ ac++;
+ nb += (se - sb);
+
+ if (*se == '\n') se++;
+ sb = NULL;
+ s = se;
+ break;
+ default:
+ break;
+ }
+ }
+
+ nb += sizeof(*dir) + sizeof(*dp) + ((ac + 1) * sizeof(*av)) + (ac + 1);
+ dir = xcalloc(1, nb);
+ dp = (struct dirent *) (dir + 1);
+ av = (const char **) (dp + 1);
+ dt = (char *) (av + (ac + 1));
+ t = (char *) (dt + ac + 1);
+
+ dir->fd = ftpmagicdir;
+ dir->data = (char *) dp;
+ dir->allocation = nb;
+ dir->size = ac;
+ dir->offset = -1;
+ dir->filepos = 0;
+
+ ac = 0;
+ dt[ac] = DT_DIR; av[ac++] = t; t = stpcpy(t, "."); t++;
+ dt[ac] = DT_DIR; av[ac++] = t; t = stpcpy(t, ".."); t++;
+ sb = NULL;
+ s = se = ftpBuf;
+ while ((c = *se) != '\0') {
+ se++;
+ switch (c) {
+ case '/':
+ sb = se;
+ break;
+ case '\r':
+ av[ac] = t;
+ if (sb == NULL) {
+ switch(*s) {
+ case 'p': dt[ac] = DT_FIFO; break;
+ case 'c': dt[ac] = DT_CHR; break;
+ case 'd': dt[ac] = DT_DIR; break;
+ case 'b': dt[ac] = DT_BLK; break;
+ case '-': dt[ac] = DT_REG; break;
+ case 'l': dt[ac] = DT_LNK; break;
+ case 's': dt[ac] = DT_SOCK; break;
+ default: dt[ac] = DT_UNKNOWN; break;
+ }
+ for (sb = se; sb > s && sb[-1] != ' '; sb--)
+ ;
+ }
+ ac++;
+ t = stpncpy(t, sb, (se - sb));
+ t[-1] = '\0';
+ if (*se == '\n') se++;
+ sb = NULL;
+ s = se;
+ break;
+ default:
+ break;
+ }
+ }
+ av[ac] = NULL;
+
+ return dir;
}
-static void ftpGlobfree(glob_t * pglob)
- /*@modifies *pglob @*/
+static struct dirent * ftpReaddir(DIR * dir)
{
-/*@-modfilesys@*/
-if (_rpmio_debug)
-fprintf(stderr, "*** ftpGlobfree(%p)\n", pglob);
-/*@=modfilesys@*/
- if (pglob->gl_offs == -1) { /* XXX HACK HACK HACK */
- free((void *)pglob->gl_pathv);
- pglob->gl_pathv = NULL;
+ struct dirent * dp;
+ const char ** av;
+ unsigned char * dt;
+ int ac;
+ int i;
+
+ if (dir == NULL || !ISFTPMAGIC(dir) || dir->data == NULL) {
+ /* XXX TODO: EBADF errno. */
+ return NULL;
+ }
+
+ dp = (struct dirent *) dir->data;
+ av = (const char **) (dp + 1);
+ ac = dir->size;
+ dt = (char *) (av + (ac + 1));
+ i = dir->offset + 1;
+
+ if (i < 0 || i >= ac || av[i] == NULL)
+ return NULL;
+
+ dir->offset = i;
+
+ /* XXX glob(3) uses REAL_DIR_ENTRY(dp) test on d_ino */
+ dp->d_ino = i + 1; /* W2DO? */
+ dp->d_off = 0; /* W2DO? */
+ dp->d_reclen = 0; /* W2DO? */
+ dp->d_type = dt[i];
+
+ strncpy(dp->d_name, av[i], sizeof(dp->d_name));
+if (_ftp_debug)
+fprintf(stderr, "*** ftpReaddir(%p) %p \"%s\"\n", dir, dp, dp->d_name);
+
+ return dp;
+}
+
+static int ftpClosedir(DIR * dir)
+{
+if (_ftp_debug)
+fprintf(stderr, "*** ftpClosedir(%p)\n", dir);
+ if (dir == NULL || !ISFTPMAGIC(dir)) {
+ /* XXX TODO: EBADF errno. */
+ return -1;
}
+ free((void *)dir);
+ dir = NULL;
+ return 0;
}
int Stat(const char * path, struct stat * st)
@@ -1168,9 +1316,14 @@ if (_rpmio_debug)
fprintf(stderr, "*** Glob(%s,0x%x,%p,%p)\n", pattern, (unsigned)flags, (void *)errfunc, pglob);
/*@=castfcnptr@*/
switch (ut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
- return ftpGlob(pattern, flags, errfunc, pglob);
- /*@notreached@*/ break;
+ case URL_IS_FTP:
+ pglob->gl_closedir = Closedir;
+ pglob->gl_readdir = Readdir;
+ pglob->gl_opendir = Opendir;
+ pglob->gl_lstat = Lstat;
+ pglob->gl_stat = Stat;
+ flags |= GLOB_ALTDIRFUNC;
+ break;
case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
case URL_IS_PATH:
pattern = lpath;
@@ -1189,12 +1342,7 @@ void Globfree(glob_t *pglob)
{
if (_rpmio_debug)
fprintf(stderr, "*** Globfree(%p)\n", pglob);
- /*@-branchstate@*/
- if (pglob->gl_offs == -1) /* XXX HACK HACK HACK */
- ftpGlobfree(pglob);
- else
- globfree(pglob);
- /*@=branchstate@*/
+ globfree(pglob);
}
DIR * Opendir(const char * path)
@@ -1205,7 +1353,9 @@ DIR * Opendir(const char * path)
if (_rpmio_debug)
fprintf(stderr, "*** Opendir(%s)\n", path);
switch (ut) {
- case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
+ case URL_IS_FTP:
+ return ftpOpendir(path);
+ /*@notreached@*/ break;
case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
case URL_IS_PATH:
path = lpath;
@@ -1227,6 +1377,8 @@ struct dirent * Readdir(DIR * dir)
{
if (_rpmio_debug)
fprintf(stderr, "*** Readdir(%p)\n", (void *)dir);
+ if (dir == NULL || ISFTPMAGIC(dir))
+ return ftpReaddir(dir);
return readdir(dir);
}
@@ -1234,6 +1386,8 @@ int Closedir(DIR * dir)
{
if (_rpmio_debug)
fprintf(stderr, "*** Closedir(%p)\n", (void *)dir);
+ if (dir == NULL || ISFTPMAGIC(dir))
+ return ftpClosedir(dir);
return closedir(dir);
}
/*@=voidabstract@*/
diff --git a/rpmio/tdir.c b/rpmio/tdir.c
new file mode 100644
index 000000000..2795b33cc
--- /dev/null
+++ b/rpmio/tdir.c
@@ -0,0 +1,81 @@
+#include "system.h"
+
+#include <rpmio_internal.h>
+#include <rpmmacro.h>
+#include <rpmmessages.h>
+#include <popt.h>
+
+#include "debug.h"
+
+static int _debug = 0;
+
+/*@unchecked@*/
+extern int _ftp_debug;
+/*@unchecked@*/
+extern int _rpmio_debug;
+
+#define FTPPATH "ftp://porkchop/mnt/redhat/beehive/comps/dist/7.2-rpm"
+#define DIRPATH "/mnt/redhat/beehive/comps/dist/7.2-rpm"
+static char * dirpath = DIRPATH;
+static char * ftppath = FTPPATH;
+
+static void printDir(const char * path)
+{
+ struct dirent * dp;
+ DIR * dir;
+ int xx;
+ int i;
+
+fprintf(stderr, "===== %s\n", path);
+ dir = Opendir(path);
+ i = 0;
+ while ((dp = Readdir(dir)) != NULL) {
+fprintf(stderr, "%5d (%x,%x) %x %x %s\n", i++,
+(unsigned) dp->d_ino,
+(unsigned) dp->d_off,
+(unsigned) dp->d_reclen,
+(unsigned) dp->d_type,
+dp->d_name);
+ }
+ xx = Closedir(dir);
+}
+
+static struct poptOption optionsTable[] = {
+ { "debug", 'd', POPT_ARG_VAL, &_debug, -1, NULL, NULL },
+ { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
+ N_("debug protocol data stream"), NULL},
+ { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
+ N_("debug rpmio I/O"), NULL},
+ { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
+ N_("debug URL cache handling"), NULL},
+ { "verbose", 'v', 0, 0, 'v', NULL, NULL },
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
+int
+main(int argc, const char *argv[])
+{
+ poptContext optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
+ int rc;
+
+ while ((rc = poptGetNextOpt(optCon)) > 0) {
+ switch (rc) {
+ case 'v':
+ rpmIncreaseVerbosity();
+ /*@switchbreak@*/ break;
+ default:
+ /*@switchbreak@*/ break;
+ }
+ }
+
+ if (_debug) {
+ rpmIncreaseVerbosity();
+ rpmIncreaseVerbosity();
+ }
+
+ printDir(dirpath);
+ printDir(ftppath);
+
+ return 0;
+}
diff --git a/rpmio/tglob.c b/rpmio/tglob.c
new file mode 100644
index 000000000..2dabc1f5c
--- /dev/null
+++ b/rpmio/tglob.c
@@ -0,0 +1,84 @@
+#include "system.h"
+
+#include <rpmio_internal.h>
+#include <rpmmacro.h>
+#include <rpmmessages.h>
+#include <popt.h>
+
+#include "debug.h"
+
+static int _debug = 0;
+
+/*@unchecked@*/
+extern int _ftp_debug;
+/*@unchecked@*/
+extern int _rpmio_debug;
+
+#define FTPPATH "ftp://porkchop/mnt/redhat/beehive/comps/dist/[78]*/rpm*"
+#define DIRPATH "/mnt/redhat/beehive/comps/dist/[78]*/rpm*"
+static char * dirpath = DIRPATH;
+static char * ftppath = FTPPATH;
+
+static int Glob_error(const char *epath, int eerrno)
+{
+fprintf(stderr, "*** glob_error(%p,%d) path %s\n", epath, eerrno, epath);
+ return 1;
+}
+
+static void printGlob(const char * path)
+{
+ glob_t gl;
+ int rc;
+ int i;
+
+fprintf(stderr, "===== %s\n", path);
+ gl.gl_pathc = 0;
+ gl.gl_pathv = NULL;
+ gl.gl_offs = 0;
+ rc = Glob(path, 0, Glob_error, &gl);
+fprintf(stderr, "*** Glob rc %d\n", rc);
+ if (rc == 0)
+ for (i = 0; i < gl.gl_pathc; i++)
+ fprintf(stderr, "%5d %s\n", i, gl.gl_pathv[i]);
+ Globfree(&gl);
+}
+
+static struct poptOption optionsTable[] = {
+ { "debug", 'd', POPT_ARG_VAL, &_debug, -1, NULL, NULL },
+ { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
+ N_("debug protocol data stream"), NULL},
+ { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
+ N_("debug rpmio I/O"), NULL},
+ { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
+ N_("debug URL cache handling"), NULL},
+ { "verbose", 'v', 0, 0, 'v', NULL, NULL },
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
+int
+main(int argc, const char *argv[])
+{
+ poptContext optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
+ int rc;
+
+ while ((rc = poptGetNextOpt(optCon)) > 0) {
+ switch (rc) {
+ case 'v':
+ rpmIncreaseVerbosity();
+ /*@switchbreak@*/ break;
+ default:
+ /*@switchbreak@*/ break;
+ }
+ }
+
+ if (_debug) {
+ rpmIncreaseVerbosity();
+ rpmIncreaseVerbosity();
+ }
+
+ printGlob(dirpath);
+ printGlob(ftppath);
+
+ return 0;
+}
diff --git a/tools/tpkgid.c b/tools/tpkgid.c
index 882f0a30f..520cb7541 100644
--- a/tools/tpkgid.c
+++ b/tools/tpkgid.c
@@ -4,6 +4,7 @@
#include <rpmlib.h>
#include <rpmmacro.h>
+#include <rpmurl.h>
#include <rpmpgp.h>
#include "depends.h"
@@ -12,6 +13,10 @@
#include "debug.h"
static int _debug = 0;
+/*@unchecked@*/
+extern int _ftp_debug;
+/*@unchecked@*/
+extern int _rpmio_debug;
const char * bhpath;
int bhpathlen = 0;
@@ -372,8 +377,14 @@ static void initGlobs(const char ** argv)
}
static struct poptOption optionsTable[] = {
- { "verbose", 'v', 0, 0, 'v', NULL, NULL },
{ "debug", 'd', POPT_ARG_VAL, &_debug, -1, NULL, NULL },
+ { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
+ N_("debug protocol data stream"), NULL},
+ { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
+ N_("debug rpmio I/O"), NULL},
+ { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
+ N_("debug URL cache handling"), NULL},
+ { "verbose", 'v', 0, 0, 'v', NULL, NULL },
POPT_AUTOHELP
POPT_TABLEEND
};