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

Reply via email to