RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: [EMAIL PROTECTED] Module: rpm Date: 29-Feb-2008 20:25:37 Branch: HEAD Handle: 2008022919253700 Added files: rpm/rpmio ar.c ar.h tdeb.c Modified files: rpm/rpmio .cvsignore Makefile.am Log: - jbj: read ar(1) archives (only GNU with <16 char names atm). Summary: Revision Changes Path 1.21 +5 -2 rpm/rpmio/.cvsignore 1.141 +11 -8 rpm/rpmio/Makefile.am 1.1 +220 -0 rpm/rpmio/ar.c 1.1 +74 -0 rpm/rpmio/ar.h 1.1 +158 -0 rpm/rpmio/tdeb.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmio/.cvsignore ============================================================================ $ cvs diff -u -r1.20 -r1.21 .cvsignore --- rpm/rpmio/.cvsignore 11 Feb 2008 22:11:39 -0000 1.20 +++ rpm/rpmio/.cvsignore 29 Feb 2008 19:25:37 -0000 1.21 @@ -8,11 +8,15 @@ *.la *.lcd *.lo +dumpasn1 gengpg.h +lookup3 +rpmdigest rpmgrep teststderr testtry tdigest +tdeb tdir tfts tget @@ -27,6 +31,5 @@ tput tring trpmio -dumpasn1 -lookup3 tsw +ttar @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/Makefile.am ============================================================================ $ cvs diff -u -r1.140 -r1.141 Makefile.am --- rpm/rpmio/Makefile.am 27 Feb 2008 20:26:00 -0000 1.140 +++ rpm/rpmio/Makefile.am 29 Feb 2008 19:25:37 -0000 1.141 @@ -4,9 +4,9 @@ LINT = splint -EXTRA_DIST = tdir.c tfts.c tget.c tglob.c thkp.c thtml.c tinv.c tkey.c tmire.c tput.c trpmio.c tsw.c ttar.c lookup3.c tpw.c librpmio.vers testit.sh rpmgrep.1 +EXTRA_DIST = ar.c tdeb.c tdir.c tfts.c tget.c tglob.c thkp.c thtml.c tinv.c tkey.c tmire.c tput.c trpmio.c tsw.c ttar.c lookup3.c tpw.c librpmio.vers testit.sh rpmgrep.1 -EXTRA_PROGRAMS = tdir tfts tget tglob thkp thtml tinv tkey tmacro tmagic tmire tput tpw trpmio tsw ttar dumpasn1 lookup3 +EXTRA_PROGRAMS = tdeb tdir tfts tget tglob thkp thtml tinv tkey tmacro tmagic tmire tput tpw trpmio tsw ttar dumpasn1 lookup3 bin_PROGRAMS = rpmdigest man_MANS = @@ -35,11 +35,11 @@ $(top_builddir)/misc/librpmmisc.la \ @LTLIBINTL@ -#RPM_LDADD = \ -# $(top_builddir)/build/librpmbuild.la \ -# $(top_builddir)/lib/librpm.la \ -# $(top_builddir)/rpmdb/librpmdb.la \ -# $(RPMIO_LDADD) +RPM_LDADD = \ + $(top_builddir)/build/librpmbuild.la \ + $(top_builddir)/lib/librpm.la \ + $(top_builddir)/rpmdb/librpmdb.la \ + $(RPMIO_LDADD) pkgincdir = $(pkgincludedir)$(WITH_PATH_VERSIONED_SUFFIX) pkginc_HEADERS = \ @@ -48,7 +48,7 @@ rpmnss.h rpmpgp.h rpmsq.h rpmssl.h rpmsw.h rpmurl.h rpmxar.h \ stringbuf.h ugid.h rpmuuid.h noinst_HEADERS = \ - md2.h md4.h poptIO.h rmd128.h rmd160.h rmd256.h rmd320.h sha224.h \ + ar.h md2.h md4.h poptIO.h rmd128.h rmd160.h rmd256.h rmd320.h sha224.h \ salsa10.h salsa20.h tiger.h \ LzmaDecode.h rpmhook.h rpmio_internal.h rpmlua.h @@ -154,6 +154,9 @@ rpmdigest_SOURCES = rpmdigest.c rpmdigest_LDADD = $(RPMIO_LDADD) +tdeb_SOURCES = tdeb.c ar.c +tdeb_LDFLAGS = $(RPM_LDADD) + tdir_SOURCES = tdir.c tdir_LDADD = $(RPMIO_LDADD) @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/ar.c ============================================================================ $ cvs diff -u -r0 -r1.1 ar.c --- /dev/null 2008-02-29 20:22:00 +0100 +++ ar.c 2008-02-29 20:25:37 +0100 @@ -0,0 +1,220 @@ +/** \ingroup payload + * \file rpmio/ar.c + * Handle ar(1) archives. + */ + +#include "system.h" + +#include <rpmio.h> +#include <rpmlib.h> + +#include "ar.h" +#include "fsm.h" +#include "ugid.h" + +#include "debug.h" + +/[EMAIL PROTECTED] FSM_t @*/ + +/[EMAIL PROTECTED]@*/ +int _ar_debug = 0; + +/** + * * Vector to fsmNext. + * */ +int (*_fsmNext) (void * _fsm, int nstage) + /[EMAIL PROTECTED] _fsm @*/; + +/** + * Convert string to unsigned integer (with buffer size check). + * @param str input string + * @retval endptr address of 1st character not processed + * @param base numerical conversion base + * @param num max no. of bytes to read + * @return converted integer + */ +static int strntoul(const char *str, /[EMAIL PROTECTED]@*/char **endptr, int base, int num) + /[EMAIL PROTECTED] *endptr @*/ +{ + char * buf, * end; + unsigned long ret; + + buf = alloca(num + 1); + strncpy(buf, str, num); + buf[num] = '\0'; + + ret = strtoul(buf, &end, base); + if (endptr != NULL) { + if (*end != '\0') + *endptr = ((char *)str) + (end - buf); /* XXX discards const */ + else + *endptr = ((char *)str) + strlen(buf); + } + + return ret; +} + +static ssize_t arRead(FSM_t fsm, void * buf, size_t count) + /[EMAIL PROTECTED] fsm, *buf @*/ +{ + char * t = buf; + size_t nb = 0; + +if (_ar_debug) +fprintf(stderr, " arRead(%p, %p[%u])\n", fsm, buf, (unsigned)count); + + while (count > 0) { + size_t rc; + + /* Read next ar block. */ + fsm->wrlen = count; + rc = _fsmNext(fsm, FSM_DREAD); + if (!rc && fsm->rdnb != fsm->wrlen) + rc = CPIOERR_READ_FAILED; + if (rc) return -rc; + + /* Append to buffer. */ + rc = (count > fsm->rdnb ? fsm->rdnb : count); + if (buf != fsm->wrbuf) + memcpy(t + nb, fsm->wrbuf, rc); + nb += rc; + count -= rc; + } + return nb; +} + +int arHeaderRead(void * _fsm, struct stat * st) + /[EMAIL PROTECTED] fsm, *st @*/ +{ + FSM_t fsm = _fsm; + arHeader hdr = (arHeader) fsm->wrbuf; + ssize_t rc = 0; + +if (_ar_debug) +fprintf(stderr, " arHeaderRead(%p, %p)\n", fsm, st); + +top: + rc = arRead(fsm, hdr, sizeof(*hdr)); + if (rc <= 0) return -rc; +if (_ar_debug) +fprintf(stderr, "==> %p[%u] \"%.*s\"\n", hdr, (unsigned)rc, (int)sizeof(*hdr), (char *)hdr); + rc = 0; + + /* Verify header marker. */ + if (strncmp(hdr->marker, AR_MARKER, sizeof(AR_MARKER)-1)) + return CPIOERR_BAD_MAGIC; + + st->st_size = strntoul(hdr->filesize, NULL, 10, sizeof(hdr->filesize)); + + /* GNU: on "//": Ignore long file names for now. */ + /* GNU: on "/": Skip symbols (if any) */ + if (hdr->name[0] == '/' && (hdr->name[1] == '/' || hdr->name[1] == ' ')) { + rc = arRead(fsm, fsm->wrbuf, st->st_size); + if (rc <= 0) return -rc; + goto top; + } + + /* Read file name. */ + if (fsm->path == NULL && hdr->name[0] != ' ') { + size_t nb = sizeof(hdr->name); + char t[sizeof(hdr->name)+1]; + memcpy(t, hdr->name, nb); + t[nb] = '\0'; + while (nb > 0 && t[nb-1] == ' ') + t[--nb] = '\0'; + /* GNU: trailing '/' to permit file names with trailing ' '. */ + if (nb > 0 && t[nb - 1] == '/') + t[--nb] = '\0'; + fsm->path = xstrdup(t); + } + + st->st_mtime = strntoul(hdr->mtime, NULL, 10, sizeof(hdr->mtime)); + st->st_ctime = st->st_atime = st->st_mtime; + + st->st_uid = strntoul(hdr->uid, NULL, 10, sizeof(hdr->uid)); + st->st_gid = strntoul(hdr->gid, NULL, 10, sizeof(hdr->gid)); + + st->st_mode = strntoul(hdr->mode, NULL, 8, sizeof(hdr->mode)); + + st->st_nlink = 1; + +if (_ar_debug) +fprintf(stderr, "\t %06o%3d (%4d,%4d)%12d %s\n", + (unsigned)st->st_mode, (int)st->st_nlink, + (int)st->st_uid, (int)st->st_gid, (int)st->st_size, + (fsm->path ? fsm->path : "")); + + return rc; +} + +static ssize_t arWrite(FSM_t fsm, const void *buf, size_t count) + /[EMAIL PROTECTED] fsm @*/ +{ + const char * s = buf; + size_t nb = 0; + +if (_ar_debug) +fprintf(stderr, " arWrite(%p, %p[%u])\n", fsm, buf, (unsigned)count); + + while (count > 0) { + size_t rc; + + /* XXX DWRITE uses rdnb for I/O length. */ + fsm->rdnb = count; + if (s != fsm->rdbuf) + memmove(fsm->rdbuf, s + nb, fsm->rdnb); + + rc = _fsmNext(fsm, FSM_DWRITE); + if (!rc && fsm->rdnb != fsm->wrnb) + rc = CPIOERR_WRITE_FAILED; + if (rc) return -rc; + + nb += fsm->rdnb; + count -= fsm->rdnb; + } + return nb; +} + +int arHeaderWrite(void * _fsm, struct stat * st) +{ + FSM_t fsm = _fsm; + arHeader hdr = (arHeader) fsm->rdbuf; + int rc = 0; + +if (_ar_debug) +fprintf(stderr, " arHeaderWrite(%p, %p)\n", fsm, st); + + memset(hdr, 0, sizeof(*hdr)); + + memset(hdr->name, ' ', sizeof(*hdr->name)); + strncpy(hdr->name, fsm->path, sizeof(hdr->name)); + + sprintf(hdr->mtime, "%011o", (unsigned) (st->st_mtime & 037777777777)); + sprintf(hdr->uid, "%06o", (unsigned int)(st->st_uid & 07777777)); + sprintf(hdr->gid, "%06o", (unsigned int)(st->st_gid & 07777777)); + + sprintf(hdr->mode, "%07o", (unsigned int)(st->st_mode & 00007777)); + sprintf(hdr->filesize, "%011o", (unsigned) (st->st_size & 037777777777)); + + strncpy(hdr->marker, AR_MARKER, sizeof(AR_MARKER)-1); + + rc = arWrite(fsm, hdr, sizeof(*hdr)); + if (rc < 0) return -rc; + rc = 0; + + /* XXX Padding is unnecessary but shouldn't hurt. */ + rc = _fsmNext(fsm, FSM_PAD); + + return rc; +} + +int arTrailerWrite(void * _fsm) +{ + FSM_t fsm = _fsm; + int rc = 0; + +if (_ar_debug) +fprintf(stderr, " arTrailerWrite(%p)\n", fsm); + + return rc; +} @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/ar.h ============================================================================ $ cvs diff -u -r0 -r1.1 ar.h --- /dev/null 2008-02-29 20:22:00 +0100 +++ ar.h 2008-02-29 20:25:37 +0100 @@ -0,0 +1,74 @@ +#ifndef H_AR +#define H_AR + +/** \ingroup payload + * \file rpmio/ar.h + * Structures used for ar(1) archives. + */ + +typedef struct arHeader_s * arHeader; + +/* ar(1) file constants */ +# define AR_MAGIC "!<arch>\n" +# define AR_MARKER "`\n" + +/** \ingroup payload + * ar(1) archive header. + */ +struct arHeader_s { + char name[16]; + char mtime[12]; + char uid[6]; + char gid[6]; + char mode[8]; + char filesize[10]; + char marker[2]; +}; + +/[EMAIL PROTECTED]@*/ +extern int _ar_debug; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Vector to fsmNext. + */ +extern int (*_fsmNext) (void * _fsm, int nstage) + /[EMAIL PROTECTED] _fsm @*/; + +/** + * Write ar(1) trailer. + * @retval _fsm file path and stat info + * @return 0 on success + */ +int arTrailerWrite(void * _fsm) + /[EMAIL PROTECTED] h_errno, fileSystem, internalState @*/ + /[EMAIL PROTECTED] _fsm, fileSystem, internalState @*/; + +/** + * Write ar(1) header. + * @retval _fsm file path and stat info + * @param st + * @return 0 on success + */ +int arHeaderWrite(void * _fsm, struct stat * st) + /[EMAIL PROTECTED] h_errno, fileSystem, internalState @*/ + /[EMAIL PROTECTED] _fsm, fileSystem, internalState @*/; + +/** + * Read ar(1) header. + * @retval _fsm file path and stat info + * @retval st + * @return 0 on success + */ +int arHeaderRead(void * _fsm, struct stat * st) + /[EMAIL PROTECTED] h_errno, fileSystem, internalState @*/ + /[EMAIL PROTECTED] _fsm, *st, fileSystem, internalState @*/; + +#ifdef __cplusplus +} +#endif + +#endif /* H_AR */ @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/tdeb.c ============================================================================ $ cvs diff -u -r0 -r1.1 tdeb.c --- /dev/null 2008-02-29 20:22:00 +0100 +++ tdeb.c 2008-02-29 20:25:37 +0100 @@ -0,0 +1,158 @@ +#include "system.h" + +#include "rpmio_internal.h" + +#define _RPMFI_INTERNAL +#include <rpmcli.h> +#include <rpmts.h> + +#include "cpio.h" /* XXX cpioStrerror */ +#include "ar.h" + +#include "fsm.h" /* XXX CPIO_FOO/FSM_FOO constants */ + +#define _RPMSQ_INTERNAL +#include "psm.h" + +#include <rpmfi.h> + +#include "debug.h" + +static int rpmFSM(rpmts ts, const char * fn, int mapflags) +{ + rpmpsm psm; + rpmfi fi; + const char * ioflags; + int fsmmode; + int rc = 0; + int xx; + +fprintf(stderr, "--> rpmFSM(%p, \"%s\", 0x%x)\n", ts, fn, mapflags); + + if (fn != NULL) { + + fi = rpmfiNew(ts, NULL, RPMTAG_BASENAMES, 0); + + fi->fsm->headerRead = &arHeaderRead; + fi->fsm->headerWrite = &arHeaderWrite; + fi->fsm->trailerWrite = &arTrailerWrite; + fi->fsm->blksize = 1; /* XXX AR_BLOCKSIZE? */ + + psm = rpmpsmNew(ts, NULL, fi); + + ioflags = (mapflags & CPIO_PAYLOAD_CREATE) ? "w.ufdio" : "r.ufdio"; + psm->cfd = Fopen(fn, ioflags); + if (psm->cfd != NULL && !Ferror(psm->cfd)) { +char buf[BUFSIZ]; +Fread(buf, 1, sizeof(AR_MAGIC)-1, psm->cfd); + + fi->mapflags |= mapflags; + fsmmode = (mapflags & CPIO_PAYLOAD_CREATE) ? FSM_PKGBUILD : FSM_PKGINSTALL; + rc = fsmSetup(fi->fsm, fsmmode, "ar", ts, fi, + psm->cfd, NULL, &psm->failedFile); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS), + fdstat_op(psm->cfd, FDSTAT_READ)); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST), + fdstat_op(psm->cfd, FDSTAT_DIGEST)); + xx = fsmTeardown(fi->fsm); + + xx = Fclose(psm->cfd); + + if (rc != 0 || psm->failedFile != NULL) { + const char * msg = cpioStrerror(rc); + fprintf(stderr, "%s: %s: %s\n", fn, msg, psm->failedFile); + msg = _free(msg); + } + } + + psm = rpmpsmFree(psm); + + fi = rpmfiFree(fi); + } + + return rc; +} + +#define RPMAR_LIST (1 << 0) +#define RPMAR_CREATE (1 << 1) +#define RPMAR_EXTRACT (1 << 2) + +static int armode = RPMAR_LIST; +static const char * arfn = NULL; + +static int rpmarCreate(rpmts ts, QVA_t ia, const char ** av) +{ + return rpmFSM(ts, (arfn ? arfn : "-"), CPIO_PAYLOAD_CREATE); +} + +static int rpmarExtract(rpmts ts, QVA_t ia, const char ** av) +{ + return rpmFSM(ts, (arfn ? arfn : "-"), CPIO_PAYLOAD_EXTRACT); +} + +static int rpmarList(rpmts ts, QVA_t ia, const char ** av) +{ + return rpmFSM(ts, (arfn ? arfn : "-"), CPIO_PAYLOAD_LIST); +} + +static struct poptOption optionsTable[] = { + { "create", 'c', POPT_ARG_VAL, &armode, RPMAR_CREATE, + N_("create archive.a from file arguments"), NULL }, + { "extract", 'x', POPT_ARG_VAL, &armode, RPMAR_EXTRACT, + N_("extract files from archive.a"), NULL }, + { "file", 'f', POPT_ARG_STRING, &arfn, 0, + N_("path to archive.a"), N_("FILE") }, + { "list", 't', POPT_ARG_VAL, &armode, RPMAR_LIST, + N_("list contents of archive.a"), NULL }, + + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0, + N_("Common options for all modes and executables:"), + NULL }, + + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND +}; + +int +main(int argc, char *const argv[]) +{ + poptContext optCon; + rpmts ts = NULL; + QVA_t ia = &rpmIArgs; + const char ** av = NULL; + int ec = 0; + + optCon = rpmcliInit(argc, argv, optionsTable); + if (optCon == NULL) + exit(EXIT_FAILURE); + + av = poptGetArgs(optCon); + + ts = rpmtsCreate(); + +_fsmNext = &fsmNext; +_fsm_debug = -1; +_ar_debug = 1; +rpmIncreaseVerbosity(); +rpmIncreaseVerbosity(); + switch (armode) { + default: + break; + case RPMAR_CREATE: + ec = rpmarCreate(ts, ia, av); + break; + case RPMAR_EXTRACT: + ec = rpmarExtract(ts, ia, av); + break; + case RPMAR_LIST: + ec = rpmarList(ts, ia, av); + break; + } + + ts = rpmtsFree(ts); + + optCon = rpmcliFini(optCon); + + return ec; +} @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org