This patch might have broken something.
I've changed the cpio (and tar/ar) payload handling routines,
as part of FSM_t -> IOSM_t refactoring.
At the same time, I'm pulling out common code.
The return codes are changing from
0 is success
to a ssize_t like read(2) and write(2) that returns the number of
bytes (or -1).
So if I missed impedance matching to "0 is success", than
the number of bytes will be returned instead.
I can build and install a package, so I doubt I broke anything.
There may be some goofiness with EOF conditions for ar/tar payloads too,
but I doubt anyone is using tar/ar payloads.
Add "-vv --fsmdebug --cpiodebug" to diagnose any problems, fixing is
trivial.
73 de Jeff
On Mar 10, 2008, at 5:18 PM, Jeff Johnson wrote:
> RPM Package Manager, CVS Repository
> http://rpm5.org/cvs/
>
> ______________________________________________________________________
> ______
>
> Server: rpm5.org Name: Jeff Johnson
> Root: /v/rpm/cvs Email: jbj@rpm5.org
> Module: rpm Date: 10-Mar-2008
> 22:18:07
> Branch: HEAD Handle: 2008031021180601
>
> Modified files:
> rpm CHANGES
> rpm/lib fsm.c
> rpm/rpmio ar.c ar.h cpio.c cpio.h iosm.c tar.c tar.h
>
> Log:
> - jbj: make sure cpio/tar/ar are as similar as possible.
>
> Summary:
> Revision Changes Path
> 1.2234 +1 -0 rpm/CHANGES
> 2.166 +1 -1 rpm/lib/fsm.c
> 1.15 +15 -12 rpm/rpmio/ar.c
> 1.5 +9 -7 rpm/rpmio/ar.h
> 1.8 +190 -118 rpm/rpmio/cpio.c
> 1.5 +18 -13 rpm/rpmio/cpio.h
> 1.19 +1 -1 rpm/rpmio/iosm.c
> 1.9 +11 -9 rpm/rpmio/tar.c
> 1.4 +12 -10 rpm/rpmio/tar.h
>
> ______________________________________________________________________
> ______
>
> patch -p0 <<'@@ .'
> Index: rpm/CHANGES
>
> ======================================================================
> ======
> $ cvs diff -u -r1.2233 -r1.2234 CHANGES
> --- rpm/CHANGES 10 Mar 2008 19:18:56 -0000 1.2233
> +++ rpm/CHANGES 10 Mar 2008 21:18:06 -0000 1.2234
> @@ -1,4 +1,5 @@
> 5.0.0 -> 5.1a1:
> + - jbj: make sure cpio/tar/ar are as similar as possible.
> - jbj: keep tar.c parallel to ar.c coding conventions.
> cpio.c next.
> - jbj: clean up most rpmio gcc -W warnings.
> - jbj: clean up iosm/fsm gcc -W warnings.
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/fsm.c
>
> ======================================================================
> ======
> $ cvs diff -u -r2.165 -r2.166 fsm.c
> --- rpm/lib/fsm.c 10 Mar 2008 19:15:46 -0000 2.165
> +++ rpm/lib/fsm.c 10 Mar 2008 21:18:06 -0000 2.166
> @@ -1993,7 +1993,7 @@
> void * ptr;
> uint64_t archivePos = fdGetCpioPos(fsm->cfd);
> if (archivePos > fi->archivePos) {
> - fi->archivePos = (uint64_t) archivePos;
> + fi->archivePos = (unsigned long long) archivePos;
> ptr = rpmtsNotify(ts, fi->te, RPMCALLBACK_INST_PROGRESS,
> fi->archivePos, fi->archiveSize);
> }
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/ar.c
>
> ======================================================================
> ======
> $ cvs diff -u -r1.14 -r1.15 ar.c
> --- rpm/rpmio/ar.c 8 Mar 2008 08:45:53 -0000 1.14
> +++ rpm/rpmio/ar.c 10 Mar 2008 21:18:07 -0000 1.15
> @@ -98,7 +98,7 @@
>
> top:
> rc = arRead(iosm, hdr, sizeof(*hdr));
> - if (rc <= 0) return (int) -rc;
> + if (rc <= 0) return (int) -rc;
> if (_ar_debug)
> fprintf(stderr, "==> %p[%u] \"%.*s\"\n", hdr, (unsigned)rc, (int)
> sizeof(*hdr)-2, (char *)hdr);
> rc = 0;
> @@ -117,7 +117,7 @@
> size_t i;
>
> rc = arRead(iosm, iosm->wrbuf, st->st_size);
> - if (rc <= 0) return (int) -rc;
> + if (rc <= 0) return (int) -rc;
>
> iosm->wrbuf[rc] = '\0';
> iosm->lmtab = t = xstrdup(iosm->wrbuf);
> @@ -136,7 +136,7 @@
> /* GNU: on "/": Skip symbol table. */
> if (hdr->name[1] == ' ') {
> rc = arRead(iosm, iosm->wrbuf, st->st_size);
> - if (rc <= 0) return (int) -rc;
> + if (rc <= 0) return (int) -rc;
> goto top;
> }
> /* GNU: on "/123": Read "123" offset to substitute long member
> name. */
> @@ -169,6 +169,7 @@
> st->st_mode = strntoul(hdr->mode, NULL, 8, sizeof(hdr->mode));
>
> st->st_nlink = 1;
> + rc = 0;
>
> if (_ar_debug)
> fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n",
> @@ -214,7 +215,7 @@
> IOSM_t iosm = _iosm;
> arHeader hdr = (arHeader) iosm->rdbuf;
> size_t nb;
> - int rc = 0;
> + ssize_t rc = 0;
>
> if (_ar_debug)
> fprintf(stderr, " arHeaderWrite(%p, %p)\n", iosm, st);
> @@ -222,7 +223,8 @@
> /* At beginning of ar(1) archive, write magic and long
> member table. */
> if (fdGetCpioPos(iosm->cfd) == 0) {
> /* Write ar(1) magic. */
> - (void) arWrite(iosm, AR_MAGIC, sizeof(AR_MAGIC)-1);
> + rc = arWrite(iosm, AR_MAGIC, sizeof(AR_MAGIC)-1);
> + if (rc < 0) return (int) -rc;
> /* GNU: on "//": Write long member name string table. */
> if (iosm->lmtab != NULL) {
> memset(hdr, (int) ' ', sizeof(*hdr));
> @@ -231,14 +233,15 @@
> sprintf(hdr->filesize, "%-10d", (unsigned) (iosm->lmtablen
> & 037777777777));
> strncpy(hdr->marker, AR_MARKER, sizeof(AR_MARKER)-1);
>
> - rc = (int) arWrite(iosm, hdr, sizeof(*hdr));
> - if (rc < 0) return -rc;
> - rc = (int) arWrite(iosm, iosm->lmtab, iosm->lmtablen);
> - if (rc < 0) return -rc;
> + rc = arWrite(iosm, hdr, sizeof(*hdr));
> + if (rc < 0) return (int) -rc;
> + rc = arWrite(iosm, iosm->lmtab, iosm->lmtablen);
> + if (rc < 0) return (int) -rc;
> rc = _iosmNext(iosm, IOSM_PAD);
> - if (rc < 0) return -rc;
> + if (rc) return rc;
> }
> }
> + rc = 0;
>
> memset(hdr, (int)' ', sizeof(*hdr));
>
> @@ -272,8 +275,8 @@
> if (_ar_debug)
> fprintf(stderr, "==> %p[%u] \"%.*s\"\n", hdr, (unsigned)rc, (int)
> sizeof(*hdr), (char *)hdr);
>
> - rc = (int) arWrite(iosm, hdr, sizeof(*hdr));
> - if (rc < 0) return -rc;
> + rc = arWrite(iosm, hdr, sizeof(*hdr));
> + if (rc < 0) return (int) -rc;
> rc = 0;
>
> return rc;
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/ar.h
>
> ======================================================================
> ======
> $ cvs diff -u -r1.4 -r1.5 ar.h
> --- rpm/rpmio/ar.h 4 Mar 2008 00:30:58 -0000 1.4
> +++ rpm/rpmio/ar.h 10 Mar 2008 21:18:07 -0000 1.5
> @@ -6,6 +6,8 @@
> * Structures used for ar(1) archives.
> */
>
> +/*
> + */
> typedef struct arHeader_s * arHeader;
>
> /* ar(1) file constants */
> @@ -33,13 +35,14 @@
> #endif
>
> /**
> - * Write ar(1) trailer.
> + * Read ar(1) header.
> * @retval _iosm file path and stat info
> + * @retval st
> * @return 0 on success
> */
> -int arTrailerWrite(void * _iosm)
> +int arHeaderRead(void * _iosm, struct stat * st)
> /*@globals fileSystem, internalState @*/
> - /*@modifies _iosm, fileSystem, internalState @*/;
> + /*@modifies _iosm, *st, fileSystem, internalState @*/;
>
> /**
> * Write ar(1) header.
> @@ -52,14 +55,13 @@
> /*@modifies _iosm, fileSystem, internalState @*/;
>
> /**
> - * Read ar(1) header.
> + * Write ar(1) trailer.
> * @retval _iosm file path and stat info
> - * @retval st
> * @return 0 on success
> */
> -int arHeaderRead(void * _iosm, struct stat * st)
> +int arTrailerWrite(void * _iosm)
> /*@globals fileSystem, internalState @*/
> - /*@modifies _iosm, *st, fileSystem, internalState @*/;
> + /*@modifies _iosm, fileSystem, internalState @*/;
>
> #ifdef __cplusplus
> }
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/cpio.c
>
> ======================================================================
> ======
> $ cvs diff -u -r1.7 -r1.8 cpio.c
> --- rpm/rpmio/cpio.c 10 Mar 2008 04:46:19 -0000 1.7
> +++ rpm/rpmio/cpio.c 10 Mar 2008 21:18:07 -0000 1.8
> @@ -6,6 +6,7 @@
> #include "system.h"
>
> #include <rpmio.h>
> +#include <ugid.h>
> #include <cpio.h>
> #define _IOSM_INTERNAL
> #include <iosm.h>
> @@ -20,12 +21,13 @@
> /**
> * Convert string to unsigned integer (with buffer size check).
> * @param str input string
> - * @retval endptr address of 1st character not processed
> + * @retval *endptr 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, /*@out@*/char **endptr, int
> base, size_t num)
> +static int strntoul(const char *str, /*@null@*/ /*@out@*/char
> **endptr,
> + int base, size_t num)
> /*@modifies *endptr @*/
> /*@requires maxSet(endptr) >= 0 @*/
> {
> @@ -37,10 +39,12 @@
> buf[num] = '\0';
>
> ret = strtoul(buf, &end, base);
> - if (*end != '\0')
> - *endptr = ((char *)str) + (end - buf); /* XXX discards const */
> - else
> - *endptr = ((char *)str) + strlen(buf);
> + if (endptr != NULL) {
> + if (*end != '\0')
> + *endptr = ((char *)str) + (end - buf); /* XXX discards
> const */
> + else
> + *endptr = ((char *)str) + strlen(buf);
> + }
>
> return ret;
> }
> @@ -52,41 +56,161 @@
> sprintf(space, "%8.8lx", (unsigned long) (val)); \
> memcpy(phys, space, 8)
>
> -int cpioTrailerWrite(void * _iosm)
> +static ssize_t cpioRead(void * _iosm, void * buf, size_t count)
> + /*@globals fileSystem @*/
> + /*@modifies _iosm, *buf, fileSystem @*/
> {
> IOSM_t iosm = _iosm;
> - struct cpioCrcPhysicalHeader * hdr =
> - (struct cpioCrcPhysicalHeader *)iosm->rdbuf;
> - int rc;
> + char * t = buf;
> + size_t nb = 0;
>
> - memset(hdr, (int)'0', PHYS_HDR_SIZE);
> - memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
> - memcpy(hdr->nlink, "00000001", 8);
> - memcpy(hdr->namesize, "0000000b", 8);
> - memcpy(iosm->rdbuf + PHYS_HDR_SIZE, CPIO_TRAILER, sizeof
> (CPIO_TRAILER));
> +if (_cpio_debug)
> +fprintf(stderr, " cpioRead(%p, %p[%u])\n", iosm, buf,
> (unsigned)count);
>
> - /* XXX DWRITE uses rdnb for I/O length. */
> - iosm->rdnb = PHYS_HDR_SIZE + sizeof(CPIO_TRAILER);
> - rc = iosmNext(iosm, IOSM_DWRITE);
> + while (count > 0) {
> + size_t rc;
>
> - /*
> - * GNU cpio pads to 512 bytes here, but we don't. This may
> matter for
> - * tape device(s) and/or concatenated cpio archives. <shrug>
> - */
> - if (!rc)
> - rc = iosmNext(iosm, IOSM_PAD);
> + /* Read next cpio block. */
> + iosm->wrlen = count;
> + rc = _iosmNext(iosm, IOSM_DREAD);
> + if (!rc && iosm->rdnb != iosm->wrlen)
> + rc = IOSMERR_READ_FAILED;
> + if (rc) return -rc;
> +
> + /* Append to buffer. */
> + rc = (count > iosm->rdnb ? iosm->rdnb : count);
> + if (buf != iosm->wrbuf)
> + memcpy(t + nb, iosm->wrbuf, rc);
> + nb += rc;
> + count -= rc;
> + }
> + return nb;
> +}
> +
> +int cpioHeaderRead(void * _iosm, struct stat * st)
> +{
> + IOSM_t iosm = _iosm;
> + cpioHeader hdr = (cpioHeader) iosm->wrbuf;
> + char * t;
> + size_t nb;
> + char * end;
> + int major, minor;
> + ssize_t rc = 0;
> +
> +if (_cpio_debug)
> +fprintf(stderr, " cpioHeaderRead(%p, %p)\n", iosm, st);
> +
> + /* Read next header. */
> + rc = cpioRead(iosm, hdr, PHYS_HDR_SIZE);
> + if (rc < 0) return (int) -rc;
> +
> + /* Verify header magic. */
> + if (strncmp(CPIO_CRC_MAGIC, hdr->magic, sizeof
> (CPIO_CRC_MAGIC)-1) &&
> + strncmp(CPIO_NEWC_MAGIC, hdr->magic, sizeof(CPIO_NEWC_MAGIC)-1))
> + return IOSMERR_BAD_MAGIC;
> +
> + /* Convert header to stat(2). */
> + GET_NUM_FIELD(hdr->inode, st->st_ino);
> + GET_NUM_FIELD(hdr->mode, st->st_mode);
> + GET_NUM_FIELD(hdr->uid, st->st_uid);
> + GET_NUM_FIELD(hdr->gid, st->st_gid);
> + GET_NUM_FIELD(hdr->nlink, st->st_nlink);
> + GET_NUM_FIELD(hdr->mtime, st->st_mtime);
> + GET_NUM_FIELD(hdr->filesize, st->st_size);
> +
> + GET_NUM_FIELD(hdr->devMajor, major);
> + GET_NUM_FIELD(hdr->devMinor, minor);
> + /*@-shiftimplementation@*/
> + st->st_dev = Makedev(major, minor);
> + /*@=shiftimplementation@*/
> +
> + GET_NUM_FIELD(hdr->rdevMajor, major);
> + GET_NUM_FIELD(hdr->rdevMinor, minor);
> + /*@-shiftimplementation@*/
> + st->st_rdev = Makedev(major, minor);
> + /*@=shiftimplementation@*/
> +
> + GET_NUM_FIELD(hdr->namesize, nb);
> + if (nb >= iosm->wrsize)
> + return IOSMERR_BAD_HEADER;
> +
> + /* Read file name. */
> + { t = xmalloc(nb + 1);
> + rc = cpioRead(iosm, t, nb);
> + if (rc < 0) {
> + t = _free(t);
> + iosm->path = NULL;
> + rc = IOSMERR_BAD_HEADER;
> + return (int) rc;
> + }
> + t[nb] = '\0';
> + iosm->path = t;
> + }
> +
> + /* Read link name. */
> + if (S_ISLNK(st->st_mode)) {
> + rc = _iosmNext(iosm, IOSM_POS);
> + if (rc) return (int) rc;
> + nb = (size_t) st->st_size;
> + rc = cpioRead(iosm, t, nb);
> + if (rc < 0) {
> + t = _free(t);
> + iosm->lpath = NULL;
> + return (int) -rc;
> + }
> + t[nb] = '\0';
> + iosm->lpath = t;
> + }
> +
> + rc = 0;
> +
> +if (_cpio_debug)
> +fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n\t-> %s\n",
> + (unsigned)st->st_mode, (int)st->st_nlink,
> + (int)st->st_uid, (int)st->st_gid, (unsigned long)
> st->st_size,
> + (iosm->path ? iosm->path : ""), (iosm->lpath ?
> iosm->lpath : ""));
> +
> + return (int) rc;
> +}
> +
> +static ssize_t cpioWrite(void * _iosm, const void *buf, size_t
> count)
> + /*@globals fileSystem @*/
> + /*@modifies _iosm, fileSystem @*/
> +{
> + IOSM_t iosm = _iosm;
> + const char * s = buf;
> + size_t nb = 0;
> +
> +if (_cpio_debug)
> +fprintf(stderr, " cpioWrite(%p, %p[%u])\n", iosm, buf,
> (unsigned)count);
> +
> + while (count > 0) {
> + size_t rc;
> +
> + /* XXX DWRITE uses rdnb for I/O length. */
> + iosm->rdnb = count;
> + if (s != iosm->rdbuf)
> + memmove(iosm->rdbuf, s + nb, iosm->rdnb);
>
> - return rc;
> + rc = _iosmNext(iosm, IOSM_DWRITE);
> + if (!rc && iosm->rdnb != iosm->wrnb)
> + rc = IOSMERR_WRITE_FAILED;
> + if (rc) return -rc;
> +
> + nb += iosm->rdnb;
> + count -= iosm->rdnb;
> + }
> + return nb;
> }
>
> int cpioHeaderWrite(void * _iosm, struct stat * st)
> {
> IOSM_t iosm = _iosm;
> - struct cpioCrcPhysicalHeader * hdr = (struct
> cpioCrcPhysicalHeader *)iosm->rdbuf;
> + cpioHeader hdr = (cpioHeader) iosm->rdbuf;
> char field[64];
> - size_t len;
> + size_t nb;
> dev_t dev;
> - int rc = 0;
> + ssize_t rc = 0;
>
> if (_cpio_debug)
> fprintf(stderr, " cpioHeaderWrite(%p, %p)\n", iosm, st);
> @@ -105,111 +229,59 @@
> dev = major((unsigned)st->st_rdev); SET_NUM_FIELD(hdr-
> >rdevMajor, dev, field);
> dev = minor((unsigned)st->st_rdev); SET_NUM_FIELD(hdr-
> >rdevMinor, dev, field);
>
> - len = strlen(iosm->path) + 1; SET_NUM_FIELD(hdr->namesize,
> len, field);
> + nb = strlen(iosm->path) + 1; SET_NUM_FIELD(hdr->namesize,
> nb, field);
> memcpy(hdr->checksum, "00000000", 8);
> - memcpy(iosm->rdbuf + PHYS_HDR_SIZE, iosm->path, len);
>
> - /* XXX DWRITE uses rdnb for I/O length. */
> - iosm->rdnb = PHYS_HDR_SIZE + len;
> - rc = iosmNext(iosm, IOSM_DWRITE);
> - if (!rc && iosm->rdnb != iosm->wrnb)
> - rc = IOSMERR_WRITE_FAILED;
> - if (!rc)
> - rc = iosmNext(iosm, IOSM_PAD);
> + /* XXX Coalesce hdr+name into single I/O. */
> + memcpy(iosm->rdbuf + PHYS_HDR_SIZE, iosm->path, nb);
> + nb += PHYS_HDR_SIZE;
> + rc = cpioWrite(iosm, hdr, nb);
> + if (rc < 0) return (int) -rc;
>
> - if (!rc && S_ISLNK(st->st_mode)) {
> + if (S_ISLNK(st->st_mode)) {
> assert(iosm->lpath != NULL);
> - iosm->rdnb = strlen(iosm->lpath);
> - memcpy(iosm->rdbuf, iosm->lpath, iosm->rdnb);
> - rc = iosmNext(iosm, IOSM_DWRITE);
> - if (!rc && iosm->rdnb != iosm->wrnb)
> - rc = IOSMERR_WRITE_FAILED;
> - if (!rc)
> - rc = iosmNext(iosm, IOSM_PAD);
> + rc = _iosmNext(iosm, IOSM_PAD);
> + if (rc) return (int) rc;
> +
> + nb = strlen(iosm->lpath);
> + rc = cpioWrite(iosm, iosm->lpath, nb);
> + if (rc < 0) return (int) -rc;
> }
>
> - return rc;
> + rc = _iosmNext(iosm, IOSM_PAD);
> +
> + return (int) rc;
> }
>
> -int cpioHeaderRead(void * _iosm, struct stat * st)
> +int cpioTrailerWrite(void * _iosm)
> {
> IOSM_t iosm = _iosm;
> - struct cpioCrcPhysicalHeader hdr;
> - size_t nameSize;
> - char * end;
> - int major, minor;
> - int rc = 0;
> + cpioHeader hdr = (cpioHeader) iosm->rdbuf;
> + size_t nb;
> + ssize_t rc = 0;
>
> if (_cpio_debug)
> -fprintf(stderr, " cpioHeaderRead(%p, %p)\n", iosm, st);
> -
> - iosm->wrlen = PHYS_HDR_SIZE;
> - rc = iosmNext(iosm, IOSM_DREAD);
> - if (!rc && iosm->rdnb != iosm->wrlen)
> - rc = IOSMERR_READ_FAILED;
> - if (rc) return rc;
> - memcpy(&hdr, iosm->wrbuf, iosm->rdnb);
> -
> - if (strncmp(CPIO_CRC_MAGIC, hdr.magic, sizeof
> (CPIO_CRC_MAGIC)-1) &&
> - strncmp(CPIO_NEWC_MAGIC, hdr.magic, sizeof(CPIO_NEWC_MAGIC)-1))
> - return IOSMERR_BAD_MAGIC;
> -
> - GET_NUM_FIELD(hdr.inode, st->st_ino);
> - GET_NUM_FIELD(hdr.mode, st->st_mode);
> - GET_NUM_FIELD(hdr.uid, st->st_uid);
> - GET_NUM_FIELD(hdr.gid, st->st_gid);
> - GET_NUM_FIELD(hdr.nlink, st->st_nlink);
> - GET_NUM_FIELD(hdr.mtime, st->st_mtime);
> - GET_NUM_FIELD(hdr.filesize, st->st_size);
> -
> - GET_NUM_FIELD(hdr.devMajor, major);
> - GET_NUM_FIELD(hdr.devMinor, minor);
> - /*@-shiftimplementation@*/
> - st->st_dev = Makedev(major, minor);
> - /*@=shiftimplementation@*/
> -
> - GET_NUM_FIELD(hdr.rdevMajor, major);
> - GET_NUM_FIELD(hdr.rdevMinor, minor);
> - /*@-shiftimplementation@*/
> - st->st_rdev = Makedev(major, minor);
> - /*@=shiftimplementation@*/
> +fprintf(stderr, " cpioTrailerWrite(%p)\n", iosm);
>
> - GET_NUM_FIELD(hdr.namesize, nameSize);
> - if (nameSize >= iosm->wrsize)
> - return IOSMERR_BAD_HEADER;
> + memset(hdr, (int)'0', PHYS_HDR_SIZE);
> + memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
> + memcpy(hdr->nlink, "00000001", 8);
> + memcpy(hdr->namesize, "0000000b", 8);
>
> - { char * t = xmalloc(nameSize + 1);
> - iosm->wrlen = nameSize;
> - rc = iosmNext(iosm, IOSM_DREAD);
> - if (!rc && iosm->rdnb != iosm->wrlen)
> - rc = IOSMERR_BAD_HEADER;
> - if (rc) {
> - t = _free(t);
> - iosm->path = NULL;
> - return rc;
> - }
> - memcpy(t, iosm->wrbuf, iosm->rdnb);
> - t[nameSize] = '\0';
> - iosm->path = t;
> - }
> + nb = sizeof(CPIO_TRAILER);
> + /* XXX Coalesce hdr+trailer into single I/O. */
> + memcpy(iosm->rdbuf + PHYS_HDR_SIZE, CPIO_TRAILER, nb);
> + nb += PHYS_HDR_SIZE;
>
> - if (S_ISLNK(st->st_mode)) {
> - rc = iosmNext(iosm, IOSM_POS);
> - if (rc) return rc;
> - iosm->wrlen = st->st_size;
> - rc = iosmNext(iosm, IOSM_DREAD);
> - if (!rc && iosm->rdnb != iosm->wrlen)
> - rc = IOSMERR_READ_FAILED;
> - if (rc) return rc;
> - iosm->wrbuf[st->st_size] = '\0';
> - iosm->lpath = xstrdup(iosm->wrbuf);
> - }
> + rc = cpioWrite(iosm, hdr, nb);
> + if (rc < 0) return (int) -rc;
>
> -if (_cpio_debug)
> -fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n\t-> %s\n",
> - (unsigned)st->st_mode, (int)st->st_nlink,
> - (int)st->st_uid, (int)st->st_gid, (unsigned long)
> st->st_size,
> - (iosm->path ? iosm->path : ""), (iosm->lpath ?
> iosm->lpath : ""));
> + /*
> + * GNU cpio pads to 512 bytes here, but we don't. This may
> matter for
> + * tape device(s) and/or concatenated cpio archives. <shrug>
> + */
> + rc = _iosmNext(iosm, IOSM_PAD);
>
> - return rc;
> + return (int) rc;
> }
> +
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/cpio.h
>
> ======================================================================
> ======
> $ cvs diff -u -r1.4 -r1.5 cpio.h
> --- rpm/rpmio/cpio.h 4 Mar 2008 00:30:58 -0000 1.4
> +++ rpm/rpmio/cpio.h 10 Mar 2008 21:18:07 -0000 1.5
> @@ -6,14 +6,21 @@
> * Structures used for cpio(1) archives.
> */
>
> +/**
> + */
> +typedef struct cpioCrcPhysicalHeader_s * cpioHeader;
> +
> +/* Cpio file constants */
> #define CPIO_NEWC_MAGIC "070701"
> #define CPIO_CRC_MAGIC "070702"
> #define CPIO_TRAILER "TRAILER!!!"
>
> +#define PHYS_HDR_SIZE 110 /* Don't depend on sizeof(struct) */
> +
> /** \ingroup payload
> * Cpio archive header information.
> */
> -struct cpioCrcPhysicalHeader {
> +struct cpioCrcPhysicalHeader_s {
> char magic[6];
> char inode[8];
> char mode[8];
> @@ -30,8 +37,6 @@
> char checksum[8]; /* ignored !! */
> };
>
> -#define PHYS_HDR_SIZE 110 /* Don't depend on sizeof(struct) */
> -
> /*@unchecked@*/
> extern int _cpio_debug;
>
> @@ -40,13 +45,14 @@
> #endif
>
> /**
> - * Write cpio trailer.
> + * Read cpio header.
> * @retval _iosm file path and stat info
> + * @retval st
> * @return 0 on success
> */
> -int cpioTrailerWrite(void * _iosm)
> - /*@globals h_errno, fileSystem, internalState @*/
> - /*@modifies _iosm, fileSystem, internalState @*/;
> +int cpioHeaderRead(void * _iosm, struct stat * st)
> + /*@globals fileSystem, internalState @*/
> + /*@modifies _iosm, *st, fileSystem, internalState @*/;
>
> /**
> * Write cpio header.
> @@ -55,18 +61,17 @@
> * @return 0 on success
> */
> int cpioHeaderWrite(void * _iosm, struct stat * st)
> - /*@globals h_errno, fileSystem, internalState @*/
> + /*@globals fileSystem, internalState @*/
> /*@modifies _iosm, fileSystem, internalState @*/;
>
> /**
> - * Read cpio header.
> + * Write cpio trailer.
> * @retval _iosm file path and stat info
> - * @retval st
> * @return 0 on success
> */
> -int cpioHeaderRead(void * _iosm, struct stat * st)
> - /*@globals h_errno, fileSystem, internalState @*/
> - /*@modifies _iosm, *st, fileSystem, internalState @*/;
> +int cpioTrailerWrite(void * _iosm)
> + /*@globals fileSystem, internalState @*/
> + /*@modifies _iosm, fileSystem, internalState @*/;
>
> #ifdef __cplusplus
> }
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/iosm.c
>
> ======================================================================
> ======
> $ cvs diff -u -r1.18 -r1.19 iosm.c
> --- rpm/rpmio/iosm.c 10 Mar 2008 19:15:46 -0000 1.18
> +++ rpm/rpmio/iosm.c 10 Mar 2008 21:18:07 -0000 1.19
> @@ -2074,7 +2074,7 @@
> rpmfi fi = iosmGetFi(iosm);
> uint64_t archivePos = fdGetCpioPos(iosm->cfd);
> if (archivePos > fi->archivePos) {
> - fi->archivePos = (uint64_t) archivePos;
> + fi->archivePos = (unsigned long long) archivePos;
> #if defined(_USE_RPMTS)
> (void) rpmtsNotify(iosmGetTs(iosm), fi-
> >te,RPMCALLBACK_INST_PROGRESS,
> fi->archivePos, fi->archiveSize);
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/tar.c
>
> ======================================================================
> ======
> $ cvs diff -u -r1.8 -r1.9 tar.c
> --- rpm/rpmio/tar.c 10 Mar 2008 19:18:57 -0000 1.8
> +++ rpm/rpmio/tar.c 10 Mar 2008 21:18:07 -0000 1.9
> @@ -129,7 +129,7 @@
>
> top:
> do {
> - /* Read next tar block. */
> + /* Read next header. */
> rc = tarRead(_iosm, hdr, TAR_BLOCK_SIZE);
> if (rc < 0) return (int) -rc;
>
> @@ -167,6 +167,7 @@
> if (strncmp(hdr->magic, TAR_MAGIC, sizeof(TAR_MAGIC)-1))
> return IOSMERR_BAD_MAGIC;
>
> + /* Convert header to stat(2). */
> st->st_size = strntoul(hdr->filesize, NULL, 8, sizeof(hdr-
> >filesize));
>
> st->st_nlink = 1;
> @@ -260,6 +261,8 @@
> iosm->lpath = t;
> }
>
> + rc = 0;
> +
> if (_tar_debug)
> fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n\t-> %s\n",
> (unsigned)st->st_mode, (int)st->st_nlink,
> @@ -402,14 +405,14 @@
> if (nb > sizeof(hdr->name)) {
> memset(hdr, 0, sizeof(*hdr));
> strcpy(hdr->linkname, llname);
> - sprintf(hdr->mode, "%07o", 0);
> - sprintf(hdr->uid, "%07o", 0);
> - sprintf(hdr->gid, "%07o", 0);
> + sprintf(hdr->mode, "%07o", 0);
> + sprintf(hdr->uid, "%07o", 0);
> + sprintf(hdr->gid, "%07o", 0);
> sprintf(hdr->filesize, "%011o", (unsigned) (nb &
> 037777777777));
> - sprintf(hdr->mtime, "%011o", 0);
> + sprintf(hdr->mtime, "%011o", 0);
> hdr->typeflag = 'K';
> - strncpy(hdr->uname, "root", sizeof(hdr->uname));
> - strncpy(hdr->gname, "root", sizeof(hdr->gname));
> + strncpy(hdr->uname, "root", sizeof(hdr->uname));
> + strncpy(hdr->gname, "root", sizeof(hdr->gname));
> rc = tarHeaderWriteBlock(iosm, st, hdr);
> if (rc < 0) return (int) -rc;
> rc = tarHeaderWriteName(iosm, iosm->lpath);
> @@ -482,8 +485,7 @@
>
> /* Pad up to 20 blocks (10Kb) of zeroes. */
> iosm->blksize *= 20;
> - if (!rc)
> - rc = _iosmNext(iosm, IOSM_PAD);
> + rc = _iosmNext(iosm, IOSM_PAD);
> iosm->blksize /= 20;
>
> return rc;
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/tar.h
>
> ======================================================================
> ======
> $ cvs diff -u -r1.3 -r1.4 tar.h
> --- rpm/rpmio/tar.h 4 Mar 2008 00:30:58 -0000 1.3
> +++ rpm/rpmio/tar.h 10 Mar 2008 21:18:07 -0000 1.4
> @@ -6,9 +6,11 @@
> * Structures used for tar(1) archives.
> */
>
> +/**
> + */
> typedef struct tarHeader_s * tarHeader;
>
> -/* Tar file constants */
> +/* Tar file constants */
> # define TAR_MAGIC "ustar" /* ustar and a null */
> # define TAR_VERSION " " /* Be compatable with GNU tar
> format */
>
> @@ -50,13 +52,14 @@
> #endif
>
> /**
> - * Write cpio trailer to payload.
> - * @retval _fsm file path and stat info
> + * Read tar header from payload.
> + * @retval _iosm file path and stat info
> + * @retval st
> * @return 0 on success
> */
> -int tarTrailerWrite(void * _iosm)
> +int tarHeaderRead(void * _iosm, struct stat * st)
> /*@globals fileSystem, internalState @*/
> - /*@modifies _iosm, fileSystem, internalState @*/;
> + /*@modifies _iosm, *st, fileSystem, internalState @*/;
>
> /**
> * Write tar header to payload.
> @@ -69,14 +72,13 @@
> /*@modifies _iosm, fileSystem, internalState @*/;
>
> /**
> - * Read tar header from payload.
> - * @retval _iosm file path and stat info
> - * @retval st
> + * Write cpio trailer to payload.
> + * @retval _fsm file path and stat info
> * @return 0 on success
> */
> -int tarHeaderRead(void * _iosm, struct stat * st)
> +int tarTrailerWrite(void * _iosm)
> /*@globals fileSystem, internalState @*/
> - /*@modifies _iosm, *st, fileSystem, internalState @*/;
> + /*@modifies _iosm, fileSystem, internalState @*/;
>
> #ifdef __cplusplus
> }
> @@ .
> ______________________________________________________________________
> RPM Package Manager http://rpm5.org
> CVS Sources Repository rpm-cvs@rpm5.org
Received on Mon Mar 10 22:25:35 2008