diff options
author | jbj <devnull@localhost> | 2001-02-03 14:30:57 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2001-02-03 14:30:57 +0000 |
commit | 2816871692ceb70eb1feb75314acbc98c20369dc (patch) | |
tree | 4aca060c42e92424e611c97b8f0a53a41ecb6984 | |
parent | e3d524717407f943594d41429988b61561e36549 (diff) | |
download | rpm-2816871692ceb70eb1feb75314acbc98c20369dc.tar.gz rpm-2816871692ceb70eb1feb75314acbc98c20369dc.tar.bz2 rpm-2816871692ceb70eb1feb75314acbc98c20369dc.zip |
Add I/O to file state machine.
CVS patchset: 4516
CVS date: 2001/02/03 14:30:57
-rw-r--r-- | lib/cpio.c | 904 | ||||
-rw-r--r-- | lib/rollback.c | 12 | ||||
-rw-r--r-- | lib/rollback.h | 79 | ||||
-rw-r--r-- | po/rpm.pot | 94 |
4 files changed, 586 insertions, 503 deletions
diff --git a/lib/cpio.c b/lib/cpio.c index 24ea1b8d3..4bc488b52 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -90,6 +90,16 @@ struct cpioHeader { /*@owned@*/ const char * path; /*@owned@*/ const char * opath; FD_t cfd; + FD_t rfd; +/*@owned@*/ char * rdbuf; + size_t rdsize; + size_t rdlen; + size_t rdnb; + FD_t wfd; +/*@owned@*/ char * wrbuf; + size_t wrsize; + size_t wrlen; + size_t wrnb; /*@owned@*/ void * mapi; /*@dependent@*/ const void * map; /*@owned@*/ struct hardLink * links; @@ -118,28 +128,30 @@ struct cpioHeader { struct stat sb; }; -/** \ingroup payload - * Cpio archive header information. - * @todo Add support for tar (soon) and ar (eventually) archive formats. - */ -struct cpioCrcPhysicalHeader { - char magic[6]; - char inode[8]; - char mode[8]; - char uid[8]; - char gid[8]; - char nlink[8]; - char mtime[8]; - char filesize[8]; - char devMajor[8]; - char devMinor[8]; - char rdevMajor[8]; - char rdevMinor[8]; - char namesize[8]; - char checksum[8]; /* ignored !! */ -}; +rpmTransactionSet fsmGetTs(FSM_t fsm) { + struct mapi * mapi = fsm->mapi; + return (mapi ? mapi->ts : NULL); +} -#define PHYS_HDR_SIZE 110 /*!< Don't depend on sizeof(struct) */ +TFI_t fsmGetFi(FSM_t fsm) { + struct mapi * mapi = fsm->mapi; + return (mapi ? mapi->fi : NULL); +} + +static int fsmSetIndex(FSM_t fsm, int isave) { + struct mapi * mapi = fsm->mapi; + int iprev = -1; + if (mapi) { + iprev = mapi->isave; + mapi->isave = isave; + } + return iprev; +} + +int fsmGetIndex(FSM_t fsm) { + struct mapi * mapi = fsm->mapi; + return (mapi ? mapi->isave : -1); +} /** */ @@ -650,99 +662,6 @@ FSM_t freeFSM(FSM_t fsm) } /** - * Read data from payload. - * @param cfd payload file handle - * @retval vbuf data from read - * @param amount no. bytes to read - * @return no. bytes read - */ -static inline off_t saferead(FD_t cfd, /*@out@*/void * vbuf, size_t amount) - /*@modifies cfd, *vbuf @*/ -{ - char * buf = vbuf; - off_t rc = 0; - - while (amount > 0) { - size_t nb; - - nb = Fread(buf, sizeof(buf[0]), amount, cfd); - if (nb <= 0) - return nb; - rc += nb; - if (rc >= amount) - break; - buf += nb; - amount -= nb; - } - return rc; -} - -/** - * Read data from payload and update number of bytes read. - * @param cfd payload file handle - * @retval buf data from read - * @param size no. bytes to read - * @return no. bytes read - */ -static inline off_t ourread(FD_t cfd, /*@out@*/void * buf, size_t size) - /*@modifies cfd, *buf @*/ -{ - off_t i = saferead(cfd, buf, size); - if (i > 0) - fdSetCpioPos(cfd, fdGetCpioPos(cfd) + i); - return i; -} - -/** - * Write data to payload. - * @param cfd payload file handle - * @param vbuf data to write - * @param amount no. bytes to write - * @return no. bytes written - */ -static inline off_t safewrite(FD_t cfd, const void * vbuf, size_t amount) - /*@modifies cfd @*/ -{ - const char * buf = vbuf; - off_t rc = 0; - - while (amount > 0) { - size_t nb; - - nb = Fwrite(buf, sizeof(buf[0]), amount, cfd); - if (nb <= 0) - return nb; - rc += nb; - if (rc >= amount) - break; - buf += nb; - amount -= nb; - } - - return rc; -} - -/** - * Align output payload handle, padding with zeroes. - * @param cfd payload file handle - * @param modulo data alignment - * @return 0 on success, CPIOERR_WRITE_FAILED - */ -static inline int padoutfd(FD_t cfd, size_t * where, int modulo) - /*@modifies cfd, *where @*/ -{ - static int buf[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int amount; - - amount = (modulo - (*where % modulo)) % modulo; - *where += amount; - - if (safewrite(cfd, buf, amount) != amount) - return CPIOERR_WRITE_FAILED; - return 0; -} - -/** * Convert string to unsigned integer (with buffer size check). * @param input string * @retval address of 1st character not processed @@ -769,6 +688,29 @@ static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num) return ret; } +/** \ingroup payload + * Cpio archive header information. + * @todo Add support for tar (soon) and ar (eventually) archive formats. + */ +struct cpioCrcPhysicalHeader { + char magic[6]; + char inode[8]; + char mode[8]; + char uid[8]; + char gid[8]; + char nlink[8]; + char mtime[8]; + char filesize[8]; + char devMajor[8]; + char devMinor[8]; + char rdevMajor[8]; + char rdevMinor[8]; + char namesize[8]; + char checksum[8]; /* ignored !! */ +}; + +#define PHYS_HDR_SIZE 110 /*!< Don't depend on sizeof(struct) */ + #define GET_NUM_FIELD(phys, log) \ log = strntoul(phys, &end, 16, sizeof(phys)); \ if (*end) return CPIOERR_BAD_HEADER; @@ -777,49 +719,102 @@ static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num) memcpy(phys, space, 8); /** - * Process next cpio heasder. + * Write cpio header. * @retval fsm file path and stat info * @return 0 on success */ -static int getNextHeader(FSM_t fsm, struct stat * st) +static int cpioHeaderWrite(FSM_t fsm, struct stat * st) +{ + struct cpioCrcPhysicalHeader * hdr = (struct cpioCrcPhysicalHeader *)fsm->rdbuf; + char field[64]; + size_t len; + dev_t dev; + int rc = 0; + + 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); + SET_NUM_FIELD(hdr->uid, st->st_uid, field); + SET_NUM_FIELD(hdr->gid, st->st_gid, field); + SET_NUM_FIELD(hdr->nlink, st->st_nlink, field); + SET_NUM_FIELD(hdr->mtime, st->st_mtime, field); + SET_NUM_FIELD(hdr->filesize, st->st_size, field); + + dev = major((unsigned)st->st_dev); SET_NUM_FIELD(hdr->devMajor, dev, field); + dev = minor((unsigned)st->st_dev); SET_NUM_FIELD(hdr->devMinor, dev, field); + 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(fsm->path) + 1; SET_NUM_FIELD(hdr->namesize, len, field); + memcpy(hdr->checksum, "00000000", 8); + memcpy(fsm->rdbuf + PHYS_HDR_SIZE, fsm->path, len); + + fsm->rdnb = PHYS_HDR_SIZE + len; + rc = fsmStage(fsm, FSM_DWRITE); + if (!rc && fsm->rdnb != fsm->wrnb) + rc = CPIOERR_WRITE_FAILED; + if (!rc) + rc = fsmStage(fsm, FSM_PAD); + return rc; +} + +/** + * Read cpio heasder. + * @retval fsm file path and stat info + * @return 0 on success + */ +static int cpioHeaderRead(FSM_t fsm, struct stat * st) /*@modifies fsm->cfd, fsm->path, *st @*/ { - struct cpioCrcPhysicalHeader physHeader; + struct cpioCrcPhysicalHeader hdr; int nameSize; char * end; int major, minor; + int rc = 0; - if (ourread(fsm->cfd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) - return CPIOERR_READ_FAILED; + fsm->wrlen = PHYS_HDR_SIZE; + rc = fsmStage(fsm, FSM_DREAD); + if (!rc && fsm->rdnb != fsm->wrlen) + rc = CPIOERR_READ_FAILED; + if (rc) return rc; + memcpy(&hdr, fsm->wrbuf, fsm->rdnb); - if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, sizeof(CPIO_CRC_MAGIC)-1) && - strncmp(CPIO_NEWC_MAGIC, physHeader.magic, sizeof(CPIO_NEWC_MAGIC)-1)) + if (strncmp(CPIO_CRC_MAGIC, hdr.magic, sizeof(CPIO_CRC_MAGIC)-1) && + strncmp(CPIO_NEWC_MAGIC, hdr.magic, sizeof(CPIO_NEWC_MAGIC)-1)) return CPIOERR_BAD_MAGIC; - GET_NUM_FIELD(physHeader.inode, st->st_ino); - GET_NUM_FIELD(physHeader.mode, st->st_mode); - GET_NUM_FIELD(physHeader.uid, st->st_uid); - GET_NUM_FIELD(physHeader.gid, st->st_gid); - GET_NUM_FIELD(physHeader.nlink, st->st_nlink); - GET_NUM_FIELD(physHeader.mtime, st->st_mtime); - GET_NUM_FIELD(physHeader.filesize, st->st_size); + 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(physHeader.devMajor, major); - GET_NUM_FIELD(physHeader.devMinor, minor); + GET_NUM_FIELD(hdr.devMajor, major); + GET_NUM_FIELD(hdr.devMinor, minor); st->st_dev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ; - GET_NUM_FIELD(physHeader.rdevMajor, major); - GET_NUM_FIELD(physHeader.rdevMinor, minor); + GET_NUM_FIELD(hdr.rdevMajor, major); + GET_NUM_FIELD(hdr.rdevMinor, minor); st->st_rdev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ; - GET_NUM_FIELD(physHeader.namesize, nameSize); + GET_NUM_FIELD(hdr.namesize, nameSize); + if (nameSize >= fsm->wrsize) + return CPIOERR_BAD_HEADER; { char * t = xmalloc(nameSize + 1); - if (ourread(fsm->cfd, t, nameSize) != nameSize) { + fsm->wrlen = nameSize; + rc = fsmStage(fsm, FSM_DREAD); + if (!rc && fsm->rdnb != fsm->wrlen) + rc = CPIOERR_BAD_HEADER; + if (rc) { free(t); fsm->path = NULL; - return CPIOERR_BAD_HEADER; + return rc; } + memcpy(t, fsm->wrbuf, fsm->rdnb); + t[nameSize] = '\0'; fsm->path = t; } @@ -836,9 +831,6 @@ static int expandRegular(FSM_t fsm) /*@modifies fileSystem, fsm->cfd @*/ { const char * filemd5; - FD_t ofd; - char buf[BUFSIZ]; - int bytesRead; const struct stat * st = &fsm->sb; int left = st->st_size; int rc = 0; @@ -870,27 +862,26 @@ rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), fsm->opath, fsm->path); if (rc != CPIOERR_LSTAT_FAILED) return rc; rc = 0; - ofd = Fopen(fsm->path, "w.ufdio"); - if (ofd == NULL || Ferror(ofd)) - return CPIOERR_OPEN_FAILED; + rc = fsmStage(fsm, FSM_WOPEN); + if (rc) + goto exit; /* XXX This doesn't support brokenEndian checks. */ if (filemd5) - fdInitMD5(ofd, 0); + fdInitMD5(fsm->wfd, 0); while (left) { - bytesRead = ourread(fsm->cfd, buf, left < sizeof(buf) ? left : sizeof(buf)); - if (bytesRead <= 0) { - rc = CPIOERR_READ_FAILED; - break; - } - if (Fwrite(buf, sizeof(buf[0]), bytesRead, ofd) != bytesRead) { - rc = CPIOERR_COPY_FAILED; - break; - } + fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left); + rc = fsmStage(fsm, FSM_DREAD); + if (rc) + goto exit; + + rc = fsmStage(fsm, FSM_WRITE); + if (rc) + goto exit; - left -= bytesRead; + left -= fsm->wrnb; /* don't call this with fileSize == fileComplete */ if (!rc && left) @@ -900,8 +891,8 @@ rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), fsm->opath, fsm->path); if (filemd5) { const char * md5sum = NULL; - Fflush(ofd); - fdFiniMD5(ofd, (void **)&md5sum, NULL, 1); + Fflush(fsm->wfd); + fdFiniMD5(fsm->wfd, (void **)&md5sum, NULL, 1); if (md5sum == NULL) { rc = CPIOERR_MD5SUM_MISMATCH; @@ -912,11 +903,13 @@ rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), fsm->opath, fsm->path); } } - Fclose(ofd); - +exit: + (void) fsmStage(fsm, FSM_WCLOSE); return rc; } +/** + */ static int fsmMakeLinks(FSM_t fsm) { const char * path = fsm->path; @@ -956,6 +949,8 @@ static int fsmMakeLinks(FSM_t fsm) return rc; } +/** + */ static int fsmCommitLinks(FSM_t fsm) { const char * path = fsm->path; @@ -992,15 +987,19 @@ int fsmStage(FSM_t fsm, fileStage stage) fileStage prevStage = fsm->stage; const char * const prev = fileStageString(prevStage); #endif + 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; + int left; int i; - if (stage & FSM_INTERNAL) { - if (_fsm_debug && !(stage == FSM_VERIFY || stage == FSM_NOTIFY)) + if (stage & FSM_DEAD) { + /* do nothing */ + } else if (stage & FSM_INTERNAL) { + if (_fsm_debug && !(stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s %06o%3d (%4d,%4d)%10d %s %s\n", cur, st->st_mode, st->st_nlink, st->st_uid, st->st_gid, st->st_size, @@ -1009,7 +1008,7 @@ int fsmStage(FSM_t fsm, fileStage stage) ? fileActionString(fsm->action) : "")); } else { fsm->stage = stage; - if (_fsm_debug || !(stage & FSM_QUIET)) + if (_fsm_debug || !(stage & FSM_VERBOSE)) rpmMessage(RPMMESS_DEBUG, "%-8s %06o%3d (%4d,%4d)%10d %s %s\n", cur, st->st_mode, st->st_nlink, st->st_uid, st->st_gid, st->st_size, @@ -1032,6 +1031,12 @@ int fsmStage(FSM_t fsm, fileStage stage) fsm->dnlx = _free(fsm->dnlx); fsm->ldn = _free(fsm->ldn); fsm->ldnalloc = fsm->ldnlen = 0; + fsm->rdsize = 8 * BUFSIZ; + fsm->rdbuf = _free(fsm->rdbuf); + fsm->rdbuf = xmalloc(fsm->rdsize); + fsm->wrsize = 8 * BUFSIZ; + fsm->wrbuf = _free(fsm->wrbuf); + fsm->wrbuf = xmalloc(fsm->wrsize); fsm->mkdirsdone = 0; fsm->map = NULL; fsm->links = NULL; @@ -1069,34 +1074,14 @@ int fsmStage(FSM_t fsm, fileStage stage) /* FSM_INIT -> {FSM_PRE,FSM_DESTROY} */ break; case FSM_MAP: - /* No map, nothing to do. */ - /* @todo FA_ALTNAME rename still needs doing. */ - if (fsm->mapi == NULL) break; - fsm->map = mapFind(fsm->mapi, fsm->path); - fsm->action = fsmAction(fsm, &fsm->osuffix, &fsm->nsuffix); - - if (fsmFlags(fsm, CPIO_MAP_PATH) || fsm->nsuffix) { - fsm->path = _free(fsm->path); - fsm->path = mapFsPath(fsm->map, st, fsm->subdir, - (fsm->suffix ? fsm->suffix : fsm->nsuffix)); - } - - if (fsmFlags(fsm, CPIO_MAP_MODE)) - st->st_mode = mapFinalMode(fsm->map); - if (fsmFlags(fsm, CPIO_MAP_UID)) - st->st_uid = mapFinalUid(fsm->map); - if (fsmFlags(fsm, CPIO_MAP_GID)) - st->st_gid = mapFinalGid(fsm->map); + if (fsm->mapi) + (void) fsmMap(fsm); break; case FSM_MKDIRS: { const char * path = fsm->path; mode_t st_mode = st->st_mode; void * dnli = dnlInitIterator(fsm->mapi, 0); -#ifdef DYING - char dn[BUFSIZ]; /* XXX add to fsm */ -#else - char * dn = xcalloc(1, BUFSIZ); -#endif + char * dn = fsm->rdbuf; int dc = dnlCount(dnli); int i; @@ -1164,7 +1149,6 @@ int fsmStage(FSM_t fsm, fileStage stage) fsm->ldnlen = dnlen; } dnli = dnlFreeIterator(dnli); - free(dn); fsm->path = path; st->st_mode = st_mode; /* XXX restore st->st_mode */ } @@ -1173,11 +1157,7 @@ int fsmStage(FSM_t fsm, fileStage stage) if (fsm->dnlx) { const char * path = fsm->path; void * dnli = dnlInitIterator(fsm->mapi, 1); -#ifdef DYING - char dn[BUFSIZ]; /* XXX add to fsm */ -#else - char * dn = calloc(1, BUFSIZ); -#endif + char * dn = fsm->rdbuf; int dc = dnlCount(dnli); dn[0] = '\0'; @@ -1205,7 +1185,6 @@ int fsmStage(FSM_t fsm, fileStage stage) } while ((te - dn) > fsm->dnlx[dc]); } dnli = dnlFreeIterator(dnli); - free(dn); fsm->path = path; } break; @@ -1294,20 +1273,21 @@ fprintf(stderr, "*** %p link[%d:%d] %d filex %d %s\n", fsm->li, fsm->li->linksLe } } else if (S_ISLNK(st->st_mode)) { const char * opath = fsm->opath; - char buf[2048]; /* XXX add to fsm */ - if ((st->st_size + 1)> sizeof(buf)) { + if ((st->st_size + 1) > fsm->rdsize) { rc = CPIOERR_HDR_SIZE; break; } - if (ourread(fsm->cfd, buf, st->st_size) != st->st_size) { + + fsm->wrlen = st->st_size; + rc = fsmStage(fsm, FSM_DREAD); + if (!rc && fsm->rdnb != fsm->wrlen) rc = CPIOERR_READ_FAILED; - break; - } - buf[st->st_size] = '\0'; + if (rc) break; + fsm->wrbuf[st->st_size] = '\0'; /* XXX symlink(fsm->opath, fsm->path) */ - fsm->opath = buf; /* XXX abuse fsm->path */ + fsm->opath = fsm->wrbuf; /* XXX abuse fsm->path */ rc = fsmStage(fsm, FSM_VERIFY); if (rc == CPIOERR_LSTAT_FAILED) rc = fsmStage(fsm, FSM_SYMLINK); @@ -1432,6 +1412,8 @@ opath = _free(opath); } fsm->ldn = _free(fsm->ldn); fsm->ldnalloc = fsm->ldnlen = 0; + fsm->rdbuf = _free(fsm->rdbuf); + fsm->wrbuf = _free(fsm->wrbuf); break; case FSM_VERIFY: rc = lstat(fsm->path, ost); @@ -1470,12 +1452,11 @@ opath = _free(opath); } } else if (S_ISLNK(st->st_mode)) { if (S_ISLNK(ost->st_mode)) { - char buf[2048]; - rc = readlink(fsm->path, buf, sizeof(buf) - 1); + rc = readlink(fsm->path, fsm->rdbuf, fsm->rdsize - 1); errno = saveerrno; if (rc > 0) { - buf[rc] = '\0'; - if (!strcmp(fsm->opath, buf)) return 0; + fsm->rdbuf[rc] = '\0'; + if (!strcmp(fsm->opath, fsm->rdbuf)) return 0; } } } else if (S_ISFIFO(st->st_mode)) { @@ -1492,41 +1473,60 @@ opath = _free(opath); if (rc == 0) rc = CPIOERR_LSTAT_FAILED; return (rc ? rc : CPIOERR_LSTAT_FAILED); /* XXX HACK */ break; + case FSM_UNLINK: rc = unlink(fsm->path); -if (rc < 0) fprintf(stderr, "*** %s(%s) %m\n", cur, fsm->path); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s) %s\n", cur, + fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_UNLINK_FAILED; break; case FSM_RENAME: rc = rename(fsm->opath, fsm->path); -if (rc < 0) fprintf(stderr, "*** %s(%s,%s) %m\n", cur, fsm->opath, fsm->path); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %s) %s\n", cur, + fsm->opath, fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_RENAME_FAILED; break; case FSM_MKDIR: rc = mkdir(fsm->path, (st->st_mode & 07777)); -if (rc < 0) fprintf(stderr, "*** %s(%s,%o) %m\n", cur, fsm->path, (st->st_mode & 07777)); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, 0%o) %s\n", cur, + fsm->path, (st->st_mode & 07777), + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_MKDIR_FAILED; break; case FSM_RMDIR: rc = rmdir(fsm->path); -if (rc < 0) fprintf(stderr, "*** %s(%s) %m\n", cur, fsm->path); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s) %s\n", cur, + fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_RMDIR_FAILED; break; case FSM_CHOWN: rc = chown(fsm->path, st->st_uid, st->st_gid); -if (rc < 0) fprintf(stderr, "*** %s(%s,%d,%d) %m\n", cur, fsm->path, st->st_uid, st->st_gid); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %d, %d) %s\n", cur, + fsm->path, st->st_uid, st->st_gid, + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_CHOWN_FAILED; break; case FSM_LCHOWN: #if ! CHOWN_FOLLOWS_SYMLINK rc = lchown(fsm->path, st->st_uid, st->st_gid); -if (rc < 0) fprintf(stderr, "*** %s(%s,%d,%d) %m\n", cur, fsm->path, st->st_uid, st->st_gid); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %d, %d) %s\n", cur, + fsm->path, st->st_uid, st->st_gid, + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_CHOWN_FAILED; #endif break; case FSM_CHMOD: rc = chmod(fsm->path, (st->st_mode & 07777)); -if (rc < 0) fprintf(stderr, "*** %s(%s,%o) %m\n", cur, fsm->path, (st->st_mode & 07777)); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, 0%o) %s\n", cur, + fsm->path, (st->st_mode & 07777), + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_CHMOD_FAILED; break; case FSM_UTIME: @@ -1534,47 +1534,64 @@ if (rc < 0) fprintf(stderr, "*** %s(%s,%o) %m\n", cur, fsm->path, (st->st_mode & stamp.actime = st->st_mtime; stamp.modtime = st->st_mtime; rc = utime(fsm->path, &stamp); -if (rc < 0) fprintf(stderr, "*** %s(%s,%x) %m\n", cur, fsm->path, (unsigned)st->st_mtime); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %x) %s\n", cur, + fsm->path, (unsigned)st->st_mtime, + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_UTIME_FAILED; } break; case FSM_SYMLINK: rc = symlink(fsm->opath, fsm->path); -if (rc < 0) fprintf(stderr, "*** %s(%s,%s) %m\n", cur, fsm->opath, fsm->path); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %s) %s\n", cur, + fsm->opath, fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_SYMLINK_FAILED; break; case FSM_LINK: rc = link(fsm->opath, fsm->path); -if (rc < 0) fprintf(stderr, "*** %s(%s,%s) %m\n", cur, fsm->opath, fsm->path); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %s) %s\n", cur, + fsm->opath, fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_LINK_FAILED; break; case FSM_MKFIFO: rc = mkfifo(fsm->path, (st->st_mode & 07777)); -if (rc < 0) fprintf(stderr, "*** %s(%s,%o) %m\n", cur, fsm->path, (st->st_mode & 07777)); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, 0%o) %s\n", cur, + fsm->path, (st->st_mode & 07777), + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_MKFIFO_FAILED; break; case FSM_MKNOD: /*@-unrecog@*/ rc = mknod(fsm->path, (st->st_mode & ~07777), st->st_rdev); -if (rc < 0) fprintf(stderr, "*** %s(%s,%o,%x) %m\n", cur, fsm->path, (st->st_mode & ~07777), (unsigned)st->st_rdev); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, 0%o, 0x%x) %s\n", cur, + fsm->path, (st->st_mode & ~07777), (unsigned)st->st_rdev, + (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_MKNOD_FAILED; /*@=unrecog@*/ break; case FSM_LSTAT: rc = lstat(fsm->path, ost); -if (rc < 0 && errno != ENOENT) fprintf(stderr, "*** %s(%s,%p) %m\n", cur, fsm->path, ost); + if (_fsm_debug && (stage & FSM_SYSCALL) && errno != ENOENT) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, ost) %s\n", cur, + fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_LSTAT_FAILED; break; case FSM_STAT: rc = stat(fsm->path, ost); -if (rc < 0 && errno != ENOENT) fprintf(stderr, "*** %s(%s,%p) %m\n", cur, fsm->path, ost); + if (_fsm_debug && (stage & FSM_SYSCALL) && errno != ENOENT) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, ost) %s\n", cur, + fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_STAT_FAILED; break; case FSM_CHROOT: break; case FSM_NEXT: - rc = getNextHeader(fsm, st); /* Read next payload header. */ + rc = fsmStage(fsm, FSM_HREAD); if (rc) break; if (!strcmp(fsm->path, TRAILER)) { /* Detect end-of-payload. */ fsm->path = _free(fsm->path); @@ -1582,31 +1599,120 @@ if (rc < 0 && errno != ENOENT) fprintf(stderr, "*** %s(%s,%p) %m\n", cur, fsm->p } break; case FSM_EAT: - { char buf[BUFSIZ]; /* XXX add to fsm */ - int amount; - int bite; - - rc = 0; - for (amount = st->st_size; amount > 0; amount -= bite) { - bite = (amount > sizeof(buf)) ? sizeof(buf) : amount; - if (ourread(fsm->cfd, buf, bite) == bite) - continue; - rc = CPIOERR_READ_FAILED; - break; - } + for (left = st->st_size; left > 0; left -= fsm->rdnb) { + fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left); + rc = fsmStage(fsm, FSM_DREAD); + if (rc) break; } break; case FSM_POS: - { int buf[16]; /* XXX add to fsm */ - int modulo = 4; - int amount; + left = (modulo - (fdGetCpioPos(fsm->cfd) % modulo)) % modulo; + if (left == 0) break; + fsm->wrlen = left; + (void) fsmStage(fsm, FSM_DREAD); + break; + case FSM_PAD: + memset(fsm->rdbuf, 0, 64); + left = (modulo - (fdGetCpioPos(fsm->cfd) % modulo)) % modulo; + if (left == 0) break; + fsm->rdlen = left; + (void) fsmStage(fsm, FSM_DWRITE); + break; + case FSM_HREAD: + rc = cpioHeaderRead(fsm, st); /* Read next payload header. */ + break; + case FSM_HWRITE: + rc = cpioHeaderWrite(fsm, st); /* Write next payload header. */ + break; + case FSM_DREAD: + fsm->rdnb = Fread(fsm->wrbuf, sizeof(*fsm->wrbuf), fsm->wrlen, fsm->cfd); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (wrbuf, %d, cfd)\trdnb %d\n", + cur, fsm->wrlen, fsm->rdnb); +if (fsm->rdnb != fsm->wrlen) fprintf(stderr, "*** short read, had %d, got %d\n", fsm->rdnb, fsm->wrlen); +#ifdef NOTYET + if (Ferror(fsm->rfd)) + rc = CPIOERR_READ_FAILED; +#endif + if (fsm->rdnb > 0) + fdSetCpioPos(fsm->cfd, fdGetCpioPos(fsm->cfd) + fsm->rdnb); + break; + case FSM_DWRITE: + fsm->wrnb = Fwrite(fsm->rdbuf, sizeof(*fsm->rdbuf), fsm->rdnb, fsm->cfd); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (rdbuf, %d, cfd)\twrnb %d\n", + cur, fsm->rdnb, fsm->wrnb); +if (fsm->rdnb != fsm->wrnb) fprintf(stderr, "*** short write, had %d, got %d\n", fsm->rdnb, fsm->wrnb); +#ifdef NOTYET + if (Ferror(fsm->wfd)) + rc = CPIOERR_WRITE_FAILED; +#endif + if (fsm->wrnb > 0) + fdSetCpioPos(fsm->cfd, fdGetCpioPos(fsm->cfd) + fsm->wrnb); + break; - amount = (modulo - fdGetCpioPos(fsm->cfd) % modulo) % modulo; - if (amount) - (void) ourread(fsm->cfd, buf, amount); + case FSM_ROPEN: + fsm->rfd = Fopen(fsm->path, "r.ufdio"); + if (fsm->rfd == NULL || Ferror(fsm->rfd)) { + if (fsm->rfd) (void) fsmStage(fsm, FSM_RCLOSE); + fsm->rfd = NULL; + rc = CPIOERR_OPEN_FAILED; + break; } + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s) rfd %p rdbuf %p\n", cur, + fsm->path, fsm->rfd, fsm->rdbuf); break; - case FSM_PAD: + case FSM_READ: + fsm->rdnb = Fread(fsm->rdbuf, sizeof(*fsm->rdbuf), fsm->rdlen, fsm->rfd); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (rdbuf, %d, rfd)\trdnb %d\n", + cur, fsm->rdlen, fsm->rdnb); +if (fsm->rdnb != fsm->rdlen) fprintf(stderr, "*** short read, had %d, got %d\n", fsm->rdnb, fsm->rdlen); +#ifdef NOTYET + if (Ferror(fsm->rfd)) + rc = CPIOERR_READ_FAILED; +#endif + break; + case FSM_RCLOSE: + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%p)\n", cur, fsm->rfd); + if (fsm->rfd) { + (void) Fclose(fsm->rfd); + fsm->rfd = NULL; + } + errno = saveerrno; + break; + case FSM_WOPEN: + fsm->wfd = Fopen(fsm->path, "w.ufdio"); + if (fsm->wfd == NULL || Ferror(fsm->wfd)) { + if (fsm->wfd) (void) fsmStage(fsm, FSM_WCLOSE); + fsm->wfd = NULL; + rc = CPIOERR_OPEN_FAILED; + } + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s) wfd %p wrbuf %p\n", cur, + fsm->path, fsm->wfd, fsm->wrbuf); + break; + case FSM_WRITE: + fsm->wrnb = Fwrite(fsm->wrbuf, sizeof(*fsm->wrbuf), fsm->rdnb, fsm->wfd); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (wrbuf, %d, wfd)\twrnb %d\n", + cur, fsm->rdnb, fsm->wrnb); +if (fsm->rdnb != fsm->wrnb) fprintf(stderr, "*** short write: had %d, got %d\n", fsm->rdnb, fsm->wrnb); +#ifdef NOTYET + if (Ferror(fsm->wfd)) + rc = CPIOERR_WRITE_FAILED; +#endif + break; + case FSM_WCLOSE: + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%p)\n", cur, fsm->wfd); + if (fsm->wfd) { + (void) Fclose(fsm->wfd); + fsm->wfd = NULL; + } + errno = saveerrno; break; default: @@ -1649,41 +1755,30 @@ int fsmTeardown(FSM_t fsm) { return rc; } -rpmTransactionSet fsmGetTs(FSM_t fsm) { - struct mapi * mapi = fsm->mapi; - return (mapi ? mapi->ts : NULL); -} - -TFI_t fsmGetFi(FSM_t fsm) { - struct mapi * mapi = fsm->mapi; - return (mapi ? mapi->fi : NULL); -} - -int fsmGetIndex(FSM_t fsm) { - struct mapi * mapi = fsm->mapi; - return (mapi ? mapi->isave : -1); -} - -fileAction fsmAction(FSM_t fsm, - /*@out@*/ const char ** osuffix, /*@out@*/ const char ** nsuffix) +int fsmMap(FSM_t fsm) { + struct stat * st = &fsm->sb; TFI_t fi = fsmGetFi(fsm); int i = fsmGetIndex(fsm); - fileAction action = FA_UNKNOWN; + int rc = 0; + + fsm->map = mapFind(fsm->mapi, fsm->path); + + fsm->action = FA_UNKNOWN; + fsm->osuffix = NULL; + fsm->nsuffix = NULL; if (fsm->map && fi && i >= 0 && i < fi->fc) { - action = fi->actions[i]; - if (osuffix) *osuffix = NULL; - if (nsuffix) *nsuffix = NULL; - switch (action) { + fsm->action = fi->actions[i]; + switch (fsm->action) { case FA_SKIP: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); break; case FA_SKIPMULTILIB: /* XXX RPMFILE_STATE_MULTILIB? */ -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); break; case FA_UNKNOWN: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); break; case FA_CREATE: @@ -1691,50 +1786,63 @@ fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fs break; case FA_SKIPNSTATE: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); if (fi->type == TR_ADDED) fi->fstates[i] = RPMFILE_STATE_NOTINSTALLED; break; case FA_SKIPNETSHARED: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); if (fi->type == TR_ADDED) fi->fstates[i] = RPMFILE_STATE_NETSHARED; break; case FA_BACKUP: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); switch (fi->type) { case TR_ADDED: - if (osuffix) *osuffix = SUFFIX_RPMORIG; + fsm->osuffix = SUFFIX_RPMORIG; break; case TR_REMOVED: - if (osuffix) *osuffix = SUFFIX_RPMSAVE; + fsm->osuffix = SUFFIX_RPMSAVE; break; } break; case FA_ALTNAME: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); assert(fi->type == TR_ADDED); - if (nsuffix) *nsuffix = SUFFIX_RPMNEW; + fsm->nsuffix = SUFFIX_RPMNEW; break; case FA_SAVE: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); assert(fi->type == TR_ADDED); - if (osuffix) *osuffix = SUFFIX_RPMSAVE; + fsm->osuffix = SUFFIX_RPMSAVE; break; case FA_REMOVE: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); assert(fi->type == TR_REMOVED); break; default: -fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(action), fsm->path); +fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), fsm->path); break; } + + if (fsmFlags(fsm, CPIO_MAP_PATH) || fsm->nsuffix) { + fsm->path = _free(fsm->path); + fsm->path = mapFsPath(fsm->map, st, fsm->subdir, + (fsm->suffix ? fsm->suffix : fsm->nsuffix)); + } + + if (fsmFlags(fsm, CPIO_MAP_MODE)) + st->st_mode = (st->st_mode & S_IFMT) | mapFinalMode(fsm->map); + if (fsmFlags(fsm, CPIO_MAP_UID)) + st->st_uid = mapFinalUid(fsm->map); + if (fsmFlags(fsm, CPIO_MAP_GID)) + st->st_gid = mapFinalGid(fsm->map); } - return action; + return rc; } /** @todo Verify payload MD5 sum. */ @@ -1793,161 +1901,114 @@ exit: /** * Write next item to payload stream. - * @param st stat info for item - * @param map mapping name and flags for item * @retval sizep address of no. bytes written * @param writeData should data be written? * @return 0 on success */ -static int writeFile(FSM_t fsm, const struct stat * st, /*@out@*/ size_t * sizep, - int writeData) - /*@modifies fsm->cfd, *sizep @*/ +static int writeFile(FSM_t fsm, int writeData) + /*@modifies fsm->cfd @*/ { + const char * path = fsm->path; + const char * opath = fsm->opath; const rpmTransactionSet ts = fsmGetTs(fsm); TFI_t fi = fsmGetFi(fsm); - - const char * fsPath = mapFsPath(fsm->map, NULL, NULL, NULL); - const char * archivePath = NULL; - const char * fsmPath = !fsmFlags(fsm, CPIO_MAP_PATH) - ? fsPath : (archivePath = mapArchivePath(fsm->map)); - struct cpioCrcPhysicalHeader hdr; - char buf[8192], symbuf[2048]; - dev_t num; - FD_t datafd; - size_t st_size = st->st_size; /* XXX hard links need size preserved */ - mode_t st_mode = st->st_mode; - uid_t st_uid = st->st_uid; - gid_t st_gid = st->st_gid; - size_t amount = 0; - size_t size; + struct stat * st = &fsm->sb; + size_t pos = fdGetCpioPos(fsm->cfd); + int left; int rc; + fsm->path = mapFsPath(fsm->map, NULL, NULL, NULL); + if (fsmFlags(fsm, CPIO_MAP_MODE)) - st_mode = (st_mode & S_IFMT) | mapFinalMode(fsm->map); + st->st_mode = (st->st_mode & S_IFMT) | mapFinalMode(fsm->map); if (fsmFlags(fsm, CPIO_MAP_UID)) - st_uid = mapFinalUid(fsm->map); + st->st_uid = mapFinalUid(fsm->map); if (fsmFlags(fsm, CPIO_MAP_GID)) - st_gid = mapFinalGid(fsm->map); + st->st_gid = mapFinalGid(fsm->map); - if (!writeData || S_ISDIR(st_mode)) { - st_size = 0; - } else if (S_ISLNK(st_mode)) { + if (!writeData || S_ISDIR(st->st_mode)) { + st->st_size = 0; + } else if (S_ISLNK(st->st_mode)) { /* * While linux puts the size of a symlink in the st_size field, * I don't think that's a specified standard. */ - amount = Readlink(fsPath, symbuf, sizeof(symbuf)); - if (amount <= 0) { + fsm->rdnb = st->st_size = Readlink(fsm->path, fsm->rdbuf, fsm->rdlen); + if (st->st_size <= 0) { rc = CPIOERR_READLINK_FAILED; goto exit; } - - st_size = amount; } - memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic)); - SET_NUM_FIELD(hdr.inode, st->st_ino, buf); - SET_NUM_FIELD(hdr.mode, st_mode, buf); - SET_NUM_FIELD(hdr.uid, st_uid, buf); - SET_NUM_FIELD(hdr.gid, st_gid, buf); - SET_NUM_FIELD(hdr.nlink, st->st_nlink, buf); - SET_NUM_FIELD(hdr.mtime, st->st_mtime, buf); - SET_NUM_FIELD(hdr.filesize, st_size, buf); - - num = major((unsigned)st->st_dev); SET_NUM_FIELD(hdr.devMajor, num, buf); - num = minor((unsigned)st->st_dev); SET_NUM_FIELD(hdr.devMinor, num, buf); - num = major((unsigned)st->st_rdev); SET_NUM_FIELD(hdr.rdevMajor, num, buf); - num = minor((unsigned)st->st_rdev); SET_NUM_FIELD(hdr.rdevMinor, num, buf); - - num = strlen(fsmPath) + 1; SET_NUM_FIELD(hdr.namesize, num, buf); - memcpy(hdr.checksum, "00000000", 8); - - if ((rc = safewrite(fsm->cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE) - goto exit; - if ((rc = safewrite(fsm->cfd, fsmPath, num)) != num) - goto exit; - size = PHYS_HDR_SIZE + num; - if ((rc = padoutfd(fsm->cfd, &size, 4))) + { const char * fsmPath = fsm->path; + if (fsmFlags(fsm, CPIO_MAP_PATH)) + fsm->path = mapArchivePath(fsm->map); + rc = cpioHeaderWrite(fsm, st); + fsm->path = fsmPath; + } + if (rc) goto exit; - if (writeData && S_ISREG(st_mode)) { - char *b; + if (writeData && S_ISREG(st->st_mode)) { #if HAVE_MMAP - void *mapped; + char * rdbuf = NULL; + void * mapped; size_t nmapped; #endif - /* XXX unbuffered mmap generates *lots* of fdio debugging */ - datafd = Fopen(fsPath, "r.ufdio"); - if (datafd == NULL || Ferror(datafd)) { - rc = CPIOERR_OPEN_FAILED; + rc = fsmStage(fsm, FSM_ROPEN); + if (rc) goto exit; - } + /* XXX unbuffered mmap generates *lots* of fdio debugging */ #if HAVE_MMAP nmapped = 0; - mapped = mmap(NULL, st_size, PROT_READ, MAP_SHARED, Fileno(datafd), 0); + mapped = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED, Fileno(fsm->rfd), 0); if (mapped != (void *)-1) { - b = (char *)mapped; - nmapped = st_size; - } else -#endif - { - b = buf; + rdbuf = fsm->rdbuf; + fsm->rdbuf = (char *) mapped; + fsm->rdlen = nmapped = st->st_size; } +#endif - size += st_size; + left = st->st_size; - while (st_size) { + while (left) { #if HAVE_MMAP if (mapped != (void *)-1) { - amount = nmapped; + fsm->rdnb = nmapped; } else #endif { - amount = Fread(b, sizeof(buf[0]), - (st_size > sizeof(buf) ? sizeof(buf) : st_size), - datafd); - if (amount <= 0) { - int olderrno = errno; - Fclose(datafd); - errno = olderrno; - rc = CPIOERR_READ_FAILED; - goto exit; - } + fsm->rdlen = (left > fsm->rdsize ? fsm->rdsize : left), + rc = fsmStage(fsm, FSM_READ); + if (rc) goto exit; } - if ((rc = safewrite(fsm->cfd, b, amount)) != amount) { - int olderrno = errno; - Fclose(datafd); - errno = olderrno; - goto exit; - } + rc = fsmStage(fsm, FSM_DWRITE); + if (rc) goto exit; - st_size -= amount; + left -= fsm->wrnb; } #if HAVE_MMAP if (mapped != (void *)-1) { /*@-noeffect@*/ munmap(mapped, nmapped) /*@=noeffect@*/; + fsm->rdbuf = rdbuf; } #endif - Fclose(datafd); - } else if (writeData && S_ISLNK(st_mode)) { - if ((rc = safewrite(fsm->cfd, symbuf, amount)) != amount) + } else if (writeData && S_ISLNK(st->st_mode)) { + rc = fsmStage(fsm, FSM_DWRITE); + if (rc) goto exit; - size += amount; } - /* this is a noop for most file types */ - if ((rc = padoutfd(fsm->cfd, &size, 4))) - goto exit; - - if (sizep) - *sizep = size; + rc = fsmStage(fsm, FSM_PAD); + if (rc) goto exit; if (ts && fi && ts->notify) { + size_t size = (fdGetCpioPos(fsm->cfd) - pos); (void)ts->notify(fi->h, RPMCALLBACK_INST_PROGRESS, size, size, (fi->ap ? fi->ap->key : NULL), ts->notifyData); } @@ -1955,44 +2016,41 @@ static int writeFile(FSM_t fsm, const struct stat * st, /*@out@*/ size_t * sizep rc = 0; exit: - fsPath = _free(fsPath); + if (fsm->rfd) + (void) fsmStage(fsm, FSM_RCLOSE); + fsm->opath = _free(fsm->opath); + fsm->opath = opath; + fsm->path = _free(fsm->path); + fsm->path = path; return rc; } /** * Write set of linked files to payload stream. * @param hlink set of linked files - * @retval sizep address of no. bytes written * @return 0 on success */ -static int writeLinkedFile(FSM_t fsm, - const struct hardLink * hlink, /*@out@*/size_t * sizep) - /*@modifies fsm->cfd, *sizep, *fsm->failedFile @*/ +static int writeLinkedFile(FSM_t fsm, const struct hardLink * hlink) + /*@modifies fsm->cfd, *fsm->failedFile @*/ { - size_t total = 0; - size_t size; int rc = 0; int i; for (i = hlink->nlink - 1; i > hlink->linksLeft; i--) { + (void) fsmSetIndex(fsm, hlink->filex[i]); fsm->map = hlink->fileMaps[i]; - if ((rc = writeFile(fsm, &hlink->sb, &size, 0)) != 0) + fsm->sb = hlink->sb; /* structure assignment */ + if ((rc = writeFile(fsm, 0)) != 0) goto exit; - total += size; fsm->map = mapFree(fsm->map); } i = hlink->linksLeft; + (void) fsmSetIndex(fsm, hlink->filex[i]); fsm->map = hlink->fileMaps[i]; - if ((rc = writeFile(fsm, &hlink->sb, &size, 1))) { - if (sizep) - *sizep = total; + fsm->sb = hlink->sb; /* structure assignment */ + if ((rc = writeFile(fsm, 1))) goto exit; - } - total += size; - - if (sizep) - *sizep = total; rc = 0; @@ -2008,10 +2066,10 @@ int cpioBuildArchive(FSM_t fsm) /*@-fullinitblock@*/ struct hardLink hlinkList = { NULL }; /*@=fullinitblock@*/ - struct stat * st = (struct stat *) &hlinkList.sb; + struct stat * st = &fsm->sb; + struct stat * ost = &fsm->osb; struct hardLink * hlink; - size_t archiveSize = 0; - size_t size; + size_t pos = fdGetCpioPos(fsm->cfd); int rc; hlinkList.next = NULL; @@ -2021,39 +2079,39 @@ int cpioBuildArchive(FSM_t fsm) fsm->path = mapFsPath(fsm->map, NULL, NULL, NULL); if (fsmFlags(fsm, CPIO_FOLLOW_SYMLINKS)) - rc = Stat(fsm->path, st); + rc = Stat(fsm->path, ost); else - rc = Lstat(fsm->path, st); + rc = Lstat(fsm->path, ost); if (rc) { - rc = CPIOERR_STAT_FAILED; goto exit; } - if (!S_ISDIR(st->st_mode) && st->st_nlink > 1) { + if (!S_ISDIR(ost->st_mode) && ost->st_nlink > 1) { hlink = hlinkList.next; while (hlink && - (hlink->dev != st->st_dev || hlink->inode != st->st_ino)) + (hlink->dev != ost->st_dev || hlink->inode != ost->st_ino)) hlink = hlink->next; if (hlink == NULL) { - hlink = newHardLink(st, HARDLINK_BUILD); + hlink = newHardLink(ost, HARDLINK_BUILD); hlink->next = hlinkList.next; hlinkList.next = hlink; } - hlink->fileMaps[--hlink->linksLeft] = mapLink(fsm->map); + --hlink->linksLeft; + hlink->filex[hlink->linksLeft] = fsmGetIndex(fsm); + hlink->fileMaps[hlink->linksLeft] = mapLink(fsm->map); if (hlink->linksLeft == 0) { struct hardLink * prev; - rc = writeLinkedFile(fsm, hlink, &size); + rc = writeLinkedFile(fsm, hlink); if (rc) { + /* XXX WTFO? */ fsm->path = _free(fsm->path); goto exit; } - archiveSize += size; - prev = &hlinkList; do { if (prev->next != hlink) @@ -2065,9 +2123,9 @@ int cpioBuildArchive(FSM_t fsm) } while ((prev = prev->next) != NULL); } } else { - if ((rc = writeFile(fsm, st, &size, 1))) - goto exit; - archiveSize += size; + *st = *ost; /* structure assignment */ + rc = writeFile(fsm, 1); + if (rc) goto exit; } fsm->path = _free(fsm->path); } @@ -2076,33 +2134,31 @@ int cpioBuildArchive(FSM_t fsm) while ((hlink = hlinkList.next) != NULL) { hlinkList.next = hlink->next; hlink->next = NULL; - if (rc == 0) { - rc = writeLinkedFile(fsm, hlink, &size); - archiveSize += size; - } + if (!rc) + rc = writeLinkedFile(fsm, hlink); hlink = freeHardLink(hlink); } - if (rc) - goto exit; - - { struct cpioCrcPhysicalHeader hdr; - 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); - if ((rc = safewrite(fsm->cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE) - goto exit; - if ((rc = safewrite(fsm->cfd, "TRAILER!!!", 11)) != 11) - goto exit; - archiveSize += PHYS_HDR_SIZE + 11; + if (rc) goto exit; + + { struct cpioCrcPhysicalHeader * hdr = (struct cpioCrcPhysicalHeader *)fsm->rdbuf; + 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, "TRAILER!!!", 11); + fsm->wrlen = PHYS_HDR_SIZE + 11; + rc = fsmStage(fsm, FSM_DWRITE); + if (rc) goto exit; } - /* GNU cpio pads to 512 bytes here, but we don't. I'm not sure if - it matters or not */ - - rc = padoutfd(fsm->cfd, &archiveSize, 4); + /* + * GNU cpio pads to 512 bytes here, but we don't. This matters only + * for tape devices and/or multiple archives. + */ + rc = fsmStage(fsm, FSM_PAD); - if (!rc && fsm->archiveSize) *fsm->archiveSize = archiveSize; + if (!rc && fsm->archiveSize) + *fsm->archiveSize = (fdGetCpioPos(fsm->cfd) - pos); exit: if (rc && fsm->path && fsm->failedFile && *fsm->failedFile == NULL) diff --git a/lib/rollback.c b/lib/rollback.c index 37d3e7d9f..a1b880557 100644 --- a/lib/rollback.c +++ b/lib/rollback.c @@ -203,6 +203,18 @@ void freeFi(TFI_t fi) case FSM_EAT: return "eat"; case FSM_POS: return "pos"; case FSM_PAD: return "pad"; + case FSM_HREAD: return "hread"; + case FSM_HWRITE: return "hwrite"; + case FSM_DREAD: return "Fread"; + case FSM_DWRITE: return "Fwrite"; + + case FSM_ROPEN: return "Fopen"; + case FSM_READ: return "Fread"; + case FSM_RCLOSE: return "Fclose"; + case FSM_WOPEN: return "Fopen"; + case FSM_WRITE: return "Fwrite"; + case FSM_WCLOSE: return "Fclose"; + default: return "???"; } /*@noteached@*/ diff --git a/lib/rollback.h b/lib/rollback.h index b756e5300..fcb563b28 100644 --- a/lib/rollback.h +++ b/lib/rollback.h @@ -15,16 +15,20 @@ typedef /*@abstract@*/ struct cpioHeader * FSM_t; /** */ -#define FSM_INTERNAL 0x8000 -#define FSM_QUIET 0x4000 +#define FSM_VERBOSE 0x8000 +#define FSM_INTERNAL 0x4000 +#define FSM_SYSCALL 0x2000 +#define FSM_DEAD 0x1000 +#define _fv(_a) ((_a) | FSM_VERBOSE) #define _fi(_a) ((_a) | FSM_INTERNAL) -#define _fq(_a) ((_a) | FSM_QUIET) +#define _fs(_a) ((_a) | (FSM_INTERNAL | FSM_SYSCALL)) +#define _fd(_a) ((_a) | (FSM_INTERNAL | FSM_DEAD)) typedef enum fileStage_e { FSM_UNKNOWN = 0, - FSM_INIT = _fq(1), - FSM_PRE = _fq(2), - FSM_PROCESS = _fq(3), - FSM_POST = _fq(4), + FSM_INIT = _fv(1), + FSM_PRE = _fv(2), + FSM_PROCESS = _fv(3), + FSM_POST = _fv(4), FSM_UNDO = 5, FSM_COMMIT = 6, @@ -37,31 +41,42 @@ typedef enum fileStage_e { FSM_MKDIRS = _fi(19), FSM_RMDIRS = _fi(20), FSM_MKLINKS = _fi(21), - FSM_NOTIFY = _fi(22), + FSM_NOTIFY = _fd(22), FSM_DESTROY = _fi(23), - FSM_VERIFY = _fi(24), - FSM_FINALIZE= _fi(25), - - FSM_UNLINK = _fi(33), - FSM_RENAME = _fi(34), - FSM_MKDIR = _fi(35), - FSM_RMDIR = _fi(36), - FSM_CHOWN = _fi(37), - FSM_LCHOWN = _fi(38), - FSM_CHMOD = _fi(39), - FSM_UTIME = _fi(40), - FSM_SYMLINK = _fi(41), - FSM_LINK = _fi(42), - FSM_MKFIFO = _fi(43), - FSM_MKNOD = _fi(44), - FSM_LSTAT = _fi(45), - FSM_STAT = _fi(46), - FSM_CHROOT = _fi(47), - - FSM_NEXT = _fi(65), + FSM_VERIFY = _fd(24), + FSM_FINALIZE= _fd(25), + + FSM_UNLINK = _fs(33), + FSM_RENAME = _fs(34), + FSM_MKDIR = _fs(35), + FSM_RMDIR = _fs(36), + FSM_CHOWN = _fs(37), + FSM_LCHOWN = _fs(38), + FSM_CHMOD = _fs(39), + FSM_UTIME = _fs(40), + FSM_SYMLINK = _fs(41), + FSM_LINK = _fs(42), + FSM_MKFIFO = _fs(43), + FSM_MKNOD = _fs(44), + FSM_LSTAT = _fs(45), + FSM_STAT = _fs(46), + FSM_CHROOT = _fs(47), + + FSM_NEXT = _fd(65), FSM_EAT = _fi(66), - FSM_POS = _fi(67), - FSM_PAD = _fi(68), + FSM_POS = _fd(67), + FSM_PAD = _fd(68), + FSM_HREAD = _fd(69), + FSM_HWRITE = _fd(70), + FSM_DREAD = _fs(71), + FSM_DWRITE = _fs(72), + + FSM_ROPEN = _fs(129), + FSM_READ = _fs(130), + FSM_RCLOSE = _fs(131), + FSM_WOPEN = _fs(132), + FSM_WRITE = _fs(133), + FSM_WCLOSE = _fs(134), } fileStage; #undef _fi @@ -261,9 +276,9 @@ int fsmTeardown(FSM_t fsm); int fsmGetIndex(FSM_t fsm); /** + * @return 0 always */ -fileAction fsmAction(FSM_t fsm, - /*@out@*/ const char ** osuffix, /*@out@*/ const char ** suffix); +int fsmMap(FSM_t fsm); /** * Archive extraction state machine. diff --git a/po/rpm.pot b/po/rpm.pot index 87754b2fa..105a20754 100644 --- a/po/rpm.pot +++ b/po/rpm.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2001-02-02 09:58-0500\n" +"POT-Creation-Date: 2001-02-03 09:18-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -1472,7 +1472,7 @@ msgstr "" msgid "no tar files given for build" msgstr "" -#: build/build.c:114 build/pack.c:387 +#: build/build.c:114 build/pack.c:382 msgid "Unable to open temp file.\n" msgstr "" @@ -1662,7 +1662,7 @@ msgstr "" msgid "Could not open %%files file %s: %s\n" msgstr "" -#: build/files.c:1461 build/pack.c:123 +#: build/files.c:1461 build/pack.c:118 #, c-format msgid "line: %s\n" msgstr "" @@ -1729,126 +1729,126 @@ msgstr "" msgid "Could not canonicalize hostname: %s\n" msgstr "" -#: build/pack.c:67 +#: build/pack.c:62 #, c-format msgid "create archive failed on file %s: %s\n" msgstr "" -#: build/pack.c:89 +#: build/pack.c:84 #, c-format msgid "cpio_copy write failed: %s\n" msgstr "" -#: build/pack.c:96 +#: build/pack.c:91 #, c-format msgid "cpio_copy read failed: %s\n" msgstr "" -#: build/pack.c:180 +#: build/pack.c:175 #, c-format msgid "Could not open PreIn file: %s\n" msgstr "" -#: build/pack.c:187 +#: build/pack.c:182 #, c-format msgid "Could not open PreUn file: %s\n" msgstr "" -#: build/pack.c:194 +#: build/pack.c:189 #, c-format msgid "Could not open PostIn file: %s\n" msgstr "" -#: build/pack.c:201 +#: build/pack.c:196 #, c-format msgid "Could not open PostUn file: %s\n" msgstr "" -#: build/pack.c:209 +#: build/pack.c:204 #, c-format msgid "Could not open VerifyScript file: %s\n" msgstr "" -#: build/pack.c:224 +#: build/pack.c:219 #, c-format msgid "Could not open Trigger script file: %s\n" msgstr "" -#: build/pack.c:250 +#: build/pack.c:245 #, c-format msgid "readRPM: open %s: %s\n" msgstr "" -#: build/pack.c:260 +#: build/pack.c:255 #, c-format msgid "readRPM: read %s: %s\n" msgstr "" -#: build/pack.c:281 +#: build/pack.c:276 #, c-format msgid "readRPM: %s is not an RPM package\n" msgstr "" -#: build/pack.c:287 +#: build/pack.c:282 #, c-format msgid "readRPM: reading header from %s\n" msgstr "" -#: build/pack.c:399 +#: build/pack.c:394 msgid "Bad CSA data\n" msgstr "" -#: build/pack.c:440 +#: build/pack.c:435 #, c-format msgid "Generating signature: %d\n" msgstr "" -#: build/pack.c:450 +#: build/pack.c:445 #, c-format msgid "Could not open %s: %s\n" msgstr "" -#: build/pack.c:487 +#: build/pack.c:482 #, c-format msgid "Unable to write package: %s\n" msgstr "" -#: build/pack.c:502 +#: build/pack.c:497 #, c-format msgid "Unable to open sigtarget %s: %s\n" msgstr "" -#: build/pack.c:512 +#: build/pack.c:507 #, c-format msgid "Unable to read header from %s: %s\n" msgstr "" -#: build/pack.c:526 +#: build/pack.c:521 #, c-format msgid "Unable to write header to %s: %s\n" msgstr "" -#: build/pack.c:536 +#: build/pack.c:531 #, c-format msgid "Unable to read payload from %s: %s\n" msgstr "" -#: build/pack.c:542 +#: build/pack.c:537 #, c-format msgid "Unable to write payload to %s: %s\n" msgstr "" -#: build/pack.c:569 +#: build/pack.c:564 #, c-format msgid "Wrote: %s\n" msgstr "" -#: build/pack.c:634 +#: build/pack.c:629 #, c-format msgid "Could not generate output filename for package %s: %s\n" msgstr "" -#: build/pack.c:651 +#: build/pack.c:646 #, c-format msgid "cannot create %s: %s\n" msgstr "" @@ -2185,89 +2185,89 @@ msgstr "" msgid "line %d: Bad %s number: %s\n" msgstr "" -#: lib/cpio.c:343 lib/install.c:833 +#: lib/cpio.c:355 lib/install.c:833 #, c-format msgid " file: %s%s action: %s\n" msgstr "" -#: lib/cpio.c:378 +#: lib/cpio.c:390 #, c-format msgid "%s: cannot remove %s - directory not empty\n" msgstr "" -#: lib/cpio.c:383 +#: lib/cpio.c:395 #, c-format msgid "%s rmdir of %s failed: %s\n" msgstr "" -#: lib/cpio.c:394 +#: lib/cpio.c:406 #, c-format msgid "%s removal of %s failed: %s\n" msgstr "" -#: lib/cpio.c:409 +#: lib/cpio.c:421 #, c-format msgid "%s: %s saved as %s\n" msgstr "" -#: lib/cpio.c:415 +#: lib/cpio.c:427 #, c-format msgid "%s rename of %s to %s failed: %s\n" msgstr "" -#: lib/cpio.c:508 +#: lib/cpio.c:520 msgid "========= Directories not explictly included in package:\n" msgstr "" -#: lib/cpio.c:510 +#: lib/cpio.c:522 #, c-format msgid "%9d %s\n" msgstr "" -#: lib/cpio.c:861 +#: lib/cpio.c:853 #, c-format msgid "%s saved as %s\n" msgstr "" -#: lib/cpio.c:1391 +#: lib/cpio.c:1371 #, c-format msgid "%s created as %s\n" msgstr "" -#: lib/cpio.c:2124 +#: lib/cpio.c:2180 #, c-format msgid "(error 0x%x)" msgstr "" -#: lib/cpio.c:2127 +#: lib/cpio.c:2183 msgid "Bad magic" msgstr "" -#: lib/cpio.c:2128 +#: lib/cpio.c:2184 msgid "Bad/unreadable header" msgstr "" -#: lib/cpio.c:2149 +#: lib/cpio.c:2205 msgid "Header size too big" msgstr "" -#: lib/cpio.c:2150 +#: lib/cpio.c:2206 msgid "Unknown file type" msgstr "" -#: lib/cpio.c:2151 +#: lib/cpio.c:2207 msgid "Missing hard link" msgstr "" -#: lib/cpio.c:2152 +#: lib/cpio.c:2208 msgid "MD5 sum mismatch" msgstr "" -#: lib/cpio.c:2153 +#: lib/cpio.c:2209 msgid "Internal error" msgstr "" -#: lib/cpio.c:2162 +#: lib/cpio.c:2218 msgid " failed - " msgstr "" |