summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/cpio.c255
-rw-r--r--lib/cpio.h30
-rw-r--r--lib/fsm.c198
-rw-r--r--lib/fsm.h15
-rw-r--r--lib/psm.c6
5 files changed, 302 insertions, 202 deletions
diff --git a/lib/cpio.c b/lib/cpio.c
index bfb2fbbd3..38321a1af 100644
--- a/lib/cpio.c
+++ b/lib/cpio.c
@@ -27,6 +27,32 @@
#include "debug.h"
+struct rpmcpio_s {
+ FD_t fd;
+ char mode;
+ off_t offset;
+ off_t fileend;
+};
+
+rpmcpio_t rpmcpioOpen(FD_t fd, char mode)
+{
+ if ((mode & O_ACCMODE) != O_RDONLY &&
+ (mode & O_ACCMODE) != O_WRONLY)
+ return NULL;
+
+ rpmcpio_t cpio = xcalloc(1, sizeof(*cpio));
+ cpio->fd = fd;
+ cpio->mode = mode;
+ cpio->offset = 0;
+ return cpio;
+}
+
+off_t rpmcpioTell(rpmcpio_t cpio)
+{
+ return cpio->offset;
+}
+
+
/**
* Convert string to unsigned integer (with buffer size check).
* @param str input string
@@ -52,6 +78,39 @@ static unsigned long strntoul(const char *str,char **endptr, int base, size_t nu
return ret;
}
+
+static int rpmcpioWritePad(rpmcpio_t cpio, ssize_t modulo)
+{
+ char buf[modulo];
+ ssize_t left, writen;
+ memset(buf, 0, modulo);
+ left = (modulo - ((cpio->offset) % modulo)) % modulo;
+ if (left <= 0)
+ return 0;
+ writen = Fwrite(&buf, left, 1, cpio->fd);
+ if (writen != left) {
+ return CPIOERR_WRITE_FAILED;
+ }
+ cpio->offset += writen;
+ return 0;
+}
+
+static int rpmcpioReadPad(rpmcpio_t cpio)
+{
+ ssize_t modulo = 4;
+ char buf[4];
+ ssize_t left, read;
+ left = (modulo - (cpio->offset % modulo)) % modulo;
+ if (left <= 0)
+ return 0;
+ read = Fread(&buf, left, 1, cpio->fd);
+ cpio->offset += read;
+ if (read != left) {
+ return CPIOERR_READ_FAILED;
+ }
+ return 0;
+}
+
#define GET_NUM_FIELD(phys, log) \
\
log = strntoul(phys, &end, 16, sizeof(phys)); \
@@ -62,40 +121,67 @@ static unsigned long strntoul(const char *str,char **endptr, int base, size_t nu
\
memcpy(phys, space, 8) \
-int cpioTrailerWrite(FSM_t fsm)
+static int rpmcpioTrailerWrite(rpmcpio_t cpio)
{
- struct cpioCrcPhysicalHeader * hdr =
- (struct cpioCrcPhysicalHeader *)fsm->rdbuf;
+ struct cpioCrcPhysicalHeader hdr;
int rc;
+ size_t writen;
- memset(hdr, '0', PHYS_HDR_SIZE);
- memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
- memcpy(hdr->nlink, "00000001", 8);
- memcpy(hdr->namesize, "0000000b", 8);
- memcpy(fsm->rdbuf + PHYS_HDR_SIZE, CPIO_TRAILER, sizeof(CPIO_TRAILER));
+ if (cpio->fileend != cpio->offset) {
+ return CPIOERR_WRITE_FAILED;
+ }
- /* XXX DWRITE uses rdnb for I/O length. */
- fsm->rdnb = PHYS_HDR_SIZE + sizeof(CPIO_TRAILER);
- rc = fsmNext(fsm, FSM_DWRITE);
+ rc = rpmcpioWritePad(cpio, 4);
+ if (rc)
+ return rc;
+
+ memset(&hdr, '0', PHYS_HDR_SIZE);
+ memcpy(&hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
+ memcpy(&hdr.nlink, "00000001", 8);
+ memcpy(&hdr.namesize, "0000000b", 8);
+ writen = Fwrite(&hdr, PHYS_HDR_SIZE, 1, cpio->fd);
+ cpio->offset += writen;
+ if (writen != PHYS_HDR_SIZE) {
+ return CPIOERR_WRITE_FAILED;
+ }
+ writen = Fwrite(&CPIO_TRAILER, sizeof(CPIO_TRAILER), 1, cpio->fd);
+ cpio->offset += writen;
+ if (writen != sizeof(CPIO_TRAILER)) {
+ return CPIOERR_WRITE_FAILED;
+ }
/*
- * GNU cpio pads to 512 bytes here, but we don't. This may matter for
- * tape device(s) and/or concatenated cpio archives. <shrug>
+ * XXX GNU cpio pads to 512 bytes. This may matter for
+ * tape device(s) and/or concatenated cpio archives.
*/
- if (!rc)
- rc = fsmNext(fsm, FSM_PAD);
+
+ rc = rpmcpioWritePad(cpio, 4);
return rc;
}
-int cpioHeaderWrite(FSM_t fsm, struct stat * st)
+int rpmcpioHeaderWrite(rpmcpio_t cpio, char * path, struct stat * st)
{
- struct cpioCrcPhysicalHeader * hdr = (struct cpioCrcPhysicalHeader *)fsm->rdbuf;
+ struct cpioCrcPhysicalHeader hdr_s;
+ struct cpioCrcPhysicalHeader * hdr = &hdr_s;
char field[64];
- size_t len;
+ size_t len, writen;
dev_t dev;
int rc = 0;
+ if ((cpio->mode & O_ACCMODE) != O_WRONLY) {
+ return CPIOERR_WRITE_FAILED;
+ }
+
+ if (cpio->fileend != cpio->offset) {
+ return CPIOERR_WRITE_FAILED;
+ }
+
+ rc = rpmcpioWritePad(cpio, 4);
+ if (rc) {
+ return rc;
+ }
+
memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
SET_NUM_FIELD(hdr->inode, st->st_ino, field);
SET_NUM_FIELD(hdr->mode, st->st_mode, field);
@@ -110,40 +196,88 @@ int cpioHeaderWrite(FSM_t fsm, struct stat * st)
dev = major(st->st_rdev); SET_NUM_FIELD(hdr->rdevMajor, dev, field);
dev = minor(st->st_rdev); SET_NUM_FIELD(hdr->rdevMinor, dev, field);
- len = strlen(fsm->path) + 1; SET_NUM_FIELD(hdr->namesize, len, field);
+ len = strlen(path) + 1;
+ SET_NUM_FIELD(hdr->namesize, len, field);
+
memcpy(hdr->checksum, "00000000", 8);
- memcpy(fsm->rdbuf + PHYS_HDR_SIZE, fsm->path, len);
-
- /* XXX DWRITE uses rdnb for I/O length. */
- fsm->rdnb = PHYS_HDR_SIZE + len;
- rc = fsmNext(fsm, FSM_DWRITE);
- if (!rc && fsm->rdnb != fsm->wrnb)
- rc = CPIOERR_WRITE_FAILED;
- if (!rc)
- rc = fsmNext(fsm, FSM_PAD);
+
+ writen = Fwrite(hdr, PHYS_HDR_SIZE, 1, cpio->fd);
+ cpio->offset += writen;
+ if (writen != PHYS_HDR_SIZE) {
+ return CPIOERR_WRITE_FAILED;
+ }
+
+ writen = Fwrite(path, len, 1, cpio->fd);
+ cpio->offset += writen;
+ if (writen != len) {
+ return CPIOERR_WRITE_FAILED;
+ }
+
+ rc = rpmcpioWritePad(cpio, 4);
+
+ cpio->fileend = cpio->offset + st->st_size;
+
return rc;
}
-int cpioHeaderRead(FSM_t fsm, struct stat * st)
+ssize_t rpmcpioWrite(rpmcpio_t cpio, void * buf, size_t size)
+{
+ size_t writen, left;
+
+ if ((cpio->mode & O_ACCMODE) != O_WRONLY) {
+ return CPIOERR_WRITE_FAILED;
+ }
+
+ // Do not write beyond file length
+ left = cpio->fileend - cpio->offset;
+ size = size > left ? left : size;
+ writen = Fwrite(buf, size, 1, cpio->fd);
+ cpio->offset += writen;
+ return writen;
+}
+
+
+int rpmcpioHeaderRead(rpmcpio_t cpio, char ** path, struct stat * st)
{
struct cpioCrcPhysicalHeader hdr;
int nameSize;
char * end;
unsigned int major, minor;
int rc = 0;
- char * path = NULL;
+ ssize_t read;
- fsm->wrlen = PHYS_HDR_SIZE;
- rc = fsmNext(fsm, FSM_DREAD);
- if (!rc && fsm->rdnb != fsm->wrlen)
- rc = CPIOERR_READ_FAILED;
+ if ((cpio->mode & O_ACCMODE) != O_RDONLY) {
+ return CPIOERR_READ_FAILED;
+ }
+
+ /* Move to next file */
+ if (cpio->fileend != cpio->offset) {
+ //if (Fseek(cpio->fd, cpio->fileend-cpio->offset, SEEK_CUR))
+ {
+ /* XXX try using Fseek() - which is currently broken */
+ char buf[8*BUFSIZ];
+ while (cpio->fileend != cpio->offset) {
+ read = cpio->fileend - cpio->offset > 8*BUFSIZ ? 8*BUFSIZ : cpio->fileend - cpio->offset;
+ if (rpmcpioRead(cpio, &buf, read) != read) {
+ return CPIOERR_READ_FAILED;
+ }
+ }
+ //} else { /* seek worked */
+ //cpio->offset = cpio->fileend;
+ }
+ }
+ rc = rpmcpioReadPad(cpio);
if (rc) return rc;
- memcpy(&hdr, fsm->wrbuf, fsm->rdnb);
+
+ read = Fread(&hdr, PHYS_HDR_SIZE, 1, cpio->fd);
+ cpio->offset += read;
+ if (read != PHYS_HDR_SIZE)
+ return CPIOERR_READ_FAILED;
if (strncmp(CPIO_CRC_MAGIC, hdr.magic, sizeof(CPIO_CRC_MAGIC)-1) &&
- strncmp(CPIO_NEWC_MAGIC, hdr.magic, sizeof(CPIO_NEWC_MAGIC)-1))
+ strncmp(CPIO_NEWC_MAGIC, hdr.magic, sizeof(CPIO_NEWC_MAGIC)-1)) {
return CPIOERR_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);
@@ -161,24 +295,47 @@ int cpioHeaderRead(FSM_t fsm, struct stat * st)
st->st_rdev = makedev(major, minor);
GET_NUM_FIELD(hdr.namesize, nameSize);
- if (nameSize >= fsm->wrsize)
- return CPIOERR_BAD_HEADER;
- fsm->wrlen = nameSize;
- rc = fsmNext(fsm, FSM_DREAD);
- if (!rc && fsm->rdnb != fsm->wrlen)
- rc = CPIOERR_BAD_HEADER;
+ *path = xmalloc(nameSize + 1);
+ read = Fread(*path, nameSize, 1, cpio->fd);
+ (*path)[nameSize] = '\0';
+ cpio->offset += read;
+ if (read != nameSize ) {
+ return CPIOERR_BAD_HEADER;
+ }
+
+ rc = rpmcpioReadPad(cpio);
+ cpio->fileend = cpio->offset + st->st_size;
- if (!rc) {
- path = xmalloc(nameSize + 1);
- memcpy(path, fsm->wrbuf, fsm->rdnb);
- path[nameSize] = '\0';
+ return rc;
+}
+
+ssize_t rpmcpioRead(rpmcpio_t cpio, void * buf, size_t size)
+{
+ size_t read, left;
+
+ if ((cpio->mode & O_ACCMODE) != O_RDONLY) {
+ return CPIOERR_READ_FAILED;
+ }
+
+ left = cpio->fileend - cpio->offset;
+ size = size > left ? left : size;
+ read = Fread(buf, size, 1, cpio->fd);
+ cpio->offset += read;
+ return read;
+}
+
+int rpmcpioClose(rpmcpio_t cpio)
+{
+ int rc = 0;
+ if ((cpio->mode & O_ACCMODE) == O_WRONLY) {
+ rc = rpmcpioTrailerWrite(cpio);
}
- fsm->path = path;
+ _free(cpio);
return rc;
}
-const char * cpioStrerror(int rc)
+const char * rpmcpioStrerror(int rc)
{
static char msg[256];
const char *s;
diff --git a/lib/cpio.h b/lib/cpio.h
index 945318429..206f4b804 100644
--- a/lib/cpio.h
+++ b/lib/cpio.h
@@ -12,8 +12,6 @@
*
*/
-#include "lib/fsm.h"
-
/** \ingroup payload
* @note CPIO_CHECK_ERRNO bit is set only if errno is valid.
*/
@@ -88,17 +86,23 @@ struct cpioCrcPhysicalHeader {
#define PHYS_HDR_SIZE 110 /* Don't depend on sizeof(struct) */
+typedef struct rpmcpio_s * rpmcpio_t;
+
#ifdef __cplusplus
extern "C" {
#endif
/**
- * Write cpio trailer.
- * @retval fsm file path and stat info
- * @return 0 on success
- */
-RPM_GNUC_INTERNAL
-int cpioTrailerWrite(FSM_t fsm);
+ * Create CPIO file object
+ * @param fd file
+ * @param mode XXX
+ * @return CPIO object
+ **/
+rpmcpio_t rpmcpioOpen(FD_t fd, char mode);
+
+int rpmcpioClose(rpmcpio_t cpio);
+
+off_t rpmcpioTell(rpmcpio_t cpio);
/**
* Write cpio header.
@@ -107,7 +111,9 @@ int cpioTrailerWrite(FSM_t fsm);
* @return 0 on success
*/
RPM_GNUC_INTERNAL
-int cpioHeaderWrite(FSM_t fsm, struct stat * st);
+int rpmcpioHeaderWrite(rpmcpio_t cpio, char * path, struct stat * st);
+
+ssize_t rpmcpioWrite(rpmcpio_t cpio, void * buf, size_t size);
/**
* Read cpio header.
@@ -116,7 +122,9 @@ int cpioHeaderWrite(FSM_t fsm, struct stat * st);
* @return 0 on success
*/
RPM_GNUC_INTERNAL
-int cpioHeaderRead(FSM_t fsm, struct stat * st);
+int rpmcpioHeaderRead(rpmcpio_t cpio, char ** path, struct stat * st);
+
+ssize_t rpmcpioRead(rpmcpio_t cpio, void * buf, size_t size);
/** \ingroup payload
* Return formatted error message on payload handling failure.
@@ -124,7 +132,7 @@ int cpioHeaderRead(FSM_t fsm, struct stat * st);
* @return formatted error string
*/
/* XXX should be RPM_GNUC_INTERNAL too but build/pack.c uses */
-const char * cpioStrerror(int rc);
+const char * rpmcpioStrerror(int rc);
#ifdef __cplusplus
}
diff --git a/lib/fsm.c b/lib/fsm.c
index 5c139146c..4972b3117 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -559,14 +559,11 @@ static int fsmCreate(FSM_t fsm)
int rc = 0;
fsm->path = _free(fsm->path);
- fsm->rdsize = fsm->wrsize = 0;
- fsm->rdbuf = fsm->rdb = _free(fsm->rdb);
- fsm->wrbuf = fsm->wrb = _free(fsm->wrb);
+ fsm->buf = _free(fsm->buf);
+ fsm->bufsize = 0;
if (fsm->goal == FSM_PKGINSTALL || fsm->goal == FSM_PKGBUILD) {
- fsm->rdsize = 8 * BUFSIZ;
- fsm->rdbuf = fsm->rdb = xmalloc(fsm->rdsize);
- fsm->wrsize = 8 * BUFSIZ;
- fsm->wrbuf = fsm->wrb = xmalloc(fsm->wrsize);
+ fsm->bufsize = 8 * BUFSIZ;
+ fsm->buf = xmalloc(fsm->bufsize);
}
fsm->ix = -1;
@@ -595,7 +592,6 @@ static int fsmSetup(FSM_t fsm, fileStage goal,
if (cfd != NULL) {
fsm->cfd = fdLink(cfd);
}
- fsm->cpioPos = 0;
fsm->iter = mapInitIterator(ts, te, fi);
fsm->psm = psm;
fsm->sehandle = rpmtsSELabelHandle(ts);
@@ -606,10 +602,12 @@ static int fsmSetup(FSM_t fsm, fileStage goal,
if (isSrc) {
fsm->mapFlags |= CPIO_FOLLOW_SYMLINKS;
}
+ fsm->archive = rpmcpioOpen(cfd, O_WRONLY);
} else {
if (!isSrc) {
fsm->mapFlags |= CPIO_SBIT_CHECK;
}
+ fsm->archive = rpmcpioOpen(cfd, O_RDONLY);
}
fsm->archiveSize = archiveSize;
@@ -631,7 +629,7 @@ static int fsmSetup(FSM_t fsm, fileStage goal,
if (rc && !ec) ec = rc;
if (fsm->archiveSize && ec == 0)
- *fsm->archiveSize = fsm->cpioPos;
+ *fsm->archiveSize = rpmcpioTell(fsm->archive);
/* FIX: *fsm->failedFile may be NULL */
return ec;
@@ -644,6 +642,8 @@ static int fsmTeardown(FSM_t fsm)
if (!rc)
rc = fsmUNSAFE(fsm, FSM_DESTROY);
+ rc = rpmcpioClose(fsm->archive) || rc;
+
fsm->iter = mapFreeIterator(fsm->iter);
if (fsm->cfd != NULL) {
fsm->cfd = fdFree(fsm->cfd);
@@ -788,19 +788,18 @@ static int expandRegular(FSM_t fsm)
fdInitDigest(wfd, digestalgo, 0);
while (left) {
-
- fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left);
- rc = fsmNext(fsm, FSM_DREAD);
- if (rc)
+ size_t len;
+ len = (left > fsm->bufsize ? fsm->bufsize : left);
+ if (rpmcpioRead(fsm->archive, fsm->buf, len) != len) {
+ rc = CPIOERR_READ_FAILED;
goto exit;
-
- fsm->wrnb = Fwrite(fsm->wrbuf, sizeof(*fsm->wrbuf), fsm->rdnb, wfd);
- if (fsm->rdnb != fsm->wrnb || Ferror(wfd)) {
+ }
+ if ((Fwrite(fsm->buf, sizeof(*fsm->buf), len, wfd) != len) || Ferror(wfd)) {
rc = CPIOERR_WRITE_FAILED;
goto exit;
}
- left -= fsm->wrnb;
+ left -= len;
/* don't call this with fileSize == fileComplete */
if (!rc && left)
@@ -815,8 +814,9 @@ static int expandRegular(FSM_t fsm)
if (digest != NULL && fidigest != NULL) {
size_t diglen = rpmDigestLength(digestalgo);
- if (memcmp(digest, fidigest, diglen))
+ if (memcmp(digest, fidigest, diglen)) {
rc = CPIOERR_DIGEST_MISMATCH;
+ }
} else {
rc = CPIOERR_DIGEST_MISMATCH;
}
@@ -841,7 +841,7 @@ static int fsmReadLink(const char *path,
int rc = CPIOERR_READLINK_FAILED;
if (_fsm_debug && (FSM_READLINK & FSM_SYSCALL)) {
- rpmlog(RPMLOG_DEBUG, " %8s (%s, rdbuf, %d) %s\n",
+ rpmlog(RPMLOG_DEBUG, " %8s (%s, buf, %d) %s\n",
fileStageString(FSM_READLINK),
path, (int)(bufsize -1), (llen < 0 ? strerror(errno) : ""));
}
@@ -868,7 +868,7 @@ static int writeFile(FSM_t fsm, int writeData)
struct stat * ost = &fsm->osb;
char * symbuf = NULL;
rpm_loff_t left;
- int rc;
+ int rc = 0;
st->st_size = (writeData ? ost->st_size : 0);
@@ -879,11 +879,11 @@ static int writeFile(FSM_t fsm, int writeData)
* While linux puts the size of a symlink in the st_size field,
* I don't think that's a specified standard.
*/
- /* XXX NUL terminated result in fsm->rdbuf, len in fsm->rdnb. */
- rc = fsmReadLink(fsm->path, fsm->rdbuf, fsm->rdsize, &fsm->rdnb);
+ size_t linklen;
+ rc = fsmReadLink(fsm->path, fsm->buf, fsm->bufsize, &linklen);
if (rc) goto exit;
- st->st_size = fsm->rdnb;
- rstrcat(&symbuf, fsm->rdbuf); /* XXX save readlink return. */
+ st->st_size = linklen;
+ rstrcat(&symbuf, fsm->buf); /* XXX save readlink return. */
}
if (fsm->mapFlags & CPIO_MAP_ABSOLUTE) {
@@ -895,15 +895,17 @@ static int writeFile(FSM_t fsm, int writeData)
rpmfiBNIndex(fi, fsm->ix)));
}
- rc = cpioHeaderWrite(fsm, st);
+ rc = rpmcpioHeaderWrite(fsm->archive, fsm->path, st);
_free(fsm->path);
fsm->path = path;
+
if (rc) goto exit;
+
if (writeData && S_ISREG(st->st_mode)) {
- size_t rdlen;
+ size_t len;
#ifdef HAVE_MMAP
- char * rdbuf = NULL;
+ char * buf = NULL;
void * mapped = MAP_FAILED;
size_t nmapped;
int xx;
@@ -920,9 +922,9 @@ static int writeFile(FSM_t fsm, int writeData)
nmapped = 0;
mapped = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED, Fileno(rfd), 0);
if (mapped != MAP_FAILED) {
- rdbuf = fsm->rdbuf;
- fsm->rdbuf = (char *) mapped;
- rdlen = nmapped = st->st_size;
+ buf = fsm->buf;
+ fsm->buf = (char *) mapped;
+ len = nmapped = st->st_size;
#if defined(MADV_DONTNEED)
xx = madvise(mapped, nmapped, MADV_DONTNEED);
#endif
@@ -934,24 +936,22 @@ static int writeFile(FSM_t fsm, int writeData)
while (left) {
#ifdef HAVE_MMAP
if (mapped != MAP_FAILED) {
- fsm->rdnb = nmapped;
+ len = nmapped;
} else
#endif
{
- rdlen = (left > fsm->rdsize ? fsm->rdsize : left),
-
- fsm->rdnb = Fread(fsm->rdbuf, sizeof(*fsm->rdbuf), rdlen, rfd);
- if (fsm->rdnb != rdlen || Ferror(rfd)) {
- rc = CPIOERR_READ_FAILED;
- goto exit;
- }
+ len = (left > fsm->bufsize ? fsm->bufsize : left);
+ if (Fread(fsm->buf, sizeof(*fsm->buf), len, rfd) != len || Ferror(rfd)) {
+ rc = CPIOERR_READ_FAILED;
+ goto exit;
+ }
}
- /* XXX DWRITE uses rdnb for I/O length. */
- rc = fsmNext(fsm, FSM_DWRITE);
- if (rc) goto exit;
-
- left -= fsm->wrnb;
+ if (rpmcpioWrite(fsm->archive, fsm->buf, len) != len) {
+ rc = CPIOERR_WRITE_FAILED;
+ goto exit;
+ }
+ left -= len;
}
#ifdef HAVE_MMAP
@@ -961,23 +961,18 @@ static int writeFile(FSM_t fsm, int writeData)
xx = madvise(mapped, nmapped, MADV_DONTNEED);
#endif
xx = munmap(mapped, nmapped);
- fsm->rdbuf = rdbuf;
+ fsm->buf = buf;
}
#endif
} else if (writeData && S_ISLNK(st->st_mode)) {
- /* XXX DWRITE uses rdnb for I/O length. */
- strcpy(fsm->rdbuf, symbuf); /* XXX restore readlink buffer. */
- fsm->rdnb = strlen(symbuf);
- rc = fsmNext(fsm, FSM_DWRITE);
- if (rc) goto exit;
+ size_t len = strlen(symbuf);
+ if (rpmcpioWrite(fsm->archive, symbuf, len) != len) {
+ rc = CPIOERR_WRITE_FAILED;
+ goto exit;
+ }
}
- rc = fsmNext(fsm, FSM_PAD);
- if (rc) goto exit;
-
- rc = 0;
-
exit:
if (rfd) {
/* preserve any prior errno across close */
@@ -989,6 +984,8 @@ exit:
}
fsm->path = path;
free(symbuf);
+ if (rc)
+ printf(rpmcpioStrerror(rc));
return rc;
}
@@ -1591,12 +1588,13 @@ static int fsmVerify(FSM_t fsm)
}
} else if (S_ISLNK(st->st_mode)) {
if (S_ISLNK(ost->st_mode)) {
- /* XXX NUL terminated result in fsm->rdbuf, len in fsm->rdnb. */
- rc = fsmReadLink(fsm->path, fsm->rdbuf, fsm->rdsize, &fsm->rdnb);
+ char buf[8 * BUFSIZ];
+ size_t len;
+ rc = fsmReadLink(fsm->path, buf, 8 * BUFSIZ, &len);
errno = saveerrno;
if (rc) return rc;
- /* XXX FSM_PROCESS puts link target to wrbuf. */
- if (rstreq(fsm->wrbuf, fsm->rdbuf)) return 0;
+ /* FSM_PROCESS puts link target to fsm->buf. */
+ if (rstreq(fsm->buf, buf)) return 0;
}
} else if (S_ISFIFO(st->st_mode)) {
if (S_ISFIFO(ost->st_mode)) return 0;
@@ -1629,13 +1627,11 @@ static int fsmVerify(FSM_t fsm)
*/
static int fsmStage(FSM_t fsm, fileStage stage)
{
- static int modulo = 4;
const char * const cur = fileStageString(stage);
struct stat * st = &fsm->sb;
struct stat * ost = &fsm->osb;
int saveerrno = errno;
int rc = fsm->rc;
- rpm_loff_t left;
#define _fafilter(_a) \
(!((_a) == FA_CREATE || (_a) == FA_ERASE || (_a) == FA_COPYIN || (_a) == FA_COPYOUT) \
@@ -1751,14 +1747,9 @@ static int fsmStage(FSM_t fsm, fileStage stage)
/* Flush partial sets of hard linked files. */
rc = writeLinks(fsm);
- if (!rc)
- rc = cpioTrailerWrite(fsm);
-
break;
case FSM_PROCESS:
if (fsm->postpone) {
- if (fsm->goal == FSM_PKGINSTALL)
- rc = fsmNext(fsm, FSM_EAT);
break;
}
@@ -1805,22 +1796,21 @@ static int fsmStage(FSM_t fsm, fileStage stage)
rc = fsmMkdir(fsm->path, mode);
}
} else if (S_ISLNK(st->st_mode)) {
- if ((st->st_size + 1) > fsm->rdsize) {
+ if ((st->st_size + 1) > fsm->bufsize) {
rc = CPIOERR_HDR_SIZE;
break;
}
- fsm->wrlen = st->st_size;
- rc = fsmNext(fsm, FSM_DREAD);
- if (!rc && fsm->rdnb != fsm->wrlen)
+ if (rpmcpioRead(fsm->archive, fsm->buf, st->st_size) != st->st_size) {
rc = CPIOERR_READ_FAILED;
- if (rc) break;
+ break;
+ }
- fsm->wrbuf[st->st_size] = '\0';
- /* XXX fsmVerify() assumes link target in fsm->wrbuf */
+ fsm->buf[st->st_size] = '\0';
+ /* fsmVerify() assumes link target in fsm->buf */
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
- rc = fsmSymlink(fsm->wrbuf, fsm->path);
+ rc = fsmSymlink(fsm->buf, fsm->path);
}
} else if (S_ISFIFO(st->st_mode)) {
/* This mimics cpio S_ISSOCK() behavior but probably isnt' right */
@@ -1850,7 +1840,7 @@ static int fsmStage(FSM_t fsm, fileStage stage)
break;
case FSM_NOTIFY: /* XXX move from fsm to psm -> tsm */
if (fsm->goal == FSM_PKGINSTALL) {
- rpmpsmNotify(fsm->psm, RPMCALLBACK_INST_PROGRESS, fsm->cpioPos);
+ rpmpsmNotify(fsm->psm, RPMCALLBACK_INST_PROGRESS, rpmcpioTell(fsm->archive));
} else if (fsm->goal == FSM_PKGERASE) {
/* On erase we're iterating backwards, fixup for progress */
rpm_loff_t amount = (fsm->ix >= 0) ?
@@ -2023,68 +2013,20 @@ static int fsmStage(FSM_t fsm, fileStage stage)
}
fsm->li = freeHardLink(fsm->li);
}
- fsm->rdbuf = fsm->rdb = _free(fsm->rdb);
- fsm->wrbuf = fsm->wrb = _free(fsm->wrb);
+ fsm->buf = _free(fsm->buf);
+ fsm->bufsize = 0;
break;
case FSM_NEXT:
- rc = fsmNext(fsm, FSM_POS);
- if (!rc)
- rc = cpioHeaderRead(fsm, st); /* Read next payload header. */
+ if (!rc) {
+ _free(fsm->path);
+ rc = rpmcpioHeaderRead(fsm->archive, &(fsm->path), st); /* Read next payload header. */
+ }
if (rc) break;
if (rstreq(fsm->path, CPIO_TRAILER)) { /* Detect end-of-payload. */
fsm->path = _free(fsm->path);
rc = CPIOERR_HDR_TRAILER;
}
- if (!rc)
- rc = fsmNext(fsm, FSM_POS);
- break;
- case FSM_EAT:
- for (left = st->st_size; left > 0; left -= fsm->rdnb) {
- fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left);
- rc = fsmNext(fsm, FSM_DREAD);
- if (rc)
- break;
- }
- break;
- case FSM_POS:
- left = (modulo - (fsm->cpioPos % modulo)) % modulo;
- if (left) {
- fsm->wrlen = left;
- (void) fsmNext(fsm, FSM_DREAD);
- }
- break;
- case FSM_PAD:
- left = (modulo - (fsm->cpioPos % modulo)) % modulo;
- if (left) {
- memset(fsm->rdbuf, 0, left);
- /* XXX DWRITE uses rdnb for I/O length. */
- fsm->rdnb = left;
- (void) fsmNext(fsm, FSM_DWRITE);
- }
- break;
- case FSM_DREAD:
- fsm->rdnb = Fread(fsm->wrbuf, sizeof(*fsm->wrbuf), fsm->wrlen, fsm->cfd);
- if (_fsm_debug && (stage & FSM_SYSCALL))
- rpmlog(RPMLOG_DEBUG, " %8s (%s, %d, cfd)\trdnb %d\n",
- cur, (fsm->wrbuf == fsm->wrb ? "wrbuf" : "mmap"),
- (int)fsm->wrlen, (int)fsm->rdnb);
- if (fsm->rdnb != fsm->wrlen || Ferror(fsm->cfd))
- rc = CPIOERR_READ_FAILED;
- if (fsm->rdnb > 0)
- fsm->cpioPos += fsm->rdnb;
break;
- case FSM_DWRITE:
- fsm->wrnb = Fwrite(fsm->rdbuf, sizeof(*fsm->rdbuf), fsm->rdnb, fsm->cfd);
- if (_fsm_debug && (stage & FSM_SYSCALL))
- rpmlog(RPMLOG_DEBUG, " %8s (%s, %d, cfd)\twrnb %d\n",
- cur, (fsm->rdbuf == fsm->rdb ? "rdbuf" : "mmap"),
- (int)fsm->rdnb, (int)fsm->wrnb);
- if (fsm->rdnb != fsm->wrnb || Ferror(fsm->cfd))
- rc = CPIOERR_WRITE_FAILED;
- if (fsm->wrnb > 0)
- fsm->cpioPos += fsm->wrnb;
- break;
-
default:
break;
}
diff --git a/lib/fsm.h b/lib/fsm.h
index c25b7c5e8..e438b1ab4 100644
--- a/lib/fsm.h
+++ b/lib/fsm.h
@@ -7,6 +7,7 @@
*/
#include <rpm/rpmfi.h>
+#include "cpio.h"
extern int _fsm_debug;
@@ -106,22 +107,14 @@ typedef struct hardLink_s * hardLink_t;
struct fsm_s {
char * path; /*!< Current file name. */
FD_t cfd; /*!< Payload file handle. */
- char * rdbuf; /*!< read: Buffer. */
- char * rdb; /*!< read: Buffer allocated. */
- size_t rdsize; /*!< read: Buffer allocated size. */
- size_t rdnb; /*!< read: Number of bytes returned. */
- char * wrbuf; /*!< write: Buffer. */
- char * wrb; /*!< write: Buffer allocated. */
- size_t wrsize; /*!< write: Buffer allocated size. */
- size_t wrlen; /*!< write: Number of bytes requested.*/
- size_t wrnb; /*!< write: Number of bytes returned. */
+ rpmcpio_t archive; /*!< cpio archive */
+ char * buf; /*!< read: Buffer. */
+ size_t bufsize; /*!< read: Buffer allocated size. */
FSMI_t iter; /*!< File iterator. */
int ix; /*!< Current file iterator index. */
hardLink_t links; /*!< Pending hard linked file(s). */
hardLink_t li; /*!< Current hard linked file(s). */
rpm_loff_t * archiveSize; /*!< Pointer to archive size. */
- rpm_loff_t archivePos; /*!< Current archive position. */
- rpm_loff_t cpioPos;
char ** failedFile; /*!< First file name that failed. */
const char * osuffix; /*!< Old, preserved, file suffix. */
const char * nsuffix; /*!< New, created, file suffix. */
diff --git a/lib/psm.c b/lib/psm.c
index 5947c47c2..93f0a567d 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -836,7 +836,7 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
_("unpacking of archive failed%s%s: %s\n"),
(psm->failedFile != NULL ? _(" on file ") : ""),
(psm->failedFile != NULL ? psm->failedFile : ""),
- cpioStrerror(fsmrc));
+ rpmcpioStrerror(fsmrc));
rc = RPMRC_FAIL;
/* XXX notify callback on error. */
@@ -939,10 +939,10 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
if (psm->failedFile)
rpmlog(RPMLOG_ERR,
_("%s failed on file %s: %s\n"),
- psm->goalName, psm->failedFile, cpioStrerror(rc));
+ psm->goalName, psm->failedFile, rpmcpioStrerror(rc));
else
rpmlog(RPMLOG_ERR, _("%s failed: %s\n"),
- psm->goalName, cpioStrerror(rc));
+ psm->goalName, rpmcpioStrerror(rc));
/* XXX notify callback on error. */
rpmtsNotify(ts, psm->te, RPMCALLBACK_CPIO_ERROR, 0, 0);