diff options
-rw-r--r-- | Doxyfile.in | 1 | ||||
-rw-r--r-- | lib/Makefile.am | 3 | ||||
-rw-r--r-- | lib/cpio.c | 234 | ||||
-rw-r--r-- | lib/install.c | 458 | ||||
-rw-r--r-- | lib/install.h | 68 | ||||
-rw-r--r-- | lib/transaction.c | 82 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | po/rpm.pot | 76 |
8 files changed, 465 insertions, 458 deletions
diff --git a/Doxyfile.in b/Doxyfile.in index 9a8c76962..c9ec29b49 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -302,6 +302,7 @@ INPUT = \ ./lib/poptQV.c \ ./lib/problems.c \ ./lib/query.c \ + ./lib/rollback.c \ ./lib/rpmchecksig.c \ ./lib/rpmdb.c \ ./lib/rpmdb.h \ diff --git a/lib/Makefile.am b/lib/Makefile.am index 3f9729f8f..a20594c75 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -25,7 +25,8 @@ librpm_la_SOURCES = \ cpio.c $(DBLIBSRCS) depends.c \ formats.c fprint.c fs.c hash.c header.c install.c \ md5.c md5sum.c misc.c package.c problems.c \ - poptBT.c poptQV.c query.c rpmchecksig.c rpmdb.c rpminstall.c \ + poptBT.c poptQV.c query.c rollback.c \ + rpmchecksig.c rpmdb.c rpminstall.c \ rpmlead.c rpmlibprov.c rpmrc.c scriptlet.c signature.c stringbuf.c \ tagName.c tagtable.c transaction.c uninstall.c verify.c librpm_la_LDFLAGS = @libdb3@ @libdb2@ @libdb1@ diff --git a/lib/cpio.c b/lib/cpio.c index 000d0848c..03c7e978c 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -24,7 +24,7 @@ struct hardLink { struct hardLink * next; const char ** files; /* nlink of these, used by install */ - int * fileMaps; /* used by build */ + const struct cpioFileMapping ** fileMaps; dev_t dev; ino_t inode; int nlink; @@ -79,6 +79,75 @@ static void prtli(const char *msg, struct hardLink * li) } #endif +static int mapFlags(const void * this, cpioMapFlags mask) { + const struct cpioFileMapping * map = this; + return (map->mapFlags & mask); +} + +static const char * mapArchivePath(const void * this) { + const struct cpioFileMapping * map = this; + return map->archivePath; +} + +static /*@only@*/ const char * mapFsPath(const void * this) { + const struct cpioFileMapping * map = this; + char * t = xmalloc( strlen(map->dirName) + strlen(map->baseName) + 1); + (void) stpcpy( stpcpy(t, map->dirName), map->baseName); + return t; +} + +static mode_t mapFinalMode(const void * this) { + const struct cpioFileMapping * map = this; + return map->finalMode; +} + +static uid_t mapFinalUid(const void * this) { + const struct cpioFileMapping * map = this; + return map->finalUid; +} + +static gid_t mapFinalGid(const void * this) { + const struct cpioFileMapping * map = this; + return map->finalGid; +} + +static const char * mapMd5sum(const void * this) { + const struct cpioFileMapping * map = this; + return map->md5sum; +} + +struct mapi { + const struct cpioFileMapping * mappings; + int numMappings; + int i; +}; + +static void mapFreeIterator(/*@only@*/ void * mi) { + free(mi); +} + +static void * mapInitIterator(const struct cpioFileMapping * mappings, + int numMappings) +{ + struct mapi * mapi = xmalloc(sizeof(*mapi)); + mapi->mappings = mappings; + mapi->numMappings = numMappings; + mapi->i = 0; + return mapi; +} + +static const struct cpioFileMapping * mapNextIterator(void * mi) +{ + struct mapi * mapi = mi; + const struct cpioFileMapping * map; + + if (!(mapi->i < mapi->numMappings)) + return NULL; + map = mapi->mappings + mapi->i; + mapi->i++; + return map; +} + /** * Read data from payload. * @param cfd payload file handle @@ -298,29 +367,23 @@ int cpioFileMapCmp(const void * a, const void * b) static int createDirectory(const char * path, mode_t perms) /*@modifies fileSystem @*/ { - struct stat sb; + struct stat st; - if (!lstat(path, &sb)) { - int dounlink = 0; /* XXX eliminate, dounlink==1 on all paths */ - if (S_ISDIR(sb.st_mode)) { + if (!lstat(path, &st)) { + if (S_ISDIR(st.st_mode)) return 0; - } else if (S_ISLNK(sb.st_mode)) { - if (stat(path, &sb)) { + if (S_ISLNK(st.st_mode)) { + if (stat(path, &st)) { if (errno != ENOENT) return CPIOERR_STAT_FAILED; - dounlink = 1; } else { - if (S_ISDIR(sb.st_mode)) + if (S_ISDIR(st.st_mode)) return 0; - dounlink = 1; } - } else { - dounlink = 1; } - if (dounlink && unlink(path)) { + if (unlink(path)) return CPIOERR_UNLINK_FAILED; - } } if (mkdir(path, 000)) @@ -728,7 +791,6 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings, { struct cpioHeader ch, *hdr = &ch; struct cpioFileMapping * map = NULL; - struct cpioFileMapping needle; struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 }; struct hardLink * links = NULL; struct hardLink * li = NULL; @@ -766,6 +828,7 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings, break; if (mappings) { + struct cpioFileMapping needle; needle.archivePath = hdr->path; map = bsearch(&needle, mappings, numMappings, sizeof(needle), cpioFileMapCmp); @@ -775,20 +838,17 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings, eatBytes(cfd, st->st_size); } else { if (map) { - if (map->mapFlags & CPIO_MAP_PATH) { - char * t = xmalloc( strlen(map->dirName) + - strlen(map->baseName) + 1); - (void) stpcpy( stpcpy(t, map->dirName), map->baseName); + if (mapFlags(map, CPIO_MAP_PATH)) { if (hdr->path) free((void *)hdr->path); - hdr->path = t; + hdr->path = mapFsPath(map); } - if (map->mapFlags & CPIO_MAP_MODE) - st->st_mode = map->finalMode; - if (map->mapFlags & CPIO_MAP_UID) - st->st_uid = map->finalUid; - if (map->mapFlags & CPIO_MAP_GID) - st->st_gid = map->finalGid; + if (mapFlags(map, CPIO_MAP_MODE)) + st->st_mode = mapFinalMode(map); + if (mapFlags(map, CPIO_MAP_UID)) + st->st_uid = mapFinalUid(map); + if (mapFlags(map, CPIO_MAP_GID)) + st->st_gid = mapFinalGid(map); } /* This won't get hard linked symlinks right, but I can't seem @@ -826,7 +886,8 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings, if (!rc) { if (S_ISREG(st->st_mode)) - rc = expandRegular(cfd, hdr, map->md5sum, cb, cbData); + rc = expandRegular(cfd, hdr, mapMd5sum(map), + cb, cbData); else if (S_ISDIR(st->st_mode)) rc = createDirectory(hdr->path, 000); else if (S_ISLNK(st->st_mode)) @@ -918,41 +979,38 @@ static int writeFile(FD_t cfd, const struct stat * st, int writeData) /*@modifies cfd, *sizep @*/ { + const char * fsPath = mapFsPath(map); + const char * archivePath = !mapFlags(map, CPIO_MAP_PATH) + ? fsPath : mapArchivePath(map); struct cpioCrcPhysicalHeader hdr; - char * fsPath = alloca(strlen(map->dirName) + strlen(map->baseName) + 1); char buf[8192], symbuf[2048]; dev_t num; FD_t datafd; size_t st_size = st->st_size; /* XXX hard links need size preserved */ - const char * archivePath; mode_t st_mode = st->st_mode; uid_t st_uid = st->st_uid; gid_t st_gid = st->st_gid; size_t size, amount = 0; int rc; - *fsPath = '\0'; - (void) stpcpy( stpcpy(fsPath, map->dirName), map->baseName); - - archivePath = (!(map->mapFlags & CPIO_MAP_PATH)) - ? fsPath : map->archivePath; - - if (map->mapFlags & CPIO_MAP_MODE) - st_mode = (st_mode & S_IFMT) | map->finalMode; - if (map->mapFlags & CPIO_MAP_UID) - st_uid = map->finalUid; - if (map->mapFlags & CPIO_MAP_GID) - st_gid = map->finalGid; + if (mapFlags(map, CPIO_MAP_MODE)) + st_mode = (st_mode & S_IFMT) | mapFinalMode(map); + if (mapFlags(map, CPIO_MAP_UID)) + st_uid = mapFinalUid(map); + if (mapFlags(map, CPIO_MAP_GID)) + st_gid = mapFinalGid(map); if (!writeData || S_ISDIR(st_mode)) { st_size = 0; } else if (S_ISLNK(st_mode)) { - /* While linux puts the size of a symlink in the st_size field, - I don't think that's a specified standard */ - + /* + * 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) { - return CPIOERR_READLINK_FAILED; + rc = CPIOERR_READLINK_FAILED; + goto exit; } st_size = amount; @@ -976,12 +1034,12 @@ static int writeFile(FD_t cfd, const struct stat * st, memcpy(hdr.checksum, "00000000", 8); if ((rc = safewrite(cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE) - return rc; + goto exit; if ((rc = safewrite(cfd, archivePath, num)) != num) - return rc; + goto exit; size = PHYS_HDR_SIZE + num; if ((rc = padoutfd(cfd, &size, 4))) - return rc; + goto exit; if (writeData && S_ISREG(st_mode)) { char *b; @@ -992,8 +1050,10 @@ static int writeFile(FD_t cfd, const struct stat * st, /* XXX unbuffered mmap generates *lots* of fdio debugging */ datafd = Fopen(fsPath, "r.ufdio"); - if (datafd == NULL || Ferror(datafd)) - return CPIOERR_OPEN_FAILED; + if (datafd == NULL || Ferror(datafd)) { + rc = CPIOERR_OPEN_FAILED; + goto exit; + } #if HAVE_MMAP nmapped = 0; @@ -1023,7 +1083,8 @@ static int writeFile(FD_t cfd, const struct stat * st, int olderrno = errno; Fclose(datafd); errno = olderrno; - return CPIOERR_READ_FAILED; + rc = CPIOERR_READ_FAILED; + goto exit; } } @@ -1031,7 +1092,7 @@ static int writeFile(FD_t cfd, const struct stat * st, int olderrno = errno; Fclose(datafd); errno = olderrno; - return rc; + goto exit; } st_size -= amount; @@ -1046,25 +1107,27 @@ static int writeFile(FD_t cfd, const struct stat * st, Fclose(datafd); } else if (writeData && S_ISLNK(st_mode)) { if ((rc = safewrite(cfd, symbuf, amount)) != amount) - return rc; + goto exit; size += amount; } /* this is a noop for most file types */ if ((rc = padoutfd(cfd, &size, 4))) - return rc; + goto exit; if (sizep) *sizep = size; + rc = 0; - return 0; +exit: + if (fsPath) free((void *)fsPath); + return rc; } /** * Write set of linked files to payload stream. * @param cfd payload file handle * @param hlink set of linked files - * @param mappings mapping name and flags for linked files * @param cb callback function * @param cbData callback private data * @retval sizep address of no. bytes written @@ -1072,7 +1135,6 @@ static int writeFile(FD_t cfd, const struct stat * st, * @return 0 on success */ static int writeLinkedFile(FD_t cfd, const struct hardLink * hlink, - const struct cpioFileMapping * mappings, cpioCallback cb, void * cbData, /*@out@*/size_t * sizep, /*@out@*/const char ** failedFile) @@ -1081,39 +1143,32 @@ static int writeLinkedFile(FD_t cfd, const struct hardLink * hlink, struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 }; size_t total = 0; const struct cpioFileMapping * map; - char * t; size_t size; int i, rc; for (i = hlink->nlink - 1; i > hlink->linksLeft; i--) { - map = mappings + hlink->fileMaps[i]; + map = hlink->fileMaps[i]; if ((rc = writeFile(cfd, &hlink->sb, map, &size, 0)) != 0) { - if (failedFile) { - t = xmalloc(strlen(map->dirName) + strlen(map->baseName) + 1); - (void) stpcpy( stpcpy(t, map->dirName), map->baseName); - *failedFile = t; - } + if (failedFile) + *failedFile = mapFsPath(map);; return rc; } total += size; if (cb) { - cbInfo.file = mappings[i].archivePath; + cbInfo.file = mapArchivePath(map); cb(&cbInfo, cbData); } } i = hlink->linksLeft; - map = mappings + hlink->fileMaps[i]; + map = hlink->fileMaps[i]; if ((rc = writeFile(cfd, &hlink->sb, map, &size, 1))) { if (sizep) *sizep = total; - if (failedFile) { - t = xmalloc(strlen(map->dirName) + strlen(map->baseName) + 1); - (void) stpcpy( stpcpy(t, map->dirName), map->baseName); - *failedFile = t; - } + if (failedFile) + *failedFile = mapFsPath(map);; return rc; } total += size; @@ -1122,7 +1177,7 @@ static int writeLinkedFile(FD_t cfd, const struct hardLink * hlink, *sizep = total; if (cb) { - cbInfo.file = mappings[i].archivePath; + cbInfo.file = mapArchivePath(map); cb(&cbInfo, cbData); } @@ -1135,7 +1190,6 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings, { size_t size, totalsize = 0; int rc; - int i; struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 }; struct cpioCrcPhysicalHeader hdr; /*@-fullinitblock@*/ @@ -1143,25 +1197,25 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings, /*@=fullinitblock@*/ struct stat * st = (struct stat *) &hlinkList.sb; struct hardLink * hlink; + void * mapi; + const struct cpioFileMapping * map; hlinkList.next = NULL; - for (i = 0; i < numMappings; i++) { - const struct cpioFileMapping * map; - char fsPath[8192]; + mapi = mapInitIterator(mappings, numMappings); + while ((map = mapNextIterator(mapi)) != NULL) { + const char * fsPath; - map = mappings + i; - fsPath[0] = '\0'; - (void) stpcpy( stpcpy(fsPath, map->dirName), map->baseName); + fsPath = mapFsPath(map); - if (map->mapFlags & CPIO_FOLLOW_SYMLINKS) + if (mapFlags(map, CPIO_FOLLOW_SYMLINKS)) rc = Stat(fsPath, st); else rc = Lstat(fsPath, st); if (rc) { if (failedFile) - *failedFile = xstrdup(fsPath); + *failedFile = fsPath; return CPIOERR_STAT_FAILED; } @@ -1176,13 +1230,15 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings, hlinkList.next = hlink; } - hlink->fileMaps[--hlink->linksLeft] = i; + hlink->fileMaps[--hlink->linksLeft] = map; if (hlink->linksLeft == 0) { struct hardLink * prev; - if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData, - &size, failedFile))) + rc = writeLinkedFile(cfd, hlink, cb, cbData, &size, failedFile); + if (rc) { + free((void *)fsPath); return rc; + } totalsize += size; @@ -1200,18 +1256,21 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings, } else { if ((rc = writeFile(cfd, st, map, &size, 1))) { if (failedFile) - *failedFile = xstrdup(fsPath); + *failedFile = fsPath; return rc; } if (cb) { - cbInfo.file = map->archivePath; + cbInfo.file = mapArchivePath(map); cb(&cbInfo, cbData); } totalsize += size; } + free((void *)fsPath); + fsPath = NULL; } + mapFreeIterator(mapi); rc = 0; while ((hlink = hlinkList.next) != NULL) { @@ -1219,8 +1278,7 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings, hlink->next = NULL; if (rc == 0) { - rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData, - &size, failedFile); + rc = writeLinkedFile(cfd, hlink, cb, cbData, &size, failedFile); totalsize += size; } freeHardLink(hlink); diff --git a/lib/install.c b/lib/install.c index 07a3c1612..8ac628423 100644 --- a/lib/install.c +++ b/lib/install.c @@ -19,34 +19,24 @@ /** * Private data for cpio callback. */ -struct callbackInfo { +typedef struct callbackInfo_s { unsigned long archiveSize; rpmCallbackFunction notify; const char ** specFilePtr; Header h; rpmCallbackData notifyData; const void * pkgKey; -}; - -/** - * Keeps track of memory allocated while accessing header tags. - */ -typedef struct fileMemory_s { -/*@owned@*/ const char ** dnl; -/*@owned@*/ const char ** bnl; -/*@owned@*/ const char ** cpioNames; -/*@owned@*/ const char ** md5sums; -/*@owned@*/ struct fileInfo * files; -} * fileMemory; +} * cbInfo; /** * Header file info, gathered per-file, rather than per-tag. */ -struct fileInfo { +typedef struct fileInfo_s { /*@dependent@*/ const char * cpioPath; -/*@dependent@*/ const char * relativePath; /* relative to root */ /*@dependent@*/ const char * dn; /* relative to root */ /*@dependent@*/ const char * bn; +/*@observer@*/ const char * bnsuffix; +/*@observer@*/ const char * oext; /*@dependent@*/ const char * md5sum; uid_t uid; gid_t gid; @@ -56,7 +46,18 @@ struct fileInfo { char state; enum fileActions action; int install; -} ; +} * XFI_t ; + +/** + * Keeps track of memory allocated while accessing header tags. + */ +typedef struct fileMemory_s { +/*@owned@*/ const char ** dnl; +/*@owned@*/ const char ** bnl; +/*@owned@*/ const char ** cpioNames; +/*@owned@*/ const char ** md5sums; +/*@owned@*/ XFI_t files; +} * fileMemory; /* XXX add more tags */ /** @@ -88,7 +89,7 @@ static int rpmInstallLoadMacros(Header h) int_32 * i32p; } body; char numbuf[32]; - int type; + int_32 type; for (tagm = tagMacros; tagm->macroname != NULL; tagm++) { if (!headerGetEntry(h, tagm->tag, &type, (void **) &body, NULL)) @@ -150,7 +151,7 @@ static void freeFileMemory( /*@only@*/ fileMemory fileMem) static int assembleFileList(TFI_t fi, Header h, /*@out@*/ fileMemory * memPtr, /*@out@*/ int * fileCountPtr, - /*@out@*/ struct fileInfo ** filesPtr, + /*@out@*/ XFI_t * filesPtr, int stripPrefixLength) { enum fileActions * actions; @@ -160,8 +161,8 @@ static int assembleFileList(TFI_t fi, Header h, uint_32 * fsizes; uint_16 * fmodes; fileMemory mem = newFileMemory(); - struct fileInfo * files; - struct fileInfo * file; + XFI_t files; + XFI_t file; int fileCount; int i; @@ -229,30 +230,29 @@ static int assembleFileList(TFI_t fi, Header h, * @param files install file information * @param fileCount install file count */ -static void setFileOwners(Header h, struct fileInfo * files, int fileCount) +static void setFileOwners(Header h, XFI_t files, int fileCount) { - char ** fileOwners; - char ** fileGroups; + const char ** fileOwners; + const char ** fileGroups; + XFI_t file; int i; headerGetEntry(h, RPMTAG_FILEUSERNAME, NULL, (void **) &fileOwners, NULL); headerGetEntry(h, RPMTAG_FILEGROUPNAME, NULL, (void **) &fileGroups, NULL); - for (i = 0; i < fileCount; i++) { - if (unameToUid(fileOwners[i], &files[i].uid)) { + for (i = 0, file = files; i < fileCount; i++, file++) { + if (unameToUid(fileOwners[i], &file->uid)) { rpmMessage(RPMMESS_WARNING, _("user %s does not exist - using root\n"), fileOwners[i]); - files[i].uid = 0; - /* turn off the suid bit */ - files[i].mode &= ~S_ISUID; + file->uid = 0; + file->mode &= ~S_ISUID; /* turn off the suid bit */ } - if (gnameToGid(fileGroups[i], &files[i].gid)) { + if (gnameToGid(fileGroups[i], &file->gid)) { rpmMessage(RPMMESS_WARNING, _("group %s does not exist - using root\n"), fileGroups[i]); - files[i].gid = 0; - /* turn off the sgid bit */ - files[i].mode &= ~S_ISGID; + file->gid = 0; + file->mode &= ~S_ISGID; /* turn off the sgid bit */ } } @@ -309,8 +309,9 @@ static void trimChangelog(Header h) * @param actions array of file dispositions * @return 0 on success, 1 on failure */ -static int mergeFiles(Header h, Header newH, enum fileActions * actions) +static int mergeFiles(Header h, Header newH, TFI_t fi) { + enum fileActions * actions = fi->actions; int i, j, k, fileCount; int_32 type, count, dirNamesCount, dirCount; void * data, * newdata; @@ -483,25 +484,30 @@ static int mergeFiles(Header h, Header newH, enum fileActions * actions) } /** - * Mark files in database shared with current package as "replaced". - * @param db rpm database - * @param replist shared file list + * Mark files in database shared with this package as "replaced". + * @param ts transaction set + * @param fi transaction element file info * @return 0 always */ -static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList) +static int markReplacedFiles(const rpmTransactionSet ts, const TFI_t fi) { - const struct sharedFileInfo * fileInfo; + rpmdb rpmdb = ts->rpmdb; + const struct sharedFileInfo * replaced = fi->replaced; + const struct sharedFileInfo * sfi; rpmdbMatchIterator mi; Header h; unsigned int * offsets; unsigned int prev; int num; + if (!(fi->fc > 0 && fi->replaced)) + return 0; + num = prev = 0; - for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) { - if (prev && prev == fileInfo->otherPkg) + for (sfi = replaced; sfi->otherPkg; sfi++) { + if (prev && prev == sfi->otherPkg) continue; - prev = fileInfo->otherPkg; + prev = sfi->otherPkg; num++; } if (num == 0) @@ -509,17 +515,17 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList offsets = alloca(num * sizeof(*offsets)); num = prev = 0; - for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) { - if (prev && prev == fileInfo->otherPkg) + for (sfi = replaced; sfi->otherPkg; sfi++) { + if (prev && prev == sfi->otherPkg) continue; - prev = fileInfo->otherPkg; - offsets[num++] = fileInfo->otherPkg; + prev = sfi->otherPkg; + offsets[num++] = sfi->otherPkg; } mi = rpmdbInitIterator(rpmdb, RPMDBI_PACKAGES, NULL, 0); rpmdbAppendIterator(mi, offsets, num); - fileInfo = replList; + sfi = replaced; while ((h = rpmdbNextIterator(mi)) != NULL) { char * secStates; int modified; @@ -532,10 +538,10 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList prev = rpmdbGetIteratorOffset(mi); num = 0; - while (fileInfo->otherPkg && fileInfo->otherPkg == prev) { - assert(fileInfo->otherFileNum < count); - if (secStates[fileInfo->otherFileNum] != RPMFILE_STATE_REPLACED) { - secStates[fileInfo->otherFileNum] = RPMFILE_STATE_REPLACED; + while (sfi->otherPkg && sfi->otherPkg == prev) { + assert(sfi->otherFileNum < count); + if (secStates[sfi->otherFileNum] != RPMFILE_STATE_REPLACED) { + secStates[sfi->otherFileNum] = RPMFILE_STATE_REPLACED; if (modified == 0) { /* Modified header will be rewritten. */ modified = 1; @@ -543,7 +549,7 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList } num++; } - fileInfo++; + sfi++; } } rpmdbFreeIterator(mi); @@ -555,19 +561,17 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList */ static void callback(struct cpioCallbackInfo * cpioInfo, void * data) { - struct callbackInfo * ourInfo = data; - const char * chptr; + cbInfo cbi = data; - if (ourInfo->notify) - (void)ourInfo->notify(ourInfo->h, RPMCALLBACK_INST_PROGRESS, + if (cbi->notify) + (void)cbi->notify(cbi->h, RPMCALLBACK_INST_PROGRESS, cpioInfo->bytesProcessed, - ourInfo->archiveSize, ourInfo->pkgKey, - ourInfo->notifyData); + cbi->archiveSize, cbi->pkgKey, cbi->notifyData); - if (ourInfo->specFilePtr) { - chptr = cpioInfo->file + strlen(cpioInfo->file) - 5; - if (!strcmp(chptr, ".spec")) - *ourInfo->specFilePtr = xstrdup(cpioInfo->file); + if (cbi->specFilePtr) { + const char * t = cpioInfo->file + strlen(cpioInfo->file) - 5; + if (!strcmp(t, ".spec")) + *cbi->specFilePtr = xstrdup(cpioInfo->file); } } @@ -587,19 +591,19 @@ static void callback(struct cpioCallbackInfo * cpioInfo, void * data) * @param archiveSize @todo Document. * @return 0 on success */ -static int installArchive(FD_t fd, struct fileInfo * files, int fileCount, +static int installArchive(FD_t fd, XFI_t files, int fileCount, rpmCallbackFunction notify, rpmCallbackData notifyData, const void * pkgKey, Header h, /*@out@*/ const char ** specFile, int archiveSize) { - int rc, i; struct cpioFileMapping * map = NULL; int mappedFiles = 0; const char * failedFile = NULL; - struct callbackInfo info; + cbInfo cbi = alloca(sizeof(*cbi)); char * rpmio_flags; FD_t cfd; int saveerrno; + int rc; if (!files) { /* install all files */ @@ -609,31 +613,34 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount, return 0; } - info.archiveSize = archiveSize; - info.notify = notify; - info.notifyData = notifyData; - info.specFilePtr = specFile; - info.h = headerLink(h); - info.pkgKey = pkgKey; + cbi->archiveSize = archiveSize; /* arg9 */ + cbi->notify = notify; /* arg4 */ + cbi->notifyData = notifyData; /* arg5 */ + cbi->specFilePtr = specFile; /* arg8 */ + cbi->h = headerLink(h); /* arg7 */ + cbi->pkgKey = pkgKey; /* arg6 */ if (specFile) *specFile = NULL; if (files) { + XFI_t file; + int i; + map = alloca(sizeof(*map) * fileCount); - for (i = 0, mappedFiles = 0; i < fileCount; i++) { - if (!files[i].install) continue; + for (i = 0, mappedFiles = 0, file = files; i < fileCount; i++, file++) { + if (!file->install) continue; - map[mappedFiles].archivePath = files[i].cpioPath; - (void) urlPath(files[i].dn, &map[mappedFiles].dirName); - map[mappedFiles].baseName = files[i].bn; + map[mappedFiles].archivePath = file->cpioPath; + (void) urlPath(file->dn, &map[mappedFiles].dirName); + map[mappedFiles].baseName = file->bn; /* XXX Can't do src rpm MD5 sum verification (yet). */ /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */ map[mappedFiles].md5sum = headerIsEntry(h, RPMTAG_SOURCERPM) - ? files[i].md5sum : NULL; - map[mappedFiles].finalMode = files[i].mode; - map[mappedFiles].finalUid = files[i].uid; - map[mappedFiles].finalGid = files[i].gid; + ? file->md5sum : NULL; + map[mappedFiles].finalMode = file->mode; + map[mappedFiles].finalUid = file->uid; + map[mappedFiles].finalGid = file->gid; map[mappedFiles].mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID; mappedFiles++; @@ -665,10 +672,10 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount, cfd = Fdopen(fdDup(Fileno(fd)), rpmio_flags); rc = cpioInstallArchive(cfd, map, mappedFiles, ((notify && archiveSize) || specFile) ? callback : NULL, - &info, &failedFile); + cbi, &failedFile); saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */ Fclose(cfd); - headerFree(info.h); + headerFree(cbi->h); if (rc) { /* this would probably be a good place to check if disk space @@ -682,7 +689,7 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount, } else if (notify) { if (archiveSize) (void)notify(h, RPMCALLBACK_INST_PROGRESS, archiveSize, archiveSize, - pkgKey, notifyData); + pkgKey, notifyData); else (void)notify(h, RPMCALLBACK_INST_PROGRESS, 100, 100, pkgKey, notifyData); @@ -710,13 +717,12 @@ static int installSources(Header h, const char * rootDir, FD_t fd, { const char * specFile = NULL; int specFileIndex = -1; - const char * realSourceDir = NULL; - const char * realSpecDir = NULL; - char * instSpecFile, * correctSpecFile; + const char * _sourcedir = NULL; + const char * _specdir = NULL; int fileCount = 0; uint_32 * archiveSizePtr = NULL; fileMemory fileMem = NULL; - struct fileInfo * files = NULL; + XFI_t files = NULL; int i; const char * currDir = NULL; uid_t currUid = getuid(); @@ -726,9 +732,9 @@ static int installSources(Header h, const char * rootDir, FD_t fd, rpmMessage(RPMMESS_DEBUG, _("installing a source package\n")); - realSourceDir = rpmGenPath(rootDir, "%{_sourcedir}", ""); - if ((rc = Stat(realSourceDir, &st)) < 0) { - int ut = urlPath(realSourceDir, NULL); + _sourcedir = rpmGenPath(rootDir, "%{_sourcedir}", ""); + if ((rc = Stat(_sourcedir, &st)) < 0) { + int ut = urlPath(_sourcedir, NULL); switch (ut) { case URL_IS_PATH: case URL_IS_UNKNOWN: @@ -738,28 +744,28 @@ static int installSources(Header h, const char * rootDir, FD_t fd, case URL_IS_FTP: case URL_IS_HTTP: /* XXX this will only create last component of directory path */ - rc = Mkdir(realSourceDir, 0755); + rc = Mkdir(_sourcedir, 0755); break; case URL_IS_DASH: break; } if (rc < 0) { rpmError(RPMERR_CREATE, _("cannot create sourcedir %s\n"), - realSourceDir); + _sourcedir); rc = 2; goto exit; } } - if ((rc = Access(realSourceDir, W_OK))) { - rpmError(RPMERR_CREATE, _("cannot write to %s\n"), realSourceDir); + if ((rc = Access(_sourcedir, W_OK))) { + rpmError(RPMERR_CREATE, _("cannot write to %s\n"), _sourcedir); rc = 2; goto exit; } - rpmMessage(RPMMESS_DEBUG, _("sources in: %s\n"), realSourceDir); + rpmMessage(RPMMESS_DEBUG, _("sources in: %s\n"), _sourcedir); - realSpecDir = rpmGenPath(rootDir, "%{_specdir}", ""); - if ((rc = Stat(realSpecDir, &st)) < 0) { - int ut = urlPath(realSpecDir, NULL); + _specdir = rpmGenPath(rootDir, "%{_specdir}", ""); + if ((rc = Stat(_specdir, &st)) < 0) { + int ut = urlPath(_specdir, NULL); switch (ut) { case URL_IS_PATH: case URL_IS_UNKNOWN: @@ -769,24 +775,23 @@ static int installSources(Header h, const char * rootDir, FD_t fd, case URL_IS_FTP: case URL_IS_HTTP: /* XXX this will only create last component of directory path */ - rc = Mkdir(realSpecDir, 0755); + rc = Mkdir(_specdir, 0755); break; case URL_IS_DASH: break; } if (rc < 0) { - rpmError(RPMERR_CREATE, _("cannot create specdir %s\n"), - realSpecDir); + rpmError(RPMERR_CREATE, _("cannot create specdir %s\n"), _specdir); rc = 2; goto exit; } } - if ((rc = Access(realSpecDir, W_OK))) { - rpmError(RPMERR_CREATE, _("cannot write to %s\n"), realSpecDir); + if ((rc = Access(_specdir, W_OK))) { + rpmError(RPMERR_CREATE, _("cannot write to %s\n"), _specdir); rc = 2; goto exit; } - rpmMessage(RPMMESS_DEBUG, _("spec file in: %s\n"), realSpecDir); + rpmMessage(RPMMESS_DEBUG, _("spec file in: %s\n"), _specdir); if (h != NULL && headerIsEntry(h, RPMTAG_BASENAMES)) { /* we can't remap v1 packages */ @@ -804,17 +809,18 @@ static int installSources(Header h, const char * rootDir, FD_t fd, if (i == fileCount) { /* find the spec file by name */ for (i = 0; i < fileCount; i++) { - const char *chptr; - chptr = files[i].cpioPath + strlen(files[i].cpioPath) - 5; - if (!strcmp(chptr, ".spec")) break; + const char * t = files[i].cpioPath; + t += strlen(files[i].cpioPath) - 5; + if (!strcmp(t, ".spec")) break; } } if (i < fileCount) { - char *t = alloca(strlen(realSpecDir) + - strlen(files[i].cpioPath) + 5); - (void)stpcpy(stpcpy(stpcpy(t,realSpecDir), "/"), files[i].cpioPath); - files[i].relativePath = t; + char *t = alloca(strlen(_specdir) + strlen(files[i].cpioPath) + 5); + (void)stpcpy(stpcpy(t, _specdir), "/"); + rpmCleanPath(t); + files[i].dn = t; + files[i].bn = files[i].cpioPath; specFileIndex = i; } else { rpmError(RPMERR_NOSPEC, @@ -824,17 +830,15 @@ static int installSources(Header h, const char * rootDir, FD_t fd, } } - if (notify) { + if (notify) (void)notify(h, RPMCALLBACK_INST_START, 0, 0, NULL, notifyData); - } - - currDir = currentDirectory(); if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, NULL, (void **) &archiveSizePtr, NULL)) archiveSizePtr = NULL; - Chdir(realSourceDir); + currDir = currentDirectory(); + Chdir(_sourcedir); if (installArchive(fd, fileCount > 0 ? files : NULL, fileCount, notify, notifyData, NULL, h, specFileIndex >= 0 ? NULL : &specFile, @@ -845,6 +849,9 @@ static int installSources(Header h, const char * rootDir, FD_t fd, Chdir(currDir); if (specFileIndex == -1) { + char * cSpecFile; + char * iSpecFile; + if (specFile == NULL) { rpmError(RPMERR_NOSPEC, _("source package contains no .spec file\n")); @@ -852,41 +859,48 @@ static int installSources(Header h, const char * rootDir, FD_t fd, goto exit; } - /* This logic doesn't work if realSpecDir and realSourceDir are on - different filesystems, but we only do this on v1 source packages - so I don't really care much. */ - instSpecFile = alloca(strlen(realSourceDir) + strlen(specFile) + 2); - (void)stpcpy(stpcpy(stpcpy(instSpecFile,realSourceDir), "/"), specFile); + /* + * This logic doesn't work if _specdir and _sourcedir are on + * different filesystems, but we only do this on v1 source packages + * so I don't really care much. + */ + iSpecFile = alloca(strlen(_sourcedir) + strlen(specFile) + 2); + (void)stpcpy(stpcpy(stpcpy(iSpecFile, _sourcedir), "/"), specFile); - correctSpecFile = alloca(strlen(realSpecDir) + strlen(specFile) + 2); - (void)stpcpy(stpcpy(stpcpy(correctSpecFile,realSpecDir), "/"), specFile); + cSpecFile = alloca(strlen(_specdir) + strlen(specFile) + 2); + (void)stpcpy(stpcpy(stpcpy(cSpecFile, _specdir), "/"), specFile); free((void *)specFile); - if (strcmp(instSpecFile, correctSpecFile)) { + if (strcmp(iSpecFile, cSpecFile)) { rpmMessage(RPMMESS_DEBUG, - _("renaming %s to %s\n"), instSpecFile, correctSpecFile); - if ((rc = Rename(instSpecFile, correctSpecFile))) { + _("renaming %s to %s\n"), iSpecFile, cSpecFile); + if ((rc = Rename(iSpecFile, cSpecFile))) { rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"), - instSpecFile, correctSpecFile, strerror(errno)); + iSpecFile, cSpecFile, strerror(errno)); rc = 2; goto exit; } } if (specFilePtr) - *specFilePtr = xstrdup(correctSpecFile); + *specFilePtr = xstrdup(cSpecFile); } else { - if (specFilePtr) - *specFilePtr = xstrdup(files[specFileIndex].relativePath); + if (specFilePtr) { + const char * dn = files[specFileIndex].dn; + const char * bn = files[specFileIndex].bn; + char * t = xmalloc(strlen(dn) + strlen(bn) + 1); + (void)stpcpy( stpcpy(t, dn), bn); + *specFilePtr = t; + } } rc = 0; exit: if (fileMem) freeFileMemory(fileMem); if (currDir) free((void *)currDir); - if (realSpecDir) free((void *)realSpecDir); - if (realSourceDir) free((void *)realSourceDir); + if (_specdir) free((void *)_specdir); + if (_sourcedir) free((void *)_sourcedir); return rc; } @@ -983,22 +997,16 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) rpmtransFlags transFlags = ts->transFlags; struct availablePackage * alp = fi->ap; int fileCount = 0; - int type, count; - struct fileInfo * files; - int i; + XFI_t files = NULL; Header oldH = NULL; int otherOffset = 0; int scriptArg; - int stripSize = 1; /* strip at least first / for cpio */ fileMemory fileMem = NULL; + int ec = 2; /* assume error return */ int rc; + int i; -#ifdef DYING - const char * name, * version, * release; - headerNVR(h, &name, &version, &release); -#endif - - /* XXX this looks broke, as libraries may need /sbin/ldconfig for example */ + /* XXX MULTILIB is broken, as packages can and do execute /sbin/ldconfig. */ if (transFlags & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_MULTILIB)) transFlags |= RPMTRANS_FLAG_NOSCRIPTS; @@ -1006,10 +1014,8 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) alp->name, alp->version, alp->release, transFlags & RPMTRANS_FLAG_TEST); - if ((scriptArg = rpmdbCountPackages(ts->rpmdb, alp->name)) < 0) { - rc = 2; + if ((scriptArg = rpmdbCountPackages(ts->rpmdb, alp->name)) < 0) goto exit; - } scriptArg += 1; { rpmdbMatchIterator mi; @@ -1025,29 +1031,28 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) rpmdbFreeIterator(mi); } - if (!(transFlags & RPMTRANS_FLAG_JUSTDB) && headerIsEntry(h, RPMTAG_BASENAMES)) { - const char * defaultPrefix; - /* old format relocateable packages need the entire default - prefix stripped to form the cpio list, while all other packages - need the leading / stripped */ - if (headerGetEntry(h, RPMTAG_DEFAULTPREFIX, NULL, (void **) - &defaultPrefix, NULL)) { - stripSize = strlen(defaultPrefix) + 1; - } else { - stripSize = 1; - } + if (!(transFlags & RPMTRANS_FLAG_JUSTDB) && + headerIsEntry(h, RPMTAG_BASENAMES)) + { + const char * p; + int stripSize; - if (assembleFileList(fi, h, &fileMem, &fileCount, &files, stripSize)) { - rc = 2; + /* + * Old format relocateable packages need the entire default + * prefix stripped to form the cpio list, while all other packages + * need the leading / stripped. + */ + rc = headerGetEntry(h, RPMTAG_DEFAULTPREFIX, NULL, (void **) &p, NULL); + stripSize = (rc ? strlen(p) + 1 : 1); + if (assembleFileList(fi, h, &fileMem, &fileCount, &files, stripSize)) goto exit; - } } else { files = NULL; } if (transFlags & RPMTRANS_FLAG_TEST) { rpmMessage(RPMMESS_DEBUG, _("stopping install as we're running --test\n")); - rc = 0; + ec = 0; goto exit; } @@ -1060,7 +1065,6 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) rpmError(RPMERR_SCRIPT, _("skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n"), alp->name, alp->version, alp->release, rc); - rc = 2; goto exit; } @@ -1076,29 +1080,33 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) } if (files) { + XFI_t file; + setFileOwners(h, files, fileCount); - for (i = 0; i < fileCount; i++) { + for (i = 0, file = files; i < fileCount; i++, file++) { + char opath[BUFSIZ]; + char * npath; char * ext; - char * newpath; - ext = NULL; + file->bnsuffix = file->oext = ext = NULL; - switch (files[i].action) { + switch (file->action) { case FA_BACKUP: - ext = ".rpmorig"; + file->oext = ext = ".rpmorig"; break; case FA_ALTNAME: - newpath = alloca(strlen(files[i].relativePath) + 20); - (void)stpcpy(stpcpy(newpath, files[i].relativePath), ".rpmnew"); - rpmMessage(RPMMESS_WARNING, _("%s created as %s\n"), - files[i].relativePath, newpath); - files[i].relativePath = newpath; + file->bnsuffix = ".rpmnew"; + npath = alloca(strlen(file->bn) + strlen(file->bnsuffix) + 1); + (void)stpcpy(stpcpy(npath, file->bn), file->bnsuffix); + rpmMessage(RPMMESS_WARNING, _("%s%s created as %s\n"), + file->dn, file->bn, npath); + file->bn = npath; break; case FA_SAVE: - ext = ".rpmsave"; + file->oext = ext = ".rpmsave"; break; case FA_CREATE: @@ -1106,45 +1114,48 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) case FA_SKIP: case FA_SKIPMULTILIB: - files[i].install = 0; + file->install = 0; break; case FA_SKIPNSTATE: - files[i].state = RPMFILE_STATE_NOTINSTALLED; - files[i].install = 0; + file->state = RPMFILE_STATE_NOTINSTALLED; + file->install = 0; break; case FA_SKIPNETSHARED: - files[i].state = RPMFILE_STATE_NETSHARED; - files[i].install = 0; + file->state = RPMFILE_STATE_NETSHARED; + file->install = 0; break; case FA_UNKNOWN: case FA_REMOVE: - files[i].install = 0; + file->install = 0; break; } - if (ext && access(files[i].relativePath, F_OK) == 0) { - newpath = alloca(strlen(files[i].relativePath) + 20); - (void)stpcpy(stpcpy(newpath, files[i].relativePath), ext); - rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), - files[i].relativePath, newpath); - - if (rename(files[i].relativePath, newpath)) { - rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"), - files[i].relativePath, newpath, strerror(errno)); - rc = 2; - goto exit; - } - } + if (ext == NULL) + continue; + (void)stpcpy(stpcpy(opath, file->dn), file->bn); + if (access(opath, F_OK) != 0) + continue; + npath = alloca(strlen(file->dn) + strlen(file->bn) + + strlen(ext) + 1); + (void)stpcpy(stpcpy(npath, opath), ext); + rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), opath, npath); + + if (!rename(opath, npath)) + continue; + + rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"), + opath, npath, strerror(errno)); + goto exit; } - { uint_32 * archiveSizePtr; + { uint_32 archiveSize, * asp; - if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type, - (void **) &archiveSizePtr, &count)) - archiveSizePtr = NULL; + rc = headerGetEntry(h, RPMTAG_ARCHIVESIZE, NULL, + (void **) &asp, NULL); + archiveSize = (rc ? *asp : 0); if (ts->notify) { (void)ts->notify(h, RPMCALLBACK_INST_START, 0, 0, @@ -1152,33 +1163,28 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) } /* the file pointer for fd is pointing at the cpio archive */ - if (installArchive(alp->fd, files, fileCount, + rc = installArchive(alp->fd, files, fileCount, ts->notify, ts->notifyData, alp->key, - h, NULL, archiveSizePtr ? *archiveSizePtr : 0)) - { - rc = 2; + h, NULL, archiveSize); + if (rc) goto exit; - } } - { char *fileStates = xmalloc(sizeof(*fileStates) * fileCount); - for (i = 0; i < fileCount; i++) - fileStates[i] = files[i].state; - - headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates, + { char *fstates = alloca(sizeof(*fstates) * fileCount); + for (i = 0, file = files; i < fileCount; i++, file++) + fstates[i] = file->state; + headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fstates, fileCount); - - free(fileStates); } + if (fileMem) freeFileMemory(fileMem); fileMem = NULL; } else if (transFlags & RPMTRANS_FLAG_JUSTDB) { if (headerGetEntry(h, RPMTAG_BASENAMES, NULL, NULL, &fileCount)) { - char * fileStates = xmalloc(sizeof(*fileStates) * fileCount); - memset(fileStates, RPMFILE_STATE_NORMAL, fileCount); - headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates, - fileCount); - free(fileStates); + char * fstates = alloca(sizeof(*fstates) * fileCount); + memset(fstates, RPMFILE_STATE_NORMAL, fileCount); + headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fstates, + fileCount); } } @@ -1213,46 +1219,36 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi) headerModifyEntry(oldH, RPMTAG_MULTILIBS, RPM_INT32_TYPE, &multiLib, 1); } - if (mergeFiles(oldH, h, fi->actions)) { - rc = 2; + if (mergeFiles(oldH, h, fi)) goto exit; - } } - if (rpmdbAdd(ts->rpmdb, ts->id, h)) { - rc = 2; + if (rpmdbAdd(ts->rpmdb, ts->id, h)) goto exit; - } rpmMessage(RPMMESS_DEBUG, _("running postinstall scripts (if any)\n")); - if (runInstScript(ts, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg, - (transFlags & RPMTRANS_FLAG_NOSCRIPTS))) { - rc = 2; + rc = runInstScript(ts, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg, + (transFlags & RPMTRANS_FLAG_NOSCRIPTS)); + if (rc) goto exit; - } if (!(transFlags & RPMTRANS_FLAG_NOTRIGGERS)) { /* Run triggers this package sets off */ - if (runTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) { - rc = 2; + if (runTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) goto exit; - } /* * Run triggers in this package which are set off by other packages in * the database. */ - if (runImmedTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) { - rc = 2; + if (runImmedTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) goto exit; - } } - if (fi->fc > 0 && fi->replaced) - markReplacedFiles(ts->rpmdb, fi->replaced); + markReplacedFiles(ts, fi); - rc = 0; + ec = 0; exit: if (ts->chrootDone) { @@ -1264,5 +1260,5 @@ exit: freeFileMemory(fileMem); if (oldH) headerFree(oldH); - return rc; + return ec; } diff --git a/lib/install.h b/lib/install.h index 8792f99ff..26c407e45 100644 --- a/lib/install.h +++ b/lib/install.h @@ -28,23 +28,31 @@ struct sharedFileInfo { * File disposition(s) during package install/erase. */ enum fileActions { - FA_UNKNOWN = 0, - FA_CREATE, - FA_BACKUP, - FA_SAVE, - FA_SKIP, - FA_ALTNAME, - FA_REMOVE, - FA_SKIPNSTATE, - FA_SKIPNETSHARED, - FA_SKIPMULTILIB + FA_UNKNOWN = 0, /*!< initial action (default action for source rpm) */ + FA_CREATE, /*!< ... to be replaced. */ + FA_BACKUP, /*!< ... renamed with ".rpmorig" extension. */ + FA_SAVE, /*!< ... renamed with ".rpmsave" extension. */ + FA_SKIP, /*!< ... already replaced, don't remove. */ + FA_ALTNAME, /*!< ... create with ".rpmnew" extension. */ + FA_REMOVE, /*!< ... to be removed. */ + FA_SKIPNSTATE, /*!< ... untouched, state "not installed". */ + FA_SKIPNETSHARED, /*!< ... untouched, state "netshared". */ + FA_SKIPMULTILIB, /*!< ... untouched. @todo state "multilib" ???. */ }; /** + */ +typedef enum rollbackDir_e { + ROLLBACK_SAVE = 1, /*!< Save files. */ + ROLLBACK_RESTORE = 2, /*!< Restore files. */ +} rollbackDir; + +/** * File types. * These are the types of files used internally by rpm. The file * type is determined by applying stat(2) macros like S_ISDIR to - * the file mode tag from a header. + * the file mode tag from a header. The values are arbitrary, + * but are identical to the linux stat(2) file types. */ enum fileTypes { PIPE = 1, /*!< pipe/fifo */ @@ -53,7 +61,7 @@ enum fileTypes { BDEV = 6, /*!< block device */ REG = 8, /*!< regular file */ LINK = 10, /*!< hard link */ - SOCK = 12 /*!< socket */ + SOCK = 12, /*!< socket */ }; /*@abstract@*/ typedef struct transactionFileInfo_s * TFI_t; @@ -63,33 +71,35 @@ extern "C" { #endif /** + * Retrieve and run scriptlet from header. * @param ts transaction set * @param h header - * @param scriptTag - * @param progTag - * @param arg - * @param norunScripts + * @param scriptTag scriptlet tag + * @param progTag scriptlet interpreter tag + * @param arg no. instances of package installed after scriptlet exec + * @param norunScripts should scriptlet be executed? + * @return 0 on success */ int runInstScript(const rpmTransactionSet ts, Header h, int scriptTag, int progTag, int arg, int norunScripts); /** - * Run trigger scripts in the database that are fired by header. + * Run trigger scripts in the database that are fired by this header. * @param ts transaction set - * @param sense @todo Document. + * @param sense one of RPMSENSE_TRIGGER{IN,UN,POSTUN} * @param h header - * @param countCorrection @todo Document. + * @param countCorrection 0 if installing, -1 if removing, package * @return 0 on success, 1 on error */ int runTriggers(const rpmTransactionSet ts, int sense, Header h, int countCorrection); /** - * Run triggers from header that are fired by the database. + * Run triggers from this header that are fired by headers in the database. * @param ts transaction set - * @param sense @todo Document. + * @param sense one of RPMSENSE_TRIGGER{IN,UN,POSTUN} * @param h header - * @param countCorrection @todo Document. + * @param countCorrection 0 if installing, -1 if removing, package * @return 0 on success, 1 on error */ int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h, @@ -106,7 +116,7 @@ int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h, * Install binary package (from transaction set). * @param ts transaction set * @param h package header - * @param fi transaction file info + * @param fi transaction element file info * @return 0 on success, 1 on bad magic, 2 on error */ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi); @@ -118,11 +128,21 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi); * @param h package header * @param pkgKey package private data * @param actions array of file dispositions - * @return + * @return 0 on success */ int removeBinaryPackage(const rpmTransactionSet ts, unsigned int offset, Header h, const void * pkgKey, enum fileActions * actions); +/** + * Save/restore files from transaction element by renaming on file system. + * @param ts transaction set + * @param fi transaction element file info + * @param dir save or restore? + * @return 0 on success + */ +int dirstashPackage(const rpmTransactionSet ts, const TFI_t fi, + rollbackDir dir); + #ifdef __cplusplus } #endif diff --git a/lib/transaction.c b/lib/transaction.c index ddfacefb3..efa9edacc 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -1351,76 +1351,6 @@ static void skipFiles(TFI_t fi, int noDocs) if (languages) freeSplitString((char **)languages); } -static char * ridsub = ".rid/"; -static char * ridsep = ";"; -static mode_t riddmode = 0700; -static mode_t ridfmode = 0000; - -static int dirstashPackage(const rpmTransactionSet ts, const TFI_t fi) -{ - unsigned int offset = fi->record; - char tsid[20], ofn[BUFSIZ], nfn[BUFSIZ]; - const char * s, * t; - char * se, * te; - Header h; - int i; - - { rpmdbMatchIterator mi = NULL; - - mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES, - &offset, sizeof(offset)); - - h = rpmdbNextIterator(mi); - if (h == NULL) { - rpmdbFreeIterator(mi); - return 1; - } - h = headerLink(h); - rpmdbFreeIterator(mi); - } - - sprintf(tsid, "%08x", ts->id); - - /* Create rid sub-directories if necessary. */ - if (strchr(ridsub, '/')) { - for (i = 0; i < fi->dc; i++) { - - t = te = nfn; - *te = '\0'; - te = stpcpy(te, fi->dnl[i]); - te = stpcpy(te, ridsub); - if (te[-1] == '/') - *(--te) = '\0'; -fprintf(stderr, "*** mkdir(%s,%o)\n", t, riddmode); - } - } - - /* Rename files about to be removed. */ - for (i = 0; i < fi->fc; i++) { - - if (S_ISDIR(fi->fmodes[i])) - continue; - - s = se = ofn; - *se = '\0'; - se = stpcpy( stpcpy(se, fi->dnl[fi->dil[i]]), fi->bnl[i]); - - t = te = nfn; - *te = '\0'; - te = stpcpy(te, fi->dnl[fi->dil[i]]); - if (ridsub) - te = stpcpy(te, ridsub); - te = stpcpy( stpcpy( stpcpy(te, fi->bnl[i]), ridsep), tsid); - - s = strrchr(s, '/') + 1; - t = strrchr(t, '/') + 1; -fprintf(stderr, "*** rename(%s,%s%s)\n", s, (ridsub ? ridsub : ""), t); -fprintf(stderr, "*** chmod(%s%s,%o)\n", (ridsub ? ridsub : ""), t, ridfmode); - } - - return 0; -} - #define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al int rpmRunTransactions( rpmTransactionSet ts, @@ -1601,9 +1531,10 @@ int rpmRunTransactions( rpmTransactionSet ts, switch (ts->order[oc].type) { case TR_ADDED: + fi->type = TR_ADDED; i = ts->order[oc].u.addedIndex; alp = ts->addedPackages.list + i; - + fi->ap = alp; if (!headerGetEntryMinMemory(alp->h, RPMTAG_BASENAMES, NULL, NULL, &fi->fc)) { fi->h = headerLink(alp->h); @@ -1615,10 +1546,10 @@ int rpmRunTransactions( rpmTransactionSet ts, fi->actions = xcalloc(fi->fc, sizeof(*fi->actions)); hdrs[i] = relocateFileList(ts, alp, alp->h, fi->actions); fi->h = headerLink(hdrs[i]); - fi->ap = alp; - fi->type = TR_ADDED; break; case TR_REMOVED: + fi->type = TR_REMOVED; + fi->ap = alp = NULL; fi->record = ts->order[oc].u.removed.dboffset; { rpmdbMatchIterator mi; @@ -1632,8 +1563,6 @@ int rpmRunTransactions( rpmTransactionSet ts, /* ACK! */ continue; } - fi->ap = alp = NULL; - fi->type = TR_REMOVED; break; } @@ -1899,7 +1828,7 @@ int rpmRunTransactions( rpmTransactionSet ts, if (ts->order[oc].u.removed.dependsOnIndex != i) break; if (ts->transFlags & RPMTRANS_FLAG_DIRSTASH) - dirstashPackage(ts, fi); + dirstashPackage(ts, fi, ROLLBACK_SAVE); break; } } @@ -1945,6 +1874,7 @@ int rpmRunTransactions( rpmTransactionSet ts, if (alp->multiLib) ts->transFlags |= RPMTRANS_FLAG_MULTILIB; +if (fi->ap == NULL) fi->ap = alp; if (installBinaryPackage(ts, hdrs[i], fi)) { ourrc++; lastFailed = i; diff --git a/po/POTFILES.in b/po/POTFILES.in index e33952ea2..e07092ca8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -44,6 +44,7 @@ lib/poptBT.c lib/poptQV.c lib/problems.c lib/query.c +lib/rollback.c lib/rpmchecksig.c lib/rpmdb.c lib/rpminstall.c diff --git a/po/rpm.pot b/po/rpm.pot index 31e80a8f4..384059b6f 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-01-21 10:28-0500\n" +"POT-Creation-Date: 2001-01-21 18:24-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" @@ -2190,55 +2190,55 @@ msgstr "" msgid "line %d: Bad %s number: %s\n" msgstr "" -#: lib/cpio.c:445 +#: lib/cpio.c:508 #, c-format msgid "can't rename %s to %s: %s\n" msgstr "" -#: lib/cpio.c:451 +#: lib/cpio.c:514 #, c-format msgid "can't unlink %s: %s\n" msgstr "" -#: lib/cpio.c:758 +#: lib/cpio.c:820 #, c-format msgid "getNextHeader: %s\n" msgstr "" -#: lib/cpio.c:1262 +#: lib/cpio.c:1320 #, c-format msgid "(error 0x%x)" msgstr "" -#: lib/cpio.c:1265 +#: lib/cpio.c:1323 msgid "Bad magic" msgstr "" -#: lib/cpio.c:1266 +#: lib/cpio.c:1324 msgid "Bad/unreadable header" msgstr "" -#: lib/cpio.c:1284 +#: lib/cpio.c:1342 msgid "Header size too big" msgstr "" -#: lib/cpio.c:1285 +#: lib/cpio.c:1343 msgid "Unknown file type" msgstr "" -#: lib/cpio.c:1286 +#: lib/cpio.c:1344 msgid "Missing hard link" msgstr "" -#: lib/cpio.c:1287 +#: lib/cpio.c:1345 msgid "MD5 sum mismatch" msgstr "" -#: lib/cpio.c:1288 +#: lib/cpio.c:1346 msgid "Internal error" msgstr "" -#: lib/cpio.c:1297 +#: lib/cpio.c:1355 msgid " failed - " msgstr "" @@ -2517,7 +2517,7 @@ msgstr "" msgid "dataLength() RPM_STRING_TYPE count must be 1.\n" msgstr "" -#: lib/header.c:207 lib/header.c:1015 lib/install.c:394 +#: lib/header.c:207 lib/header.c:1015 lib/install.c:395 #, c-format msgid "Data type %d not supported\n" msgstr "" @@ -2602,17 +2602,17 @@ msgstr "" msgid "(unknown type)" msgstr "" -#: lib/install.c:219 +#: lib/install.c:220 #, c-format msgid " file: %s%s action: %s\n" msgstr "" -#: lib/install.c:244 +#: lib/install.c:246 #, c-format msgid "user %s does not exist - using root\n" msgstr "" -#: lib/install.c:252 +#: lib/install.c:253 #, c-format msgid "group %s does not exist - using root\n" msgstr "" @@ -2620,90 +2620,90 @@ msgstr "" #. this would probably be a good place to check if disk space #. was used up - if so, we should return a different error #. XXX FIXME: Fclose with libio destroys errno -#: lib/install.c:677 +#: lib/install.c:684 #, c-format msgid "unpacking of archive failed%s%s: %s\n" msgstr "" -#: lib/install.c:678 +#: lib/install.c:685 msgid " on file " msgstr "" -#: lib/install.c:727 +#: lib/install.c:733 msgid "installing a source package\n" msgstr "" -#: lib/install.c:747 +#: lib/install.c:753 #, c-format msgid "cannot create sourcedir %s\n" msgstr "" -#: lib/install.c:754 lib/install.c:785 +#: lib/install.c:760 lib/install.c:790 #, c-format msgid "cannot write to %s\n" msgstr "" -#: lib/install.c:758 +#: lib/install.c:764 #, c-format msgid "sources in: %s\n" msgstr "" -#: lib/install.c:778 +#: lib/install.c:784 #, c-format msgid "cannot create specdir %s\n" msgstr "" -#: lib/install.c:789 +#: lib/install.c:794 #, c-format msgid "spec file in: %s\n" msgstr "" -#: lib/install.c:821 lib/install.c:850 +#: lib/install.c:827 lib/install.c:857 msgid "source package contains no .spec file\n" msgstr "" -#: lib/install.c:868 +#: lib/install.c:877 #, c-format msgid "renaming %s to %s\n" msgstr "" -#: lib/install.c:870 lib/install.c:1135 lib/uninstall.c:43 +#: lib/install.c:879 lib/install.c:1149 lib/uninstall.c:43 #, c-format msgid "rename of %s to %s failed: %s\n" msgstr "" -#: lib/install.c:960 +#: lib/install.c:974 msgid "source package expected, binary found\n" msgstr "" -#: lib/install.c:1005 +#: lib/install.c:1013 #, c-format msgid "package: %s-%s-%s files test = %d\n" msgstr "" -#: lib/install.c:1049 +#: lib/install.c:1054 msgid "stopping install as we're running --test\n" msgstr "" -#: lib/install.c:1054 +#: lib/install.c:1059 msgid "running preinstall script (if any)\n" msgstr "" -#: lib/install.c:1061 +#: lib/install.c:1066 msgid "skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n" msgstr "" -#: lib/install.c:1095 +#: lib/install.c:1103 #, c-format -msgid "%s created as %s\n" +msgid "%s%s created as %s\n" msgstr "" -#: lib/install.c:1131 +#: lib/install.c:1144 #, c-format msgid "%s saved as %s\n" msgstr "" -#: lib/install.c:1227 +#: lib/install.c:1229 msgid "running postinstall scripts (if any)\n" msgstr "" @@ -3554,7 +3554,7 @@ msgstr "" msgid "Please contact rpm-list@redhat.com\n" msgstr "" -#: lib/scriptlet.c:233 +#: lib/scriptlet.c:241 #, c-format msgid "execution of %s scriptlet from %s-%s-%s failed, exit status %d\n" msgstr "" |