Sanitize archive creation
- Get rid of the crazy tag-tango around rpmfi in genCpioListAndHeader(): pkg->cpioList is an rpmfi with the actual in-package paths, and on-disk package paths are passed around as a separate array. This simplifies and sanitizes things a lot... and also finally gets rid of fi->apath entirely. - Dependency generation wants on-disk paths, but it can generate those by prepending buildroot, which actually makes it more obvious what's going on. - This also kills %{_noPayloadPrefix} ancient-history compatibility flag. We could honor it in rpmfiArchiveWriteHeader() if we cared but we're talking about rpm < 3.0.5 compatibility here ... so we dont.
This commit is contained in:
parent
e0dd56a156
commit
0c2a5d5868
|
@ -908,13 +908,9 @@ static int seenHardLink(FileRecords files, FileListRec flp, rpm_ino_t *fileid)
|
|||
*/
|
||||
static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
|
||||
{
|
||||
int _addDotSlash = !(isSrc || rpmExpandNumeric("%{_noPayloadPrefix}"));
|
||||
size_t apathlen = 0;
|
||||
size_t dpathlen = 0;
|
||||
size_t skipLen = 0;
|
||||
FileListRec flp;
|
||||
char buf[BUFSIZ];
|
||||
int i;
|
||||
int i, npaths = 0;
|
||||
uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo;
|
||||
rpm_loff_t totalFileSize = 0;
|
||||
Header h = pkg->header; /* just a shortcut */
|
||||
|
@ -940,11 +936,9 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
|
|||
qsort(fl->files.recs, fl->files.used,
|
||||
sizeof(*(fl->files.recs)), compareFileListRecs);
|
||||
|
||||
/* Generate the header. */
|
||||
if (! isSrc) {
|
||||
skipLen = 1;
|
||||
}
|
||||
pkg->dpaths = xmalloc((fl->files.used + 1) * sizeof(*pkg->dpaths));
|
||||
|
||||
/* Generate the header. */
|
||||
for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) {
|
||||
rpm_ino_t fileid = flp - fl->files.recs;
|
||||
|
||||
|
@ -1002,19 +996,10 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
|
|||
/* Skip files that were marked with %exclude. */
|
||||
if (flp->flags & RPMFILE_EXCLUDE) continue;
|
||||
|
||||
/* Omit '/' and/or URL prefix, leave room for "./" prefix */
|
||||
apathlen += (strlen(flp->cpioPath) - skipLen + (_addDotSlash ? 3 : 1));
|
||||
/* Collect on-disk paths for archive creation */
|
||||
pkg->dpaths[npaths++] = xstrdup(flp->diskPath);
|
||||
|
||||
/* Leave room for both dirname and basename NUL's */
|
||||
dpathlen += (strlen(flp->diskPath) + 2);
|
||||
|
||||
/*
|
||||
* Make the header. Store the on-disk path to OLDFILENAMES for
|
||||
* cpio list generation purposes for now, final path temporarily
|
||||
* to ORIGFILENAMES, to be swapped later into OLDFILENAMES.
|
||||
*/
|
||||
headerPutString(h, RPMTAG_OLDFILENAMES, flp->diskPath);
|
||||
headerPutString(h, RPMTAG_ORIGFILENAMES, flp->cpioPath);
|
||||
headerPutString(h, RPMTAG_OLDFILENAMES, flp->cpioPath);
|
||||
headerPutString(h, RPMTAG_FILEUSERNAME,
|
||||
rpmstrPoolStr(fl->pool, flp->uname));
|
||||
headerPutString(h, RPMTAG_FILEGROUPNAME,
|
||||
|
@ -1115,6 +1100,7 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
|
|||
|
||||
headerPutUint32(h, RPMTAG_FILEFLAGS, &(flp->flags) ,1);
|
||||
}
|
||||
pkg->dpaths[npaths] = NULL;
|
||||
|
||||
if (totalFileSize < UINT32_MAX) {
|
||||
rpm_off_t totalsize = totalFileSize;
|
||||
|
@ -1133,60 +1119,21 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
|
|||
rpmlibNeedsFeature(pkg, "FileCaps", "4.6.1-1");
|
||||
}
|
||||
|
||||
if (_addDotSlash)
|
||||
(void) rpmlibNeedsFeature(pkg, "PayloadFilesHavePrefix", "4.0-1");
|
||||
|
||||
{
|
||||
struct rpmtd_s filenames;
|
||||
rpmfiFlags flags = RPMFI_NOHEADER|RPMFI_NOFILEUSER|RPMFI_NOFILEGROUP;
|
||||
rpmfi fi;
|
||||
int fc;
|
||||
const char *fn;
|
||||
char *a, **apath;
|
||||
(void) rpmlibNeedsFeature(pkg, "PayloadFilesHavePrefix", "4.0-1");
|
||||
|
||||
/* rpmfiNew() only groks compressed filelists */
|
||||
headerConvert(h, HEADERCONV_COMPRESSFILELIST);
|
||||
fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, flags);
|
||||
pkg->cpioList = rpmfiNew(NULL, h, RPMTAG_BASENAMES,
|
||||
(RPMFI_NOFILEUSER|RPMFI_NOFILEGROUP));
|
||||
|
||||
if (fi == NULL) {
|
||||
if (pkg->cpioList == NULL || rpmfiFC(pkg->cpioList) != npaths) {
|
||||
fl->processingFailed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab the real filenames from ORIGFILENAMES and put into OLDFILENAMES,
|
||||
* remove temporary cruft and side-effects from filelist compression
|
||||
* for rpmfiNew().
|
||||
*/
|
||||
headerGet(h, RPMTAG_ORIGFILENAMES, &filenames, HEADERGET_ALLOC);
|
||||
headerDel(h, RPMTAG_ORIGFILENAMES);
|
||||
headerDel(h, RPMTAG_BASENAMES);
|
||||
headerDel(h, RPMTAG_DIRNAMES);
|
||||
headerDel(h, RPMTAG_DIRINDEXES);
|
||||
rpmtdSetTag(&filenames, RPMTAG_OLDFILENAMES);
|
||||
headerPut(h, &filenames, HEADERPUT_DEFAULT);
|
||||
|
||||
/* Create hge-style archive path array, normally adding "./" */
|
||||
fc = rpmtdCount(&filenames);
|
||||
apath = xmalloc(fc * sizeof(*apath) + apathlen + 1);
|
||||
a = (char *)(apath + fc);
|
||||
*a = '\0';
|
||||
rpmtdInit(&filenames);
|
||||
for (int i = 0; (fn = rpmtdNextString(&filenames)); i++) {
|
||||
apath[i] = a;
|
||||
if (_addDotSlash)
|
||||
a = stpcpy(a, "./");
|
||||
a = stpcpy(a, (fn + skipLen));
|
||||
a++; /* skip apath NUL */
|
||||
}
|
||||
rpmfiSetApath(fi, apath);
|
||||
pkg->cpioList = fi;
|
||||
rpmtdFreeData(&filenames);
|
||||
}
|
||||
|
||||
/* Compress filelist unless legacy format requested */
|
||||
if (!(fl->pkgFlags & RPMBUILD_PKG_NODIRTOKENS)) {
|
||||
headerConvert(h, HEADERCONV_COMPRESSFILELIST);
|
||||
if (fl->pkgFlags & RPMBUILD_PKG_NODIRTOKENS) {
|
||||
/* Uncompress filelist if legacy format requested */
|
||||
headerConvert(h, HEADERCONV_EXPANDFILELIST);
|
||||
} else {
|
||||
/* Binary packages with dirNames cannot be installed by legacy rpm. */
|
||||
(void) rpmlibNeedsFeature(pkg, "CompressedFileNames", "3.0.4-1");
|
||||
}
|
||||
|
|
21
build/pack.c
21
build/pack.c
|
@ -32,17 +32,19 @@
|
|||
* @retval failedFile name of failed file on error
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int writeFile(rpmfi fi, int writeData, char **failedFile)
|
||||
static int writeFile(rpmfi fi, ARGV_t dpaths, int writeData,
|
||||
char **failedFile)
|
||||
{
|
||||
FD_t rfd = NULL;
|
||||
int rc = 0;
|
||||
const char *path = dpaths[rpmfiFX(fi)];
|
||||
|
||||
rc = rpmfiArchiveWriteHeader(fi);
|
||||
|
||||
if (rc) goto exit;
|
||||
|
||||
if (writeData && S_ISREG(rpmfiFMode(fi))) {
|
||||
rfd = Fopen(rpmfiFN(fi), "r.ufdio");
|
||||
rfd = Fopen(path, "r.ufdio");
|
||||
if (Ferror(rfd)) {
|
||||
rc = CPIOERR_OPEN_FAILED;
|
||||
goto exit;
|
||||
|
@ -61,7 +63,7 @@ static int writeFile(rpmfi fi, int writeData, char **failedFile)
|
|||
|
||||
exit:
|
||||
if (rc && failedFile)
|
||||
*failedFile = xstrdup(rpmfiFN(fi));
|
||||
*failedFile = xstrdup(path);
|
||||
if (rfd) {
|
||||
/* preserve any prior errno across close */
|
||||
int myerrno = errno;
|
||||
|
@ -71,7 +73,7 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int writeLinks(rpmfi fi, char **failedFile)
|
||||
static int writeLinks(rpmfi fi, ARGV_t dpaths, char **failedFile)
|
||||
{
|
||||
int rc = 0;
|
||||
rpmfi xfi = rpmfilesIter(rpmfiFiles(fi), RPMFI_ITER_FWD);
|
||||
|
@ -88,7 +90,7 @@ static int writeLinks(rpmfi fi, char **failedFile)
|
|||
rpmfiSetFX(fi, hardlinks[j]);
|
||||
|
||||
/* Write data after last link. */
|
||||
rc = writeFile(fi, (j == numHardlinks-1), failedFile);
|
||||
rc = writeFile(fi, dpaths, (j == numHardlinks-1), failedFile);
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
|
@ -100,7 +102,7 @@ static int writeLinks(rpmfi fi, char **failedFile)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int rpmPackageFilesArchive(rpmfi fi, int isSrc, FD_t cfd,
|
||||
static int rpmPackageFilesArchive(rpmfi fi, int isSrc, FD_t cfd, ARGV_t dpaths,
|
||||
rpm_loff_t * archiveSize, char ** failedFile)
|
||||
{
|
||||
int rc = rpmfiAttachArchive(fi, cfd, O_WRONLY);
|
||||
|
@ -114,12 +116,12 @@ static int rpmPackageFilesArchive(rpmfi fi, int isSrc, FD_t cfd,
|
|||
continue;
|
||||
|
||||
/* Copy file into archive. */
|
||||
rc = writeFile(fi, 1, failedFile);
|
||||
rc = writeFile(fi, dpaths, 1, failedFile);
|
||||
}
|
||||
|
||||
/* Flush partial sets of hard linked files. */
|
||||
if (!rc)
|
||||
rc = writeLinks(fi, failedFile);
|
||||
rc = writeLinks(fi, dpaths, failedFile);
|
||||
|
||||
if (archiveSize)
|
||||
*archiveSize = (rc == 0) ? rpmfiArchiveTell(fi) : 0;
|
||||
|
@ -145,7 +147,8 @@ static rpmRC cpio_doio(FD_t fdo, Package pkg, const char * fmodeMacro)
|
|||
return RPMRC_FAIL;
|
||||
|
||||
fsmrc = rpmPackageFilesArchive(pkg->cpioList, headerIsSource(pkg->header),
|
||||
cfd, &pkg->cpioArchiveSize, &failedFile);
|
||||
cfd, pkg->dpaths,
|
||||
&pkg->cpioArchiveSize, &failedFile);
|
||||
|
||||
if (fsmrc) {
|
||||
char *emsg = rpmcpioStrerror(fsmrc);
|
||||
|
|
|
@ -99,6 +99,7 @@ struct Package_s {
|
|||
rpmds order;
|
||||
rpmfi cpioList;
|
||||
rpm_loff_t cpioArchiveSize;
|
||||
ARGV_t dpaths;
|
||||
|
||||
struct Source * icon;
|
||||
|
||||
|
|
|
@ -1178,6 +1178,7 @@ static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi f
|
|||
/* Create file manifest buffer to deliver to dependency finder. */
|
||||
fi = rpmfiInit(fi, 0);
|
||||
while (rpmfiNext(fi) >= 0)
|
||||
appendStringBuf(sb_stdin, spec->buildRoot);
|
||||
appendLineStringBuf(sb_stdin, rpmfiFN(fi));
|
||||
|
||||
for (DepMsg_t dm = DepMsgs; dm->msg != NULL; dm++) {
|
||||
|
@ -1268,7 +1269,7 @@ rpmRC rpmfcGenerateDepends(const rpmSpec spec, Package pkg)
|
|||
/* Does package have any %config files? */
|
||||
genConfigDeps |= (rpmfiFFlags(fi) & RPMFILE_CONFIG);
|
||||
|
||||
av[idx] = xstrdup(rpmfiFN(fi));
|
||||
av[idx] = rstrscat(NULL, spec->buildRoot, rpmfiFN(fi), NULL);
|
||||
fmode[idx] = rpmfiFMode(fi);
|
||||
}
|
||||
av[ac] = NULL;
|
||||
|
|
|
@ -103,6 +103,7 @@ Package newPackage(const char *name, rpmstrPool pool, Package *pkglist)
|
|||
p->fileFile = NULL;
|
||||
p->policyList = NULL;
|
||||
p->pool = rpmstrPoolLink(pool);
|
||||
p->dpaths = NULL;
|
||||
|
||||
if (name)
|
||||
p->name = rpmstrPoolId(p->pool, name, 1);
|
||||
|
@ -145,6 +146,7 @@ static Package freePackage(Package pkg)
|
|||
pkg->fileFile = argvFree(pkg->fileFile);
|
||||
pkg->policyList = argvFree(pkg->policyList);
|
||||
pkg->cpioList = rpmfiFree(pkg->cpioList);
|
||||
pkg->dpaths = argvFree(pkg->dpaths);
|
||||
|
||||
pkg->icon = freeSources(pkg->icon);
|
||||
pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
|
||||
|
|
25
lib/rpmfi.c
25
lib/rpmfi.c
|
@ -50,7 +50,6 @@ struct rpmfi_s {
|
|||
|
||||
rpmfiles files; /*!< File info set */
|
||||
rpmcpio_t archive; /*!< Archive with payload */
|
||||
char ** apath;
|
||||
int nrefs; /*!< Reference count */
|
||||
};
|
||||
|
||||
|
@ -1136,7 +1135,6 @@ rpmfi rpmfiFree(rpmfi fi)
|
|||
fi->files = rpmfilesFree(fi->files);
|
||||
fi->fn = _free(fi->fn);
|
||||
fi->ofn = _free(fi->ofn);
|
||||
fi->apath = _free(fi->apath);
|
||||
|
||||
free(fi);
|
||||
return NULL;
|
||||
|
@ -1525,15 +1523,6 @@ void rpmfilesFpLookup(rpmfiles fi, fingerPrintCache fpc)
|
|||
}
|
||||
}
|
||||
|
||||
void rpmfiSetApath(rpmfi fi, char **apath)
|
||||
{
|
||||
if (fi != NULL) {
|
||||
fi->apath = _free(fi->apath);
|
||||
if (apath)
|
||||
fi->apath = apath;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate iterator accessors function wrappers, these do nothing but
|
||||
* call the corresponding rpmfiFooIndex(fi, fi->[ij])
|
||||
|
@ -1706,15 +1695,11 @@ int rpmfiArchiveWriteHeader(rpmfi fi)
|
|||
st.st_gid = gid;
|
||||
st.st_size = fsize;
|
||||
|
||||
if (fi->apath) {
|
||||
rc = rpmcpioHeaderWrite(fi->archive, fi->apath[rpmfiFX(fi)], &st);
|
||||
} else {
|
||||
const char * dn = rpmfiDN(fi);
|
||||
char * path = rstrscat(NULL, (dn[0] == '/') ? "." : "",
|
||||
dn, rpmfiBN(fi), NULL);
|
||||
rc = rpmcpioHeaderWrite(fi->archive, path, &st);
|
||||
free(path);
|
||||
}
|
||||
const char * dn = rpmfiDN(fi);
|
||||
char * path = rstrscat(NULL, (dn[0] == '/') ? "." : "",
|
||||
dn, rpmfiBN(fi), NULL);
|
||||
rc = rpmcpioHeaderWrite(fi->archive, path, &st);
|
||||
free(path);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -196,9 +196,6 @@ int rpmfilesDigestAlgo(rpmfiles fi);
|
|||
|
||||
rpm_color_t rpmfilesColor(rpmfiles files);
|
||||
|
||||
/* Temporary ugly kludge to eliminate direct struct rpmfi access... */
|
||||
void rpmfiSetApath(rpmfi fi, char **apath);
|
||||
|
||||
/** \ingroup payload
|
||||
* Add payload archive to the file info
|
||||
* @param fi file info
|
||||
|
|
Loading…
Reference in New Issue