diff options
author | jbj <devnull@localhost> | 2002-02-23 21:24:37 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2002-02-23 21:24:37 +0000 |
commit | 6df10492d972520c7be51ae7ccf9b02780e5693b (patch) | |
tree | 89a5125925b4af142e1588d7f804fd9c30b7cf23 | |
parent | 4e34d9ebf749b0db380380b0de7b3f82b4c151bc (diff) | |
download | librpm-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.in | 4 | ||||
-rw-r--r-- | rpmio/Makefile.am | 19 | ||||
-rw-r--r-- | rpmio/rpmrpc.c | 230 | ||||
-rw-r--r-- | rpmio/tdir.c | 81 | ||||
-rw-r--r-- | rpmio/tglob.c | 84 | ||||
-rw-r--r-- | tools/tpkgid.c | 13 |
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 }; |