summaryrefslogtreecommitdiff
path: root/build/pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'build/pack.c')
-rw-r--r--build/pack.c764
1 files changed, 382 insertions, 382 deletions
diff --git a/build/pack.c b/build/pack.c
index 6480cecaa..34e0568a7 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -6,8 +6,7 @@
#include "system.h"
#include <errno.h>
-#include <netdb.h>
-#include <time.h>
+#include <sys/wait.h>
#include <rpm/rpmlib.h> /* RPMSIGTAG*, rpmReadPackageFile */
#include <rpm/rpmfileutil.h>
@@ -15,7 +14,6 @@
#include "rpmio/rpmio_internal.h" /* fdInitDigest, fdFiniDigest */
#include "lib/fsm.h"
-#include "lib/cpio.h"
#include "lib/signature.h"
#include "lib/rpmlead.h"
#include "build/rpmbuild_internal.h"
@@ -23,15 +21,54 @@
#include "debug.h"
-typedef struct cpioSourceArchive_s {
- rpm_loff_t cpioArchiveSize;
- rpmfi cpioList;
-} * CSA_t;
+static int rpmPackageFilesArchive(rpmfiles fi, int isSrc,
+ FD_t cfd, ARGV_t dpaths,
+ rpm_loff_t * archiveSize, char ** failedFile)
+{
+ int rc = 0;
+ rpmfi archive = rpmfiNewArchiveWriter(cfd, fi);
+
+ while (!rc && (rc = rpmfiNext(archive)) >= 0) {
+ /* Copy file into archive. */
+ FD_t rfd = NULL;
+ const char *path = dpaths[rpmfiFX(archive)];
+
+ rfd = Fopen(path, "r.ufdio");
+ if (Ferror(rfd)) {
+ rc = RPMERR_OPEN_FAILED;
+ } else {
+ rc = rpmfiArchiveWriteFile(archive, rfd);
+ }
+
+ if (rc && failedFile)
+ *failedFile = xstrdup(path);
+ if (rfd) {
+ /* preserve any prior errno across close */
+ int myerrno = errno;
+ Fclose(rfd);
+ errno = myerrno;
+ }
+ }
+
+ if (rc == RPMERR_ITER_END)
+ rc = 0;
+
+ /* Finish the payload stream */
+ if (!rc)
+ rc = rpmfiArchiveClose(archive);
+
+ if (archiveSize)
+ *archiveSize = (rc == 0) ? rpmfiArchiveTell(archive) : 0;
+
+ rpmfiFree(archive);
+ return rc;
+}
/**
* @todo Create transaction set *much* earlier.
*/
-static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa, const char * fmodeMacro)
+static rpmRC cpio_doio(FD_t fdo, Package pkg, const char * fmodeMacro,
+ rpm_loff_t *archiveSize)
{
char *failedFile = NULL;
FD_t cfd;
@@ -42,16 +79,18 @@ static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa, const char * fmodeMacro)
if (cfd == NULL)
return RPMRC_FAIL;
- fsmrc = rpmPackageFilesArchive(csa->cpioList, headerIsSource(h), cfd,
- &csa->cpioArchiveSize, &failedFile);
+ fsmrc = rpmPackageFilesArchive(pkg->cpioList, headerIsSource(pkg->header),
+ cfd, pkg->dpaths,
+ archiveSize, &failedFile);
if (fsmrc) {
+ char *emsg = rpmfileStrerror(fsmrc);
if (failedFile)
rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"),
- failedFile, rpmcpioStrerror(fsmrc));
+ failedFile, emsg);
else
- rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"),
- rpmcpioStrerror(fsmrc));
+ rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"), emsg);
+ free(emsg);
}
free(failedFile);
@@ -92,11 +131,13 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file,
}
while (fgets(buf, sizeof(buf), f)) {
- if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
+ char *expanded;
+ if (rpmExpandMacros(spec->macros, buf, &expanded, 0) < 0) {
rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf);
goto exit;
}
- appendStringBuf(sb, buf);
+ appendStringBuf(sb, expanded);
+ free(expanded);
}
headerPutString(h, tag, getStringBuf(sb));
rc = RPMRC_OK;
@@ -109,40 +150,31 @@ exit:
return rc;
}
-static rpm_time_t * getBuildTime(void)
-{
- static rpm_time_t buildTime[1];
-
- if (buildTime[0] == 0)
- buildTime[0] = (int32_t) time(NULL);
- return buildTime;
-}
-
-static const char * buildHost(void)
-{
- static char hostname[1024];
- static int oneshot = 0;
- struct hostent *hbn;
-
- if (! oneshot) {
- (void) gethostname(hostname, sizeof(hostname));
- hbn = gethostbyname(hostname);
- if (hbn)
- strcpy(hostname, hbn->h_name);
- else
- rpmlog(RPMLOG_WARNING,
- _("Could not canonicalize hostname: %s\n"), hostname);
- oneshot = 1;
- }
- return(hostname);
-}
-
static rpmRC processScriptFiles(rpmSpec spec, Package pkg)
{
struct TriggerFileEntry *p;
int addflags = 0;
rpmRC rc = RPMRC_FAIL;
Header h = pkg->header;
+ struct TriggerFileEntry *tfa[] = {pkg->triggerFiles,
+ pkg->fileTriggerFiles,
+ pkg->transFileTriggerFiles};
+
+ rpmTagVal progTags[] = {RPMTAG_TRIGGERSCRIPTPROG,
+ RPMTAG_FILETRIGGERSCRIPTPROG,
+ RPMTAG_TRANSFILETRIGGERSCRIPTPROG};
+
+ rpmTagVal flagTags[] = {RPMTAG_TRIGGERSCRIPTFLAGS,
+ RPMTAG_FILETRIGGERSCRIPTFLAGS,
+ RPMTAG_TRANSFILETRIGGERSCRIPTFLAGS};
+
+ rpmTagVal scriptTags[] = {RPMTAG_TRIGGERSCRIPTS,
+ RPMTAG_FILETRIGGERSCRIPTS,
+ RPMTAG_TRANSFILETRIGGERSCRIPTS};
+ rpmTagVal priorityTags[] = {0,
+ RPMTAG_FILETRIGGERPRIORITIES,
+ RPMTAG_TRANSFILETRIGGERPRIORITIES};
+ int i;
if (addFileToTag(spec, pkg->preInFile, h, RPMTAG_PREIN, 1) ||
addFileToTag(spec, pkg->preUnFile, h, RPMTAG_PREUN, 1) ||
@@ -155,30 +187,39 @@ static rpmRC processScriptFiles(rpmSpec spec, Package pkg)
goto exit;
}
- /* if any trigger has flags, we need to add flags entry for all of them */
- for (p = pkg->triggerFiles; p != NULL; p = p->next) {
- if (p->flags) {
- addflags = 1;
- break;
- }
- }
- for (p = pkg->triggerFiles; p != NULL; p = p->next) {
- headerPutString(h, RPMTAG_TRIGGERSCRIPTPROG, p->prog);
- if (addflags) {
- headerPutUint32(h, RPMTAG_TRIGGERSCRIPTFLAGS, &p->flags, 1);
+ for (i = 0; i < sizeof(tfa)/sizeof(tfa[0]); i++) {
+ addflags = 0;
+ /* if any trigger has flags, we need to add flags entry for all of them */
+ for (p = tfa[i]; p != NULL; p = p->next) {
+ if (p->flags) {
+ addflags = 1;
+ break;
+ }
}
- if (p->script) {
- headerPutString(h, RPMTAG_TRIGGERSCRIPTS, p->script);
- } else if (p->fileName) {
- if (addFileToTag(spec, p->fileName, h, RPMTAG_TRIGGERSCRIPTS, 0)) {
- goto exit;
+ for (p = tfa[i]; p != NULL; p = p->next) {
+ headerPutString(h, progTags[i], p->prog);
+
+ if (priorityTags[i]) {
+ headerPutUint32(h, priorityTags[i], &p->priority, 1);
+ }
+
+ if (addflags) {
+ headerPutUint32(h, flagTags[i], &p->flags, 1);
+ }
+
+ if (p->script) {
+ headerPutString(h, scriptTags[i], p->script);
+ } else if (p->fileName) {
+ if (addFileToTag(spec, p->fileName, h, scriptTags[i], 0)) {
+ goto exit;
+ }
+ } else {
+ /* This is dumb. When the header supports NULL string */
+ /* this will go away. */
+ headerPutString(h, scriptTags[i], "");
}
- } else {
- /* This is dumb. When the header supports NULL string */
- /* this will go away. */
- headerPutString(h, RPMTAG_TRIGGERSCRIPTS, "");
}
}
rc = RPMRC_OK;
@@ -187,92 +228,40 @@ exit:
return rc;
}
-static rpmRC copyPayload(FD_t ifd, const char *ifn, FD_t ofd, const char *ofn)
+static int haveTildeDep(Package pkg)
{
- char buf[BUFSIZ];
- size_t nb;
- rpmRC rc = RPMRC_OK;
-
- while ((nb = Fread(buf, 1, sizeof(buf), ifd)) > 0) {
- if (Fwrite(buf, sizeof(buf[0]), nb, ofd) != nb) {
- rpmlog(RPMLOG_ERR, _("Unable to write payload to %s: %s\n"),
- ofn, Fstrerror(ofd));
- rc = RPMRC_FAIL;
- break;
+ for (int i = 0; i < PACKAGE_NUM_DEPS; i++) {
+ rpmds ds = rpmdsInit(pkg->dependencies[i]);
+ while (rpmdsNext(ds) >= 0) {
+ if (strchr(rpmdsEVR(ds), '~'))
+ return 1;
}
}
-
- if (nb < 0) {
- rpmlog(RPMLOG_ERR, _("Unable to read payload from %s: %s\n"),
- ifn, Fstrerror(ifd));
- rc = RPMRC_FAIL;
- }
-
- return rc;
+ return 0;
}
-static int depContainsTilde(Header h, rpmTagVal tagEVR)
+static int haveRichDep(Package pkg)
{
- struct rpmtd_s evrs;
- const char *evr = NULL;
-
- if (headerGet(h, tagEVR, &evrs, HEADERGET_MINMEM)) {
- while ((evr = rpmtdNextString(&evrs)) != NULL)
- if (strchr(evr, '~'))
- break;
- rpmtdFreeData(&evrs);
+ for (int i = 0; i < PACKAGE_NUM_DEPS; i++) {
+ rpmds ds = rpmdsInit(pkg->dependencies[i]);
+ rpmTagVal tagN = rpmdsTagN(ds);
+ if (tagN != RPMTAG_REQUIRENAME && tagN != RPMTAG_CONFLICTNAME)
+ continue;
+ while (rpmdsNext(ds) >= 0) {
+ if (rpmdsIsRich(ds))
+ return 1;
+ }
}
- return evr != NULL;
-}
-
-static rpmTagVal depevrtags[] = {
- RPMTAG_PROVIDEVERSION,
- RPMTAG_REQUIREVERSION,
- RPMTAG_OBSOLETEVERSION,
- RPMTAG_CONFLICTVERSION,
- RPMTAG_ORDERVERSION,
- RPMTAG_TRIGGERVERSION,
- RPMTAG_SUGGESTSVERSION,
- RPMTAG_ENHANCESVERSION,
- 0
-};
-
-static int haveTildeDep(Header h)
-{
- int i;
-
- for (i = 0; depevrtags[i] != 0; i++)
- if (depContainsTilde(h, depevrtags[i]))
- return 1;
return 0;
}
-static rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
- CSA_t csa, char **cookie)
+static char *getIOFlags(Package pkg)
{
- FD_t fd = NULL;
- FD_t ifd = NULL;
- char * sigtarget = NULL;;
- char * rpmio_flags = NULL;
- char * SHA1 = NULL;
+ char *rpmio_flags;
const char *s;
- Header h;
- Header sig = NULL;
- int xx;
- rpmRC rc = RPMRC_OK;
- struct rpmtd_s td;
- rpmTagVal sizetag;
- rpmTagVal payloadtag;
-
- /* Transfer header reference form *hdrp to h. */
- h = headerLink(*hdrp);
- *hdrp = headerFree(*hdrp);
-
- if (pkgidp)
- *pkgidp = NULL;
/* Save payload information */
- if (headerIsSource(h))
+ if (headerIsSource(pkg->header))
rpmio_flags = rpmExpand("%{?_source_payload}", NULL);
else
rpmio_flags = rpmExpand("%{?_binary_payload}", NULL);
@@ -286,7 +275,7 @@ static rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileNam
if (s) {
char *buf = NULL;
const char *compr = NULL;
- headerPutString(h, RPMTAG_PAYLOADFORMAT, "cpio");
+ headerPutString(pkg->header, RPMTAG_PAYLOADFORMAT, "cpio");
if (rstreq(s+1, "ufdio")) {
compr = NULL;
@@ -296,229 +285,300 @@ static rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileNam
} else if (rstreq(s+1, "bzdio")) {
compr = "bzip2";
/* Add prereq on rpm version that understands bzip2 payloads */
- (void) rpmlibNeedsFeature(h, "PayloadIsBzip2", "3.0.5-1");
+ (void) rpmlibNeedsFeature(pkg, "PayloadIsBzip2", "3.0.5-1");
#endif
#if HAVE_LZMA_H
} else if (rstreq(s+1, "xzdio")) {
compr = "xz";
- (void) rpmlibNeedsFeature(h, "PayloadIsXz", "5.2-1");
+ (void) rpmlibNeedsFeature(pkg, "PayloadIsXz", "5.2-1");
} else if (rstreq(s+1, "lzdio")) {
compr = "lzma";
- (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
+ (void) rpmlibNeedsFeature(pkg, "PayloadIsLzma", "4.4.6-1");
+#endif
+#ifdef HAVE_ZSTD
+ } else if (rstreq(s+1, "zstdio")) {
+ compr = "zstd";
+ /* Add prereq on rpm version that understands zstd payloads */
+ (void) rpmlibNeedsFeature(pkg, "PayloadIsZstd", "5.4.18-1");
#endif
} else {
rpmlog(RPMLOG_ERR, _("Unknown payload compression: %s\n"),
rpmio_flags);
- rc = RPMRC_FAIL;
+ rpmio_flags = _free(rpmio_flags);
goto exit;
}
if (compr)
- headerPutString(h, RPMTAG_PAYLOADCOMPRESSOR, compr);
+ headerPutString(pkg->header, RPMTAG_PAYLOADCOMPRESSOR, compr);
buf = xstrdup(rpmio_flags);
buf[s - rpmio_flags] = '\0';
- headerPutString(h, RPMTAG_PAYLOADFLAGS, buf+1);
+ headerPutString(pkg->header, RPMTAG_PAYLOADFLAGS, buf+1);
free(buf);
}
+exit:
+ return rpmio_flags;
+}
+static void finalizeDeps(Package pkg)
+{
/* check if the package has a dependency with a '~' */
- if (haveTildeDep(h))
- (void) rpmlibNeedsFeature(h, "TildeInVersions", "4.10.0-1");
+ if (haveTildeDep(pkg))
+ (void) rpmlibNeedsFeature(pkg, "TildeInVersions", "4.10.0-1");
+
+ /* check if the package has a rich dependency */
+ if (haveRichDep(pkg))
+ (void) rpmlibNeedsFeature(pkg, "RichDependencies", "4.12.0-1");
+
+ /* All dependencies added finally, write them into the header */
+ for (int i = 0; i < PACKAGE_NUM_DEPS; i++) {
+ /* Nuke any previously added dependencies from the header */
+ headerDel(pkg->header, rpmdsTagN(pkg->dependencies[i]));
+ headerDel(pkg->header, rpmdsTagEVR(pkg->dependencies[i]));
+ headerDel(pkg->header, rpmdsTagF(pkg->dependencies[i]));
+ headerDel(pkg->header, rpmdsTagTi(pkg->dependencies[i]));
+ /* ...and add again, now with automatic dependencies included */
+ rpmdsPutToHeader(pkg->dependencies[i], pkg->header);
+ }
+}
- /* Create and add the cookie */
- if (cookie) {
- rasprintf(cookie, "%s %d", buildHost(), (int) (*getBuildTime()));
- headerPutString(h, RPMTAG_COOKIE, *cookie);
+static void *nullDigest(int algo, int ascii)
+{
+ void *d = NULL;
+ DIGEST_CTX ctx = rpmDigestInit(algo, 0);
+ rpmDigestFinal(ctx, &d, NULL, ascii);
+ return d;
+}
+
+static rpmRC fdJump(FD_t fd, off_t offset)
+{
+ if (Fseek(fd, offset, SEEK_SET) < 0) {
+ rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
+ Fdescr(fd), Fstrerror(fd));
+ return RPMRC_FAIL;
}
-
- /* Reallocate the header into one contiguous region. */
- h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
- if (h == NULL) { /* XXX can't happen */
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to create immutable header region.\n"));
- goto exit;
+ return RPMRC_OK;
+}
+
+static rpmRC fdConsume(FD_t fd, off_t start, off_t nbytes)
+{
+ size_t bufsiz = 32*BUFSIZ;
+ unsigned char buf[bufsiz];
+ off_t left = nbytes;
+ ssize_t nb;
+
+ if (start && fdJump(fd, start))
+ return RPMRC_FAIL;
+
+ while (left > 0) {
+ nb = Fread(buf, 1, (left < bufsiz) ? left : bufsiz, fd);
+ if (nb > 0)
+ left -= nb;
+ else
+ break;
+ };
+
+ if (left) {
+ rpmlog(RPMLOG_ERR, _("Failed to read %jd bytes in file %s: %s\n"),
+ (intmax_t) nbytes, Fdescr(fd), Fstrerror(fd));
}
- /* Re-reference reallocated header. */
- *hdrp = headerLink(h);
- /*
- * Write the header+archive into a temp file so that the size of
- * archive (after compression) can be added to the header.
- */
- fd = rpmMkTempFile(NULL, &sigtarget);
- if (fd == NULL || Ferror(fd)) {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
+ return (left == 0) ? RPMRC_OK : RPMRC_FAIL;
+}
+
+static rpmRC writeHdr(FD_t fd, Header pkgh)
+{
+ /* Reallocate the header into one contiguous region for writing. */
+ Header h = headerReload(headerCopy(pkgh), RPMTAG_HEADERIMMUTABLE);
+ rpmRC rc = RPMRC_FAIL;
+
+ if (h == NULL) {
+ rpmlog(RPMLOG_ERR,_("Unable to create immutable header region\n"));
goto exit;
}
- fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to write temp header\n"));
- } else { /* Write the archive and get the size */
- (void) Fflush(fd);
- fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&SHA1, NULL, 1);
- if (csa->cpioList != NULL) {
- rc = cpio_doio(fd, h, csa, rpmio_flags);
- } else {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Bad CSA data\n"));
- }
+ rpmlog(RPMLOG_ERR, _("Unable to write header to %s: %s\n"),
+ Fdescr(fd), Fstrerror(fd));
+ goto exit;
}
+ (void) Fflush(fd);
+ rc = RPMRC_OK;
+
+exit:
+ headerFree(h);
+ return rc;
+}
+
+/*
+ * This is more than just a little insane:
+ * In order to write the signature, we need to know the size and
+ * the size and digests of the header and payload, which are located
+ * after the signature on disk. We also need a digest of the compressed
+ * payload for the main header, and of course the payload is after the
+ * header on disk. So we need to create placeholders for both the
+ * signature and main header that exactly match the final sizes, calculate
+ * the payload digest, then generate and write the real main header to
+ * be able to FINALLY calculate the digests we need for the signature
+ * header. In other words, we need to write things in the exact opposite
+ * order to how the RPM format is laid on disk.
+ */
+static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
+ const char *fileName, char **cookie,
+ rpm_time_t buildTime, const char* buildHost)
+{
+ FD_t fd = NULL;
+ char * rpmio_flags = NULL;
+ char * SHA1 = NULL;
+ char * SHA256 = NULL;
+ uint8_t * MD5 = NULL;
+ char * pld = NULL;
+ uint32_t pld_algo = PGPHASHALGO_SHA256; /* TODO: macro configuration */
+ rpmRC rc = RPMRC_FAIL; /* assume failure */
+ rpm_loff_t archiveSize = 0;
+ off_t sigStart, hdrStart, payloadStart, payloadEnd;
+
+ if (pkgidp)
+ *pkgidp = NULL;
- if (rc != RPMRC_OK)
+ rpmio_flags = getIOFlags(pkg);
+ if (!rpmio_flags)
goto exit;
- (void) Fclose(fd);
- fd = NULL;
- (void) unlink(fileName);
+ finalizeDeps(pkg);
- /* Generate the signature */
- (void) fflush(stdout);
- sig = rpmNewSignature();
+ /* Create and add the cookie */
+ if (cookie) {
+ rasprintf(cookie, "%s %d", buildHost, buildTime);
+ headerPutString(pkg->header, RPMTAG_COOKIE, *cookie);
+ }
/*
- * There should be rpmlib() dependency on this, but that doesn't
- * really do much good as these are signature tags that get read
- * way before dependency checking has a chance to figure out anything.
- * On the positive side, not inserting the 32bit tag at all means
- * older rpm will just bail out with error message on attempt to read
- * such a package.
+ * Add system-wide Tizen build information
*/
- if (csa->cpioArchiveSize < UINT32_MAX) {
- sizetag = RPMSIGTAG_SIZE;
- payloadtag = RPMSIGTAG_PAYLOADSIZE;
- } else {
- sizetag = RPMSIGTAG_LONGSIZE;
- payloadtag = RPMSIGTAG_LONGARCHIVESIZE;
- }
- (void) rpmGenDigest(sig, sigtarget, sizetag);
- (void) rpmGenDigest(sig, sigtarget, RPMSIGTAG_MD5);
-
- if (SHA1) {
- /* XXX can't use rpmtdFromFoo() on RPMSIGTAG_* items */
- rpmtdReset(&td);
- td.tag = RPMSIGTAG_SHA1;
- td.type = RPM_STRING_TYPE;
- td.data = SHA1;
- td.count = 1;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- SHA1 = _free(SHA1);
- }
+ char *buildinfo = rpmExpand("%{?_buildinfo}", NULL);
+ if (buildinfo && *buildinfo) {
+ int xx;
+ int count = 0;
+ char **strings = NULL;
- {
- /* XXX can't use headerPutType() on legacy RPMSIGTAG_* items */
- rpmtdReset(&td);
- td.tag = payloadtag;
- td.count = 1;
- if (payloadtag == RPMSIGTAG_PAYLOADSIZE) {
- rpm_off_t asize = csa->cpioArchiveSize;
- td.type = RPM_INT32_TYPE;
- td.data = &asize;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- } else {
- rpm_loff_t asize = csa->cpioArchiveSize;
- td.type = RPM_INT64_TYPE;
- td.data = &asize;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- }
+
+ if ((xx = poptParseArgvString(buildinfo, &count, &strings))) {
+ rc = RPMRC_FAIL;
+ free(buildinfo);
+ rpmlog(RPMLOG_ERR, _("Can't parse BUILDINFO tag: %s\n"), poptStrerror(xx));
+ goto exit;
+ }
+
+ if (count)
+ headerPutStringArray(pkg->header, RPMTAG_BUILDINFO, strings, count);
+
+ strings = _free(strings);
}
+ free(buildinfo);
- /* Reallocate the signature into one contiguous region. */
- sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
- if (sig == NULL) { /* XXX can't happen */
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
+ /* Create a dummy payload digest to get the header size right */
+ pld = nullDigest(pld_algo, 1);
+ headerPutUint32(pkg->header, RPMTAG_PAYLOADDIGESTALGO, &pld_algo, 1);
+ headerPutString(pkg->header, RPMTAG_PAYLOADDIGEST, pld);
+ pld = _free(pld);
+
+ /* Check for UTF-8 encoding of string tags, add encoding tag if all good */
+ if (checkForEncoding(pkg->header, 1))
goto exit;
- }
/* Open the output file */
- fd = Fopen(fileName, "w.ufdio");
+ fd = Fopen(fileName, "w+.ufdio");
if (fd == NULL || Ferror(fd)) {
- rc = RPMRC_FAIL;
rpmlog(RPMLOG_ERR, _("Could not open %s: %s\n"),
fileName, Fstrerror(fd));
goto exit;
}
/* Write the lead section into the package. */
- {
- rpmlead lead = rpmLeadFromHeader(h);
- rc = rpmLeadWrite(fd, lead);
- rpmLeadFree(lead);
- if (rc != RPMRC_OK) {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
- Fstrerror(fd));
- goto exit;
- }
+ if (rpmLeadWrite(fd, pkg->header)) {
+ rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"), Fstrerror(fd));
+ goto exit;
}
- /* Write the signature section into the package. */
- if (rpmWriteSignature(fd, sig)) {
- rc = RPMRC_FAIL;
+ /* Save the position of signature section */
+ sigStart = Ftell(fd);
+
+ /* Generate and write a placeholder signature header */
+ SHA1 = nullDigest(PGPHASHALGO_SHA1, 1);
+ SHA256 = nullDigest(PGPHASHALGO_SHA256, 1);
+ MD5 = nullDigest(PGPHASHALGO_MD5, 0);
+ if (rpmGenerateSignature(SHA256, SHA1, MD5, 0, 0, fd))
goto exit;
- }
+ SHA1 = _free(SHA1);
+ SHA256 = _free(SHA256);
+ MD5 = _free(MD5);
- /* Append the header and archive */
- ifd = Fopen(sigtarget, "r.ufdio");
- if (ifd == NULL || Ferror(ifd)) {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to open sigtarget %s: %s\n"),
- sigtarget, Fstrerror(ifd));
+ /* Write a placeholder header. */
+ hdrStart = Ftell(fd);
+ if (writeHdr(fd, pkg->header))
goto exit;
- }
- /* Add signatures to header, and write header into the package. */
- /* XXX header+payload digests/signatures might be checked again here. */
- { Header nh = headerRead(ifd, HEADER_MAGIC_YES);
+ /* Write payload section (cpio archive) */
+ payloadStart = Ftell(fd);
+ if (cpio_doio(fd, pkg, rpmio_flags, &archiveSize))
+ goto exit;
+ payloadEnd = Ftell(fd);
- if (nh == NULL) {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to read header from %s: %s\n"),
- sigtarget, Fstrerror(ifd));
- goto exit;
- }
+ /* Re-read payload to calculate compressed digest */
+ fdInitDigestID(fd, pld_algo, RPMTAG_PAYLOADDIGEST, 0);
+ if (fdConsume(fd, payloadStart, payloadEnd - payloadStart))
+ goto exit;
+ fdFiniDigest(fd, RPMTAG_PAYLOADDIGEST, (void **)&pld, NULL, 1);
- xx = headerWrite(fd, nh, HEADER_MAGIC_YES);
- headerFree(nh);
+ /* Insert the payload digest in main header */
+ headerDel(pkg->header, RPMTAG_PAYLOADDIGEST);
+ headerPutString(pkg->header, RPMTAG_PAYLOADDIGEST, pld);
+ pld = _free(pld);
- if (xx) {
- rc = RPMRC_FAIL;
- rpmlog(RPMLOG_ERR, _("Unable to write header to %s: %s\n"),
- fileName, Fstrerror(fd));
- goto exit;
- }
- }
-
- /* Write the payload into the package. */
- rc = copyPayload(ifd, fileName, fd, sigtarget);
+ /* Write the final header */
+ if (fdJump(fd, hdrStart))
+ goto exit;
+ if (writeHdr(fd, pkg->header))
+ goto exit;
+
+ /* Calculate digests: SHA on header, legacy MD5 on header + payload */
+ fdInitDigestID(fd, PGPHASHALGO_MD5, RPMTAG_SIGMD5, 0);
+ fdInitDigestID(fd, PGPHASHALGO_SHA1, RPMTAG_SHA1HEADER, 0);
+ fdInitDigestID(fd, PGPHASHALGO_SHA256, RPMTAG_SHA256HEADER, 0);
+ if (fdConsume(fd, hdrStart, payloadStart - hdrStart))
+ goto exit;
+ fdFiniDigest(fd, RPMTAG_SHA1HEADER, (void **)&SHA1, NULL, 1);
+ fdFiniDigest(fd, RPMTAG_SHA256HEADER, (void **)&SHA256, NULL, 1);
+
+ if (fdConsume(fd, 0, payloadEnd - payloadStart))
+ goto exit;
+ fdFiniDigest(fd, RPMTAG_SIGMD5, (void **)&MD5, NULL, 0);
+
+ if (fdJump(fd, sigStart))
+ goto exit;
+
+ /* Generate the signature. Now with right values */
+ if (rpmGenerateSignature(SHA256, SHA1, MD5, payloadEnd - hdrStart, archiveSize, fd))
+ goto exit;
+
+ rc = RPMRC_OK;
exit:
free(rpmio_flags);
free(SHA1);
- headerFree(h);
+ free(SHA256);
/* XXX Fish the pkgid out of the signature header. */
- if (sig != NULL && pkgidp != NULL) {
- struct rpmtd_s md5tag;
- headerGet(sig, RPMSIGTAG_MD5, &md5tag, HEADERGET_DEFAULT);
- if (rpmtdType(&md5tag) == RPM_BIN_TYPE &&
- md5tag.count == 16 && md5tag.data != NULL) {
- *pkgidp = md5tag.data;
+ if (pkgidp != NULL) {
+ if (MD5 != NULL) {
+ *pkgidp = MD5;
}
+ } else {
+ free(MD5);
}
- rpmFreeSignature(sig);
- Fclose(ifd);
Fclose(fd);
- if (sigtarget) {
- (void) unlink(sigtarget);
- free(sigtarget);
- }
-
if (rc == RPMRC_OK)
rpmlog(RPMLOG_NOTICE, _("Wrote: %s\n"), fileName);
else
@@ -553,78 +613,13 @@ static rpmRC checkPackages(char *pkgcheck)
return RPMRC_OK;
}
-static void trimChangelog(Header h)
-{
- static int oneshot;
- static int cuttime, minnum, maxnum;
- int * times;
- char ** names = 0, ** texts = 0;
- int i, keep, count = 0;
-
- if (!oneshot) {
- char *binarychangelogtrim = rpmExpand("%{?_binarychangelogtrim}", NULL);
- oneshot = 1;
- if (binarychangelogtrim && *binarychangelogtrim) {
- maxnum = atoi(binarychangelogtrim);
- binarychangelogtrim = strchr(binarychangelogtrim, ',');
- if (binarychangelogtrim)
- binarychangelogtrim++;
- }
- if (binarychangelogtrim && *binarychangelogtrim) {
- cuttime = atoi(binarychangelogtrim);
- binarychangelogtrim = strchr(binarychangelogtrim, ',');
- if (binarychangelogtrim)
- binarychangelogtrim++;
- }
- if (binarychangelogtrim && *binarychangelogtrim) {
- minnum = atoi(binarychangelogtrim);
- binarychangelogtrim = strchr(binarychangelogtrim, ',');
- }
- }
- if (!cuttime && !minnum && !maxnum) {
- return;
- }
- if (!headerGetEntry(h, RPMTAG_CHANGELOGTIME, NULL, (void **) &times, &count))
- return;
- if ((!cuttime || count <= minnum) && (!maxnum || count <= maxnum)) {
- return;
- }
- keep = count;
- if (maxnum && keep > maxnum)
- keep = maxnum;
- if (cuttime) {
- for (i = 0; i < keep; i++) {
- if (i >= minnum && times[i] < cuttime)
- break;
- }
- keep = i;
- }
- if (keep >= count)
- return;
- headerGetEntry(h, RPMTAG_CHANGELOGNAME, NULL, (void **) &names, &count);
- headerGetEntry(h, RPMTAG_CHANGELOGTEXT, NULL, (void **) &texts, &count);
- headerModifyEntry(h, RPMTAG_CHANGELOGTIME, RPM_INT32_TYPE, times, keep);
- headerModifyEntry(h, RPMTAG_CHANGELOGNAME, RPM_STRING_ARRAY_TYPE, names, keep);
- headerModifyEntry(h, RPMTAG_CHANGELOGTEXT, RPM_STRING_ARRAY_TYPE, texts, keep);
- free(names);
- free(texts);
-}
-
-rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
+static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int cheating, char** filename)
{
- struct cpioSourceArchive_s csabuf;
- CSA_t csa = &csabuf;
- rpmRC rc;
- const char *errorString;
- Package pkg;
- char *pkglist = NULL;
-
- trimChangelog(spec->packages->header);
- for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
- char *fn;
+ const char *errorString;
+ rpmRC rc = RPMRC_OK;
if (pkg->fileList == NULL)
- continue;
+ return rc;
if ((rc = processScriptFiles(spec, pkg)))
return rc;
@@ -637,15 +632,15 @@ rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
headerCopyTags(spec->packages->header, pkg->header, copyTags);
headerPutString(pkg->header, RPMTAG_RPMVERSION, VERSION);
- headerPutString(pkg->header, RPMTAG_BUILDHOST, buildHost());
- headerPutUint32(pkg->header, RPMTAG_BUILDTIME, getBuildTime(), 1);
+ headerPutString(pkg->header, RPMTAG_BUILDHOST, spec->buildHost);
+ headerPutUint32(pkg->header, RPMTAG_BUILDTIME, &(spec->buildTime), 1);
if (spec->sourcePkgId != NULL) {
headerPutBin(pkg->header, RPMTAG_SOURCEPKGID, spec->sourcePkgId,16);
}
if (cheating) {
- (void) rpmlibNeedsFeature(pkg->header, "ShortCircuited", "4.9.0-1");
+ (void) rpmlibNeedsFeature(pkg, "ShortCircuited", "4.9.0-1");
}
{ char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
@@ -658,14 +653,14 @@ rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
headerGetString(pkg->header, RPMTAG_NAME), errorString);
return RPMRC_FAIL;
}
- fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
+ *filename = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
if ((binDir = strchr(binRpm, '/')) != NULL) {
struct stat st;
char *dn;
*binDir = '\0';
dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
if (stat(dn, &st) < 0) {
- switch(errno) {
+ switch (errno) {
case ENOENT:
if (mkdir(dn, 0755) == 0)
break;
@@ -680,19 +675,28 @@ rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
free(binRpm);
}
- memset(csa, 0, sizeof(*csa));
- csa->cpioArchiveSize = 0;
- csa->cpioList = rpmfiLink(pkg->cpioList);
-
- rc = writeRPM(&pkg->header, NULL, fn, csa, NULL);
- csa->cpioList = rpmfiFree(csa->cpioList);
+ rc = writeRPM(pkg, NULL, *filename, NULL, spec->buildTime, spec->buildHost);
if (rc == RPMRC_OK) {
/* Do check each written package if enabled */
- char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", fn, NULL);
+ char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", *filename, NULL);
if (pkgcheck[0] != ' ') {
rc = checkPackages(pkgcheck);
}
free(pkgcheck);
+ }
+ return rc;
+}
+
+rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
+{
+ rpmRC rc;
+ Package pkg;
+ char *pkglist = NULL;
+
+ for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
+ char *fn = NULL;
+ rc = packageBinary(spec, pkg, cookie, cheating, &fn);
+ if (rc == RPMRC_OK) {
rstrcat(&pkglist, fn);
rstrcat(&pkglist, " ");
}
@@ -718,32 +722,28 @@ rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
rpmRC packageSources(rpmSpec spec, char **cookie)
{
- struct cpioSourceArchive_s csabuf;
- CSA_t csa = &csabuf;
+ Package sourcePkg = spec->sourcePackage;
rpmRC rc;
+ uint32_t one = 1;
/* Add some cruft */
- headerPutString(spec->sourceHeader, RPMTAG_RPMVERSION, VERSION);
- headerPutString(spec->sourceHeader, RPMTAG_BUILDHOST, buildHost());
- headerPutUint32(spec->sourceHeader, RPMTAG_BUILDTIME, getBuildTime(), 1);
+ headerPutString(sourcePkg->header, RPMTAG_RPMVERSION, VERSION);
+ headerPutString(sourcePkg->header, RPMTAG_BUILDHOST, spec->buildHost);
+ headerPutUint32(sourcePkg->header, RPMTAG_BUILDTIME, &(spec->buildTime), 1);
+ headerPutUint32(sourcePkg->header, RPMTAG_SOURCEPACKAGE, &one, 1);
/* XXX this should be %_srpmdir */
{ char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
char *pkgcheck = rpmExpand("%{?_build_pkgcheck_srpm} ", fn, NULL);
- memset(csa, 0, sizeof(*csa));
- csa->cpioArchiveSize = 0;
- csa->cpioList = rpmfiLink(spec->sourceCpioList);
-
spec->sourcePkgId = NULL;
- rc = writeRPM(&spec->sourceHeader, &spec->sourcePkgId, fn, csa, cookie);
+ rc = writeRPM(sourcePkg, &spec->sourcePkgId, fn, cookie, spec->buildTime, spec->buildHost);
/* Do check SRPM package if enabled */
if (rc == RPMRC_OK && pkgcheck[0] != ' ') {
rc = checkPackages(pkgcheck);
}
- rpmfiFree(csa->cpioList);
free(pkgcheck);
free(fn);
}