2000-08-28 03:18:25 +08:00
|
|
|
/** \ingroup rpmbuild
|
|
|
|
* \file build/pack.c
|
2000-01-25 04:02:32 +08:00
|
|
|
* Assemble components of an RPM package.
|
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
|
|
|
|
2010-01-05 21:25:31 +08:00
|
|
|
#include <errno.h>
|
|
|
|
|
2008-01-30 19:53:51 +08:00
|
|
|
#include <rpm/rpmlib.h> /* RPMSIGTAG*, rpmReadPackageFile */
|
2008-01-30 23:05:29 +08:00
|
|
|
#include <rpm/rpmts.h>
|
2007-12-08 20:02:32 +08:00
|
|
|
#include <rpm/rpmbuild.h>
|
2008-01-30 23:05:29 +08:00
|
|
|
#include <rpm/rpmfileutil.h>
|
|
|
|
#include <rpm/rpmlog.h>
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2008-01-30 23:05:29 +08:00
|
|
|
#include "rpmio/rpmio_internal.h" /* fdInitDigest, fdFiniDigest */
|
2007-11-23 18:37:54 +08:00
|
|
|
#include "lib/cpio.h"
|
|
|
|
#include "lib/fsm.h"
|
2008-11-27 17:35:56 +08:00
|
|
|
#include "lib/rpmfi_internal.h" /* rpmfiFSM() */
|
2008-12-03 17:39:48 +08:00
|
|
|
#include "lib/rpmte_internal.h" /* rpmfs */
|
2007-11-23 18:37:54 +08:00
|
|
|
#include "lib/signature.h"
|
|
|
|
#include "lib/rpmlead.h"
|
2008-01-30 23:05:29 +08:00
|
|
|
#include "build/buildio.h"
|
|
|
|
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-26 04:26:35 +08:00
|
|
|
* @todo Create transaction set *much* earlier.
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2007-12-07 15:28:39 +08:00
|
|
|
static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa,
|
2001-04-29 09:05:43 +08:00
|
|
|
const char * fmodeMacro)
|
1998-04-08 07:58:01 +08:00
|
|
|
{
|
2002-05-20 02:42:25 +08:00
|
|
|
rpmts ts = rpmtsCreate();
|
|
|
|
rpmfi fi = csa->cpioList;
|
2008-11-26 22:08:04 +08:00
|
|
|
rpmte te = NULL;
|
2008-12-03 17:39:48 +08:00
|
|
|
rpmfs fs = NULL;
|
2007-12-18 16:10:03 +08:00
|
|
|
char *failedFile = NULL;
|
2000-01-25 04:02:32 +08:00
|
|
|
FD_t cfd;
|
2007-12-07 15:28:39 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2008-12-03 17:39:48 +08:00
|
|
|
int xx, i;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2007-12-15 01:52:11 +08:00
|
|
|
{ char *fmode = rpmExpand(fmodeMacro, NULL);
|
2001-08-01 02:13:22 +08:00
|
|
|
if (!(fmode && fmode[0] == 'w'))
|
|
|
|
fmode = xstrdup("w9.gzdio");
|
|
|
|
(void) Fflush(fdo);
|
|
|
|
cfd = Fdopen(fdDup(Fileno(fdo)), fmode);
|
|
|
|
fmode = _free(fmode);
|
|
|
|
}
|
2001-05-04 05:00:18 +08:00
|
|
|
if (cfd == NULL)
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_FAIL;
|
2001-02-02 23:04:44 +08:00
|
|
|
|
2008-11-26 22:08:04 +08:00
|
|
|
/* make up a transaction element for passing to fsm */
|
|
|
|
rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
|
|
|
|
te = rpmtsElement(ts, 0);
|
2008-12-03 17:39:48 +08:00
|
|
|
fs = rpmteGetFileStates(te);
|
|
|
|
|
|
|
|
fi = rpmfiInit(fi, 0);
|
|
|
|
while ((i = rpmfiNext(fi)) >= 0) {
|
|
|
|
if (rpmfiFFlags(fi) & RPMFILE_GHOST)
|
|
|
|
rpmfsSetAction(fs, i, FA_SKIP);
|
|
|
|
else
|
|
|
|
rpmfsSetAction(fs, i, FA_COPYOUT);
|
|
|
|
}
|
2008-11-26 22:08:04 +08:00
|
|
|
|
|
|
|
xx = fsmSetup(rpmfiFSM(fi), FSM_PKGBUILD, ts, te, fi, cfd,
|
2001-02-04 04:07:39 +08:00
|
|
|
&csa->cpioArchiveSize, &failedFile);
|
2007-12-07 15:28:39 +08:00
|
|
|
if (xx)
|
|
|
|
rc = RPMRC_FAIL;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) Fclose(cfd);
|
2008-11-18 12:58:13 +08:00
|
|
|
xx = fsmTeardown(rpmfiFSM(fi));
|
2007-12-07 15:28:39 +08:00
|
|
|
if (rc == RPMRC_OK && xx) rc = RPMRC_FAIL;
|
2001-02-02 23:04:44 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
if (rc) {
|
2001-06-20 14:29:20 +08:00
|
|
|
if (failedFile)
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"),
|
2000-01-25 04:02:32 +08:00
|
|
|
failedFile, cpioStrerror(rc));
|
2001-06-20 14:29:20 +08:00
|
|
|
else
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"),
|
2001-06-20 14:29:20 +08:00
|
|
|
cpioStrerror(rc));
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
1998-11-20 02:10:28 +08:00
|
|
|
}
|
2008-11-26 22:08:04 +08:00
|
|
|
rpmtsEmpty(ts);
|
1998-11-20 02:10:28 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
failedFile = _free(failedFile);
|
2002-05-17 00:55:21 +08:00
|
|
|
ts = rpmtsFree(ts);
|
1999-01-06 07:13:56 +08:00
|
|
|
|
|
|
|
return rc;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2007-12-07 15:28:39 +08:00
|
|
|
static rpmRC cpio_copy(FD_t fdo, CSA_t csa)
|
1998-01-13 05:31:29 +08:00
|
|
|
{
|
2000-01-25 04:02:32 +08:00
|
|
|
char buf[BUFSIZ];
|
|
|
|
size_t nb;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
while((nb = Fread(buf, sizeof(buf[0]), sizeof(buf), csa->cpioFdIn)) > 0) {
|
|
|
|
if (Fwrite(buf, sizeof(buf[0]), nb, fdo) != nb) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("cpio_copy write failed: %s\n"),
|
2000-01-25 04:02:32 +08:00
|
|
|
Fstrerror(fdo));
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_FAIL;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
2000-01-25 04:02:32 +08:00
|
|
|
csa->cpioArchiveSize += nb;
|
1998-11-20 02:10:28 +08:00
|
|
|
}
|
2000-01-25 04:02:32 +08:00
|
|
|
if (Ferror(csa->cpioFdIn)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("cpio_copy read failed: %s\n"),
|
2000-01-25 04:02:32 +08:00
|
|
|
Fstrerror(csa->cpioFdIn));
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_FAIL;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_OK;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2007-09-21 20:23:02 +08:00
|
|
|
static StringBuf addFileToTagAux(rpmSpec spec,
|
2007-09-12 05:03:27 +08:00
|
|
|
const char * file, StringBuf sb)
|
1998-10-12 04:58:58 +08:00
|
|
|
{
|
2000-01-25 04:02:32 +08:00
|
|
|
char buf[BUFSIZ];
|
2008-03-25 01:01:12 +08:00
|
|
|
char * fn;
|
2001-05-01 06:32:22 +08:00
|
|
|
FILE * f;
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2007-04-16 20:06:24 +08:00
|
|
|
fn = rpmGetPath("%{_builddir}/%{?buildsubdir:%{buildsubdir}/}", file, NULL);
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2008-03-25 01:00:48 +08:00
|
|
|
f = fopen(fn, "r");
|
|
|
|
if (f == NULL || ferror(f)) {
|
2001-05-06 03:28:32 +08:00
|
|
|
sb = freeStringBuf(sb);
|
2008-03-25 01:01:12 +08:00
|
|
|
goto exit;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
while (fgets(buf, sizeof(buf), f)) {
|
2000-01-25 04:02:32 +08:00
|
|
|
if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
|
2008-03-25 01:01:12 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf);
|
2001-05-06 03:28:32 +08:00
|
|
|
sb = freeStringBuf(sb);
|
2001-05-01 06:32:22 +08:00
|
|
|
break;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
appendStringBuf(sb, buf);
|
1998-10-12 04:58:58 +08:00
|
|
|
}
|
2008-03-25 01:00:48 +08:00
|
|
|
(void) fclose(f);
|
1999-10-28 07:18:10 +08:00
|
|
|
|
2008-03-25 01:01:12 +08:00
|
|
|
exit:
|
|
|
|
free(fn);
|
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
return sb;
|
|
|
|
}
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2008-02-05 23:42:19 +08:00
|
|
|
static int addFileToTag(rpmSpec spec, const char * file, Header h, rpmTag tag)
|
2000-01-25 04:02:32 +08:00
|
|
|
{
|
2000-12-03 05:53:44 +08:00
|
|
|
StringBuf sb = newStringBuf();
|
2009-09-02 17:39:06 +08:00
|
|
|
const char *s = headerGetString(h, tag);
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2009-09-02 17:39:06 +08:00
|
|
|
if (s) {
|
2000-01-25 04:02:32 +08:00
|
|
|
appendLineStringBuf(sb, s);
|
2008-06-17 14:07:37 +08:00
|
|
|
(void) headerDel(h, tag);
|
1998-10-12 04:58:58 +08:00
|
|
|
}
|
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
if ((sb = addFileToTagAux(spec, file, sb)) == NULL)
|
2000-01-25 04:02:32 +08:00
|
|
|
return 1;
|
|
|
|
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, tag, getStringBuf(sb));
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2001-05-06 03:28:32 +08:00
|
|
|
sb = freeStringBuf(sb);
|
2000-01-25 04:02:32 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2008-02-05 23:42:19 +08:00
|
|
|
static int addFileToArrayTag(rpmSpec spec, const char *file, Header h, rpmTag tag)
|
2000-01-25 04:02:32 +08:00
|
|
|
{
|
2000-12-03 05:53:44 +08:00
|
|
|
StringBuf sb = newStringBuf();
|
2008-06-17 21:07:55 +08:00
|
|
|
const char *s;
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
if ((sb = addFileToTagAux(spec, file, sb)) == NULL)
|
2000-01-25 04:02:32 +08:00
|
|
|
return 1;
|
1998-10-12 04:58:58 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
s = getStringBuf(sb);
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, tag, s);
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2001-05-06 03:28:32 +08:00
|
|
|
sb = freeStringBuf(sb);
|
1998-10-12 04:58:58 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2007-12-07 16:43:53 +08:00
|
|
|
static rpmRC processScriptFiles(rpmSpec spec, Package pkg)
|
1996-02-19 10:24:47 +08:00
|
|
|
{
|
2000-01-25 04:02:32 +08:00
|
|
|
struct TriggerFileEntry *p;
|
2010-03-11 18:06:49 +08:00
|
|
|
int addflags = 0;
|
2000-01-25 04:02:32 +08:00
|
|
|
|
|
|
|
if (pkg->preInFile) {
|
|
|
|
if (addFileToTag(spec, pkg->preInFile, pkg->header, RPMTAG_PREIN)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open PreIn file: %s\n"), pkg->preInFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pkg->preUnFile) {
|
|
|
|
if (addFileToTag(spec, pkg->preUnFile, pkg->header, RPMTAG_PREUN)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open PreUn file: %s\n"), pkg->preUnFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
2004-03-17 05:58:25 +08:00
|
|
|
if (pkg->preTransFile) {
|
|
|
|
if (addFileToTag(spec, pkg->preTransFile, pkg->header, RPMTAG_PRETRANS)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2008-09-22 18:10:36 +08:00
|
|
|
_("Could not open PreTrans file: %s\n"), pkg->preTransFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2004-03-17 05:58:25 +08:00
|
|
|
}
|
|
|
|
}
|
2000-01-25 04:02:32 +08:00
|
|
|
if (pkg->postInFile) {
|
|
|
|
if (addFileToTag(spec, pkg->postInFile, pkg->header, RPMTAG_POSTIN)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open PostIn file: %s\n"), pkg->postInFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pkg->postUnFile) {
|
|
|
|
if (addFileToTag(spec, pkg->postUnFile, pkg->header, RPMTAG_POSTUN)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open PostUn file: %s\n"), pkg->postUnFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
2004-03-17 05:58:25 +08:00
|
|
|
if (pkg->postTransFile) {
|
|
|
|
if (addFileToTag(spec, pkg->postTransFile, pkg->header, RPMTAG_POSTTRANS)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2008-09-22 18:10:36 +08:00
|
|
|
_("Could not open PostTrans file: %s\n"), pkg->postTransFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2004-03-17 05:58:25 +08:00
|
|
|
}
|
|
|
|
}
|
2000-01-25 04:02:32 +08:00
|
|
|
if (pkg->verifyFile) {
|
|
|
|
if (addFileToTag(spec, pkg->verifyFile, pkg->header,
|
|
|
|
RPMTAG_VERIFYSCRIPT)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open VerifyScript file: %s\n"), pkg->verifyFile);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-11 18:06:49 +08:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
for (p = pkg->triggerFiles; p != NULL; p = p->next) {
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(pkg->header, RPMTAG_TRIGGERSCRIPTPROG, p->prog);
|
2010-03-11 18:06:49 +08:00
|
|
|
if (addflags) {
|
|
|
|
headerPutUint32(pkg->header, RPMTAG_TRIGGERSCRIPTFLAGS,
|
|
|
|
&p->flags, 1);
|
|
|
|
}
|
2008-06-17 17:10:01 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
if (p->script) {
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(pkg->header, RPMTAG_TRIGGERSCRIPTS, p->script);
|
2000-01-25 04:02:32 +08:00
|
|
|
} else if (p->fileName) {
|
|
|
|
if (addFileToArrayTag(spec, p->fileName, pkg->header,
|
|
|
|
RPMTAG_TRIGGERSCRIPTS)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open Trigger script file: %s\n"),
|
2000-01-25 04:02:32 +08:00
|
|
|
p->fileName);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* This is dumb. When the header supports NULL string */
|
|
|
|
/* this will go away. */
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(pkg->header, RPMTAG_TRIGGERSCRIPTS, "");
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_OK;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
rpmRC readRPM(const char *fileName, rpmSpec *specp,
|
2001-06-12 12:10:21 +08:00
|
|
|
Header *sigs, CSA_t csa)
|
2000-01-25 04:02:32 +08:00
|
|
|
{
|
|
|
|
FD_t fdi;
|
2007-09-21 20:23:02 +08:00
|
|
|
rpmSpec spec;
|
2001-02-13 03:02:15 +08:00
|
|
|
rpmRC rc;
|
2001-06-12 12:10:21 +08:00
|
|
|
|
|
|
|
fdi = (fileName != NULL)
|
|
|
|
? Fopen(fileName, "r.ufdio")
|
|
|
|
: fdDup(STDIN_FILENO);
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
if (fdi == NULL || Ferror(fdi)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("readRPM: open %s: %s\n"),
|
2001-05-04 05:00:18 +08:00
|
|
|
(fileName ? fileName : "<stdin>"),
|
2000-01-25 04:02:32 +08:00
|
|
|
Fstrerror(fdi));
|
2001-05-04 05:00:18 +08:00
|
|
|
if (fdi) (void) Fclose(fdi);
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
|
2001-06-12 12:10:21 +08:00
|
|
|
/* XXX FIXME: EPIPE on <stdin> */
|
|
|
|
if (Fseek(fdi, 0, SEEK_SET) == -1) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("%s: Fseek failed: %s\n"),
|
2001-06-12 12:10:21 +08:00
|
|
|
(fileName ? fileName : "<stdin>"), Fstrerror(fdi));
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_FAIL;
|
2001-06-12 12:10:21 +08:00
|
|
|
}
|
2000-01-25 04:02:32 +08:00
|
|
|
|
|
|
|
/* Reallocate build data structures */
|
|
|
|
spec = newSpec();
|
|
|
|
spec->packages = newPackage(spec);
|
|
|
|
|
|
|
|
/* XXX the header just allocated will be allocated again */
|
2002-07-14 03:08:51 +08:00
|
|
|
spec->packages->header = headerFree(spec->packages->header);
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2001-10-26 12:16:19 +08:00
|
|
|
/* Read the rpm lead, signatures, and header */
|
2002-05-20 02:42:25 +08:00
|
|
|
{ rpmts ts = rpmtsCreate();
|
2001-10-26 12:16:19 +08:00
|
|
|
|
|
|
|
/* XXX W2DO? pass fileName? */
|
2001-10-28 04:09:20 +08:00
|
|
|
rc = rpmReadPackageFile(ts, fdi, "readRPM",
|
2001-10-26 12:16:19 +08:00
|
|
|
&spec->packages->header);
|
|
|
|
|
2002-05-17 00:55:21 +08:00
|
|
|
ts = rpmtsFree(ts);
|
2001-10-26 12:16:19 +08:00
|
|
|
|
|
|
|
if (sigs) *sigs = NULL; /* XXX HACK */
|
|
|
|
}
|
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
switch (rc) {
|
2002-08-24 05:01:59 +08:00
|
|
|
case RPMRC_OK:
|
|
|
|
case RPMRC_NOKEY:
|
|
|
|
case RPMRC_NOTTRUSTED:
|
|
|
|
break;
|
2002-05-05 04:13:14 +08:00
|
|
|
case RPMRC_NOTFOUND:
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("readRPM: %s is not an RPM package\n"),
|
2001-05-04 05:00:18 +08:00
|
|
|
(fileName ? fileName : "<stdin>"));
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2001-02-13 03:02:15 +08:00
|
|
|
case RPMRC_FAIL:
|
2000-01-25 04:02:32 +08:00
|
|
|
default:
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("readRPM: reading header from %s\n"),
|
2001-05-04 05:00:18 +08:00
|
|
|
(fileName ? fileName : "<stdin>"));
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (specp)
|
|
|
|
*specp = spec;
|
2000-11-07 21:16:43 +08:00
|
|
|
else
|
2001-05-07 03:17:14 +08:00
|
|
|
spec = freeSpec(spec);
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
if (csa != NULL)
|
2000-01-25 04:02:32 +08:00
|
|
|
csa->cpioFdIn = fdi;
|
2000-11-07 21:16:43 +08:00
|
|
|
else
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) Fclose(fdi);
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
return RPMRC_OK;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
|
2008-03-23 20:48:49 +08:00
|
|
|
CSA_t csa, char *passPhrase, char **cookie)
|
2000-01-25 04:02:32 +08:00
|
|
|
{
|
2000-11-07 21:16:43 +08:00
|
|
|
FD_t fd = NULL;
|
|
|
|
FD_t ifd = NULL;
|
2008-06-26 15:50:01 +08:00
|
|
|
ssize_t count;
|
|
|
|
rpmSigTag sigtag;
|
2007-12-16 22:25:09 +08:00
|
|
|
char * sigtarget = NULL;;
|
2007-12-15 01:52:11 +08:00
|
|
|
char * rpmio_flags = NULL;
|
2007-12-17 03:24:44 +08:00
|
|
|
char * SHA1 = NULL;
|
2000-06-23 09:19:45 +08:00
|
|
|
char *s;
|
2008-03-23 20:48:49 +08:00
|
|
|
char *buf = NULL;
|
2001-06-12 12:10:21 +08:00
|
|
|
Header h;
|
2000-12-03 05:53:44 +08:00
|
|
|
Header sig = NULL;
|
2008-04-10 16:25:59 +08:00
|
|
|
int xx;
|
2007-12-07 15:28:39 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2008-06-17 17:10:01 +08:00
|
|
|
struct rpmtd_s td;
|
2008-06-26 21:34:32 +08:00
|
|
|
rpmSigTag sizetag;
|
|
|
|
rpmTag payloadtag;
|
1996-02-19 10:24:47 +08:00
|
|
|
|
2001-06-12 12:10:21 +08:00
|
|
|
/* Transfer header reference form *hdrp to h. */
|
2002-07-14 03:08:51 +08:00
|
|
|
h = headerLink(*hdrp);
|
|
|
|
*hdrp = headerFree(*hdrp);
|
2001-06-12 12:10:21 +08:00
|
|
|
|
2002-12-24 10:41:45 +08:00
|
|
|
if (pkgidp)
|
|
|
|
*pkgidp = NULL;
|
2002-12-22 04:37:37 +08:00
|
|
|
|
2000-06-23 09:19:45 +08:00
|
|
|
/* Save payload information */
|
2008-04-10 16:25:59 +08:00
|
|
|
if (headerIsSource(h))
|
2001-12-07 02:34:49 +08:00
|
|
|
rpmio_flags = rpmExpand("%{?_source_payload}", NULL);
|
2007-12-02 03:06:00 +08:00
|
|
|
else
|
2001-12-07 02:34:49 +08:00
|
|
|
rpmio_flags = rpmExpand("%{?_binary_payload}", NULL);
|
2007-12-02 03:06:00 +08:00
|
|
|
|
2000-06-23 09:19:45 +08:00
|
|
|
if (!(rpmio_flags && *rpmio_flags)) {
|
2001-04-29 09:05:43 +08:00
|
|
|
rpmio_flags = _free(rpmio_flags);
|
2000-06-23 09:19:45 +08:00
|
|
|
rpmio_flags = xstrdup("w9.gzdio");
|
|
|
|
}
|
|
|
|
s = strchr(rpmio_flags, '.');
|
|
|
|
if (s) {
|
2008-04-15 14:16:05 +08:00
|
|
|
const char *compr = NULL;
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, RPMTAG_PAYLOADFORMAT, "cpio");
|
2008-06-17 17:10:01 +08:00
|
|
|
|
2009-08-31 16:08:05 +08:00
|
|
|
if (rstreq(s+1, "gzdio")) {
|
2008-04-15 14:16:05 +08:00
|
|
|
compr = "gzip";
|
2009-04-13 18:58:39 +08:00
|
|
|
#if HAVE_BZLIB_H
|
2009-08-31 16:08:05 +08:00
|
|
|
} else if (rstreq(s+1, "bzdio")) {
|
2008-04-15 14:16:05 +08:00
|
|
|
compr = "bzip2";
|
2000-06-23 09:19:45 +08:00
|
|
|
/* Add prereq on rpm version that understands bzip2 payloads */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) rpmlibNeedsFeature(h, "PayloadIsBzip2", "3.0.5-1");
|
2009-04-13 18:58:39 +08:00
|
|
|
#endif
|
|
|
|
#if HAVE_LZMA_H
|
2009-08-31 16:08:05 +08:00
|
|
|
} else if (rstreq(s+1, "xzdio")) {
|
2009-03-18 15:42:23 +08:00
|
|
|
compr = "xz";
|
|
|
|
(void) rpmlibNeedsFeature(h, "PayloadIsXz", "5.2-1");
|
2009-08-31 16:08:05 +08:00
|
|
|
} else if (rstreq(s+1, "lzdio")) {
|
2009-03-18 17:24:52 +08:00
|
|
|
compr = "lzma";
|
|
|
|
(void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
|
2009-04-13 18:58:39 +08:00
|
|
|
#endif
|
2008-04-15 14:16:05 +08:00
|
|
|
} else {
|
|
|
|
rpmlog(RPMLOG_ERR, _("Unknown payload compression: %s\n"),
|
|
|
|
rpmio_flags);
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
goto exit;
|
2000-06-23 09:19:45 +08:00
|
|
|
}
|
2008-04-15 14:16:05 +08:00
|
|
|
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, RPMTAG_PAYLOADCOMPRESSOR, compr);
|
2008-03-23 20:48:49 +08:00
|
|
|
buf = xstrdup(rpmio_flags);
|
2000-07-10 07:10:25 +08:00
|
|
|
buf[s - rpmio_flags] = '\0';
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, RPMTAG_PAYLOADFLAGS, buf+1);
|
2008-03-23 20:48:49 +08:00
|
|
|
free(buf);
|
2000-06-23 09:19:45 +08:00
|
|
|
}
|
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
/* Create and add the cookie */
|
|
|
|
if (cookie) {
|
2008-03-23 20:48:49 +08:00
|
|
|
rasprintf(cookie, "%s %d", buildHost(), (int) (*getBuildTime()));
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, RPMTAG_COOKIE, *cookie);
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
|
2000-11-09 01:07:01 +08:00
|
|
|
/* Reallocate the header into one contiguous region. */
|
2001-06-12 12:10:21 +08:00
|
|
|
h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
|
2001-05-04 05:00:18 +08:00
|
|
|
if (h == NULL) { /* XXX can't happen */
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to create immutable header region.\n"));
|
2001-05-04 05:00:18 +08:00
|
|
|
goto exit;
|
|
|
|
}
|
2001-06-12 12:10:21 +08:00
|
|
|
/* Re-reference reallocated header. */
|
2002-07-14 03:08:51 +08:00
|
|
|
*hdrp = headerLink(h);
|
2000-11-09 01:07:01 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Write the header+archive into a temp file so that the size of
|
|
|
|
* archive (after compression) can be added to the header.
|
|
|
|
*/
|
2008-05-03 17:34:19 +08:00
|
|
|
fd = rpmMkTempFile(NULL, &sigtarget);
|
2008-04-11 14:05:05 +08:00
|
|
|
if (fd == NULL || Ferror(fd)) {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
|
2001-05-04 05:00:18 +08:00
|
|
|
goto exit;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1999-11-15 03:15:18 +08:00
|
|
|
|
2002-03-04 07:09:49 +08:00
|
|
|
fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
|
1999-08-24 23:18:43 +08:00
|
|
|
if (headerWrite(fd, h, HEADER_MAGIC_YES)) {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to write temp header\n"));
|
1999-08-24 23:18:43 +08:00
|
|
|
} else { /* Write the archive and get the size */
|
2002-03-07 07:17:31 +08:00
|
|
|
(void) Fflush(fd);
|
2002-07-22 06:06:19 +08:00
|
|
|
fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&SHA1, NULL, 1);
|
1999-08-24 23:18:43 +08:00
|
|
|
if (csa->cpioList != NULL) {
|
2001-01-24 07:03:28 +08:00
|
|
|
rc = cpio_doio(fd, h, csa, rpmio_flags);
|
1999-10-31 00:43:29 +08:00
|
|
|
} else if (Fileno(csa->cpioFdIn) >= 0) {
|
1999-08-24 23:18:43 +08:00
|
|
|
rc = cpio_copy(fd, csa);
|
|
|
|
} else {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Bad CSA data\n"));
|
1999-08-24 23:18:43 +08:00
|
|
|
}
|
1998-08-09 06:27:08 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
rpmio_flags = _free(rpmio_flags);
|
1999-11-15 03:15:18 +08:00
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
if (rc != RPMRC_OK)
|
2000-11-07 21:16:43 +08:00
|
|
|
goto exit;
|
1996-02-19 10:24:47 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) Fclose(fd);
|
2000-11-07 21:16:43 +08:00
|
|
|
fd = NULL;
|
2007-12-03 22:33:18 +08:00
|
|
|
(void) unlink(fileName);
|
1999-08-24 23:18:43 +08:00
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
/* Generate the signature */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) fflush(stdout);
|
2000-12-03 05:53:44 +08:00
|
|
|
sig = rpmNewSignature();
|
2008-06-26 21:34:32 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
if (csa->cpioArchiveSize < UINT32_MAX) {
|
|
|
|
sizetag = RPMSIGTAG_SIZE;
|
|
|
|
payloadtag = RPMSIGTAG_PAYLOADSIZE;
|
|
|
|
} else {
|
|
|
|
sizetag = RPMSIGTAG_LONGSIZE;
|
|
|
|
payloadtag = RPMSIGTAG_LONGARCHIVESIZE;
|
|
|
|
}
|
|
|
|
(void) rpmAddSignature(sig, sigtarget, sizetag, passPhrase);
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
|
2002-03-04 07:09:49 +08:00
|
|
|
|
2002-04-08 03:52:42 +08:00
|
|
|
if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
|
2007-10-09 19:50:42 +08:00
|
|
|
rpmlog(RPMLOG_NOTICE, _("Generating signature: %d\n"), sigtag);
|
2002-04-08 03:52:42 +08:00
|
|
|
(void) rpmAddSignature(sig, sigtarget, sigtag, passPhrase);
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
2001-06-12 12:10:21 +08:00
|
|
|
|
2002-07-22 06:06:19 +08:00
|
|
|
if (SHA1) {
|
2008-06-17 17:10:01 +08:00
|
|
|
/* XXX can't use rpmtdFromFoo() on RPMSIGTAG_* items */
|
2008-06-17 19:54:44 +08:00
|
|
|
rpmtdReset(&td);
|
|
|
|
td.tag = RPMSIGTAG_SHA1;
|
|
|
|
td.type = RPM_STRING_TYPE;
|
|
|
|
td.data = SHA1;
|
|
|
|
td.count = 1;
|
|
|
|
headerPut(sig, &td, HEADERPUT_DEFAULT);
|
2002-07-22 06:06:19 +08:00
|
|
|
SHA1 = _free(SHA1);
|
2001-06-12 12:10:21 +08:00
|
|
|
}
|
2000-12-03 05:53:44 +08:00
|
|
|
|
2008-06-26 21:34:32 +08:00
|
|
|
{
|
|
|
|
/* XXX can't use headerPutType() on legacy RPMSIGTAG_* items */
|
2008-06-17 19:54:44 +08:00
|
|
|
rpmtdReset(&td);
|
2008-06-26 21:34:32 +08:00
|
|
|
td.tag = payloadtag;
|
2008-06-17 19:54:44 +08:00
|
|
|
td.count = 1;
|
2008-06-26 21:34:32 +08:00
|
|
|
if (payloadtag == RPMSIGTAG_PAYLOADSIZE) {
|
2008-08-13 14:43:41 +08:00
|
|
|
rpm_off_t asize = csa->cpioArchiveSize;
|
2008-06-26 21:34:32 +08:00
|
|
|
td.type = RPM_INT32_TYPE;
|
2008-08-13 14:43:41 +08:00
|
|
|
td.data = &asize;
|
|
|
|
headerPut(sig, &td, HEADERPUT_DEFAULT);
|
2008-06-26 21:34:32 +08:00
|
|
|
} else {
|
2008-08-13 14:43:41 +08:00
|
|
|
rpm_loff_t asize = csa->cpioArchiveSize;
|
2008-06-26 21:34:32 +08:00
|
|
|
td.type = RPM_INT64_TYPE;
|
2008-08-13 14:43:41 +08:00
|
|
|
td.data = &asize;
|
|
|
|
headerPut(sig, &td, HEADERPUT_DEFAULT);
|
2008-06-26 21:34:32 +08:00
|
|
|
}
|
2002-03-04 07:09:49 +08:00
|
|
|
}
|
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
/* Reallocate the signature into one contiguous region. */
|
|
|
|
sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
|
2001-05-04 05:00:18 +08:00
|
|
|
if (sig == NULL) { /* XXX can't happen */
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
|
2001-05-04 05:00:18 +08:00
|
|
|
goto exit;
|
|
|
|
}
|
2000-12-03 05:53:44 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
/* Open the output file */
|
1999-11-13 01:20:49 +08:00
|
|
|
fd = Fopen(fileName, "w.ufdio");
|
|
|
|
if (fd == NULL || Ferror(fd)) {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Could not open %s: %s\n"),
|
1999-11-13 01:20:49 +08:00
|
|
|
fileName, Fstrerror(fd));
|
2000-11-07 21:16:43 +08:00
|
|
|
goto exit;
|
1996-03-30 04:06:02 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
/* Write the lead section into the package. */
|
2007-12-02 00:31:09 +08:00
|
|
|
{
|
|
|
|
rpmlead lead = rpmLeadFromHeader(h);
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = rpmLeadWrite(fd, lead);
|
2007-12-02 00:31:09 +08:00
|
|
|
lead = rpmLeadFree(lead);
|
|
|
|
if (rc != RPMRC_OK) {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
|
1999-11-11 06:09:49 +08:00
|
|
|
Fstrerror(fd));
|
2000-12-03 05:53:44 +08:00
|
|
|
goto exit;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
}
|
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
/* Write the signature section into the package. */
|
2007-12-07 15:28:39 +08:00
|
|
|
if (rpmWriteSignature(fd, sig)) {
|
|
|
|
rc = RPMRC_FAIL;
|
2000-11-07 21:16:43 +08:00
|
|
|
goto exit;
|
2007-12-07 15:28:39 +08:00
|
|
|
}
|
2000-12-03 05:53:44 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/* Append the header and archive */
|
1999-11-13 01:20:49 +08:00
|
|
|
ifd = Fopen(sigtarget, "r.ufdio");
|
|
|
|
if (ifd == NULL || Ferror(ifd)) {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to open sigtarget %s: %s\n"),
|
1999-11-13 01:20:49 +08:00
|
|
|
sigtarget, Fstrerror(ifd));
|
2000-11-07 21:16:43 +08:00
|
|
|
goto exit;
|
1999-11-13 01:20:49 +08:00
|
|
|
}
|
2000-12-03 05:53:44 +08:00
|
|
|
|
|
|
|
/* Add signatures to header, and write header into the package. */
|
2002-03-04 07:09:49 +08:00
|
|
|
/* XXX header+payload digests/signatures might be checked again here. */
|
2000-12-03 05:53:44 +08:00
|
|
|
{ Header nh = headerRead(ifd, HEADER_MAGIC_YES);
|
|
|
|
|
|
|
|
if (nh == NULL) {
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to read header from %s: %s\n"),
|
2000-12-03 05:53:44 +08:00
|
|
|
sigtarget, Fstrerror(ifd));
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef NOTYET
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerMergeLegacySigs(nh, sig);
|
2000-12-03 05:53:44 +08:00
|
|
|
#endif
|
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
xx = headerWrite(fd, nh, HEADER_MAGIC_YES);
|
2002-07-14 03:08:51 +08:00
|
|
|
nh = headerFree(nh);
|
2000-12-03 05:53:44 +08:00
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
if (xx) {
|
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to write header to %s: %s\n"),
|
2000-12-03 05:53:44 +08:00
|
|
|
fileName, Fstrerror(fd));
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the payload into the package. */
|
2008-03-23 20:48:49 +08:00
|
|
|
buf = xmalloc(BUFSIZ);
|
|
|
|
while ((count = Fread(buf, 1, BUFSIZ, ifd)) > 0) {
|
1998-01-13 05:31:29 +08:00
|
|
|
if (count == -1) {
|
2008-03-23 20:48:49 +08:00
|
|
|
free(buf);
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to read payload from %s: %s\n"),
|
1999-11-13 01:20:49 +08:00
|
|
|
sigtarget, Fstrerror(ifd));
|
2000-11-07 21:16:43 +08:00
|
|
|
goto exit;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
2001-04-18 02:30:23 +08:00
|
|
|
if (Fwrite(buf, sizeof(buf[0]), count, fd) != count) {
|
2008-03-23 20:48:49 +08:00
|
|
|
free(buf);
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Unable to write payload to %s: %s\n"),
|
1999-11-13 01:20:49 +08:00
|
|
|
fileName, Fstrerror(fd));
|
2000-11-07 21:16:43 +08:00
|
|
|
goto exit;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
}
|
2008-03-23 20:48:49 +08:00
|
|
|
free(buf);
|
2007-12-07 15:28:39 +08:00
|
|
|
rc = RPMRC_OK;
|
1996-06-28 01:21:31 +08:00
|
|
|
|
2000-11-07 21:16:43 +08:00
|
|
|
exit:
|
2002-07-22 06:06:19 +08:00
|
|
|
SHA1 = _free(SHA1);
|
2002-07-14 03:08:51 +08:00
|
|
|
h = headerFree(h);
|
2002-12-24 10:41:45 +08:00
|
|
|
|
|
|
|
/* XXX Fish the pkgid out of the signature header. */
|
|
|
|
if (sig != NULL && pkgidp != NULL) {
|
2008-05-26 20:25:11 +08:00
|
|
|
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;
|
|
|
|
}
|
2002-12-24 10:41:45 +08:00
|
|
|
}
|
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
sig = rpmFreeSignature(sig);
|
2000-11-07 21:16:43 +08:00
|
|
|
if (ifd) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) Fclose(ifd);
|
2000-11-07 21:16:43 +08:00
|
|
|
ifd = NULL;
|
|
|
|
}
|
|
|
|
if (fd) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) Fclose(fd);
|
2000-11-07 21:16:43 +08:00
|
|
|
fd = NULL;
|
|
|
|
}
|
|
|
|
if (sigtarget) {
|
2007-12-03 22:33:18 +08:00
|
|
|
(void) unlink(sigtarget);
|
2001-04-29 09:05:43 +08:00
|
|
|
sigtarget = _free(sigtarget);
|
2000-11-07 21:16:43 +08:00
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
|
2007-12-07 15:28:39 +08:00
|
|
|
if (rc == RPMRC_OK)
|
2007-10-09 19:50:42 +08:00
|
|
|
rpmlog(RPMLOG_NOTICE, _("Wrote: %s\n"), fileName);
|
2000-11-07 21:16:43 +08:00
|
|
|
else
|
2007-12-03 22:33:18 +08:00
|
|
|
(void) unlink(fileName);
|
2000-11-07 21:16:43 +08:00
|
|
|
|
|
|
|
return rc;
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
|
|
|
|
2008-03-07 02:47:17 +08:00
|
|
|
static const rpmTag copyTags[] = {
|
2000-01-25 04:02:32 +08:00
|
|
|
RPMTAG_CHANGELOGTIME,
|
|
|
|
RPMTAG_CHANGELOGNAME,
|
|
|
|
RPMTAG_CHANGELOGTEXT,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
2008-04-10 20:52:36 +08:00
|
|
|
/*
|
|
|
|
* Add extra provides to package.
|
|
|
|
*/
|
|
|
|
static void addPackageProvides(Header h)
|
|
|
|
{
|
2009-09-02 16:55:42 +08:00
|
|
|
const char *arch, *name;
|
2008-04-11 00:36:03 +08:00
|
|
|
char *evr, *isaprov;
|
2008-04-10 20:52:36 +08:00
|
|
|
rpmsenseFlags pflags = RPMSENSE_EQUAL;
|
|
|
|
|
|
|
|
/* <name> = <evr> provide */
|
2009-09-02 16:55:42 +08:00
|
|
|
name = headerGetString(h, RPMTAG_NAME);
|
|
|
|
arch = headerGetString(h, RPMTAG_ARCH);
|
|
|
|
evr = headerGetAsString(h, RPMTAG_EVR);
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, RPMTAG_PROVIDENAME, name);
|
|
|
|
headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
|
|
|
|
headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);
|
2008-04-11 00:36:03 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* <name>(<isa>) = <evr> provide
|
|
|
|
* FIXME: noarch needs special casing for now as BuildArch: noarch doesn't
|
|
|
|
* cause reading in the noarch macros :-/
|
|
|
|
*/
|
|
|
|
isaprov = rpmExpand(name, "%{?_isa}", NULL);
|
2009-08-31 16:08:05 +08:00
|
|
|
if (!rstreq(arch, "noarch") && !rstreq(name, isaprov)) {
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(h, RPMTAG_PROVIDENAME, isaprov);
|
|
|
|
headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
|
|
|
|
headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);
|
2008-04-11 00:36:03 +08:00
|
|
|
}
|
|
|
|
free(isaprov);
|
2008-04-10 20:52:36 +08:00
|
|
|
free(evr);
|
|
|
|
}
|
|
|
|
|
2008-11-10 22:52:29 +08:00
|
|
|
rpmRC checkPackages(char *pkgcheck)
|
|
|
|
{
|
|
|
|
int fail = rpmExpandNumeric("%{?_nonzero_exit_pkgcheck_terminate_build}");
|
|
|
|
int xx;
|
|
|
|
|
|
|
|
rpmlog(RPMLOG_NOTICE, _("Executing \"%s\":\n"), pkgcheck);
|
|
|
|
xx = system(pkgcheck);
|
|
|
|
if (WEXITSTATUS(xx) == -1 || WEXITSTATUS(xx) == 127) {
|
|
|
|
rpmlog(RPMLOG_ERR, _("Execution of \"%s\" failed.\n"), pkgcheck);
|
|
|
|
if (fail) return 127;
|
|
|
|
}
|
|
|
|
if (WEXITSTATUS(xx) != 0) {
|
|
|
|
rpmlog(RPMLOG_ERR, _("Package check \"%s\" failed.\n"), pkgcheck);
|
|
|
|
if (fail) return RPMRC_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RPMRC_OK;
|
|
|
|
}
|
|
|
|
|
2007-12-07 16:43:53 +08:00
|
|
|
rpmRC packageBinaries(rpmSpec spec)
|
1999-09-18 07:18:24 +08:00
|
|
|
{
|
2001-05-04 05:00:18 +08:00
|
|
|
struct cpioSourceArchive_s csabuf;
|
|
|
|
CSA_t csa = &csabuf;
|
2007-12-07 16:43:53 +08:00
|
|
|
rpmRC rc;
|
2000-01-25 04:02:32 +08:00
|
|
|
const char *errorString;
|
|
|
|
Package pkg;
|
2008-11-10 22:52:29 +08:00
|
|
|
char *pkglist = NULL;
|
1998-12-06 07:22:41 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
2007-12-15 16:39:15 +08:00
|
|
|
char *fn;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
if (pkg->fileList == NULL)
|
|
|
|
continue;
|
1998-07-25 23:33:15 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
if ((rc = processScriptFiles(spec, pkg)))
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (spec->cookie) {
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(pkg->header, RPMTAG_COOKIE, spec->cookie);
|
1998-07-25 23:33:15 +08:00
|
|
|
}
|
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
/* Copy changelog from src rpm */
|
|
|
|
headerCopyTags(spec->packages->header, pkg->header, copyTags);
|
|
|
|
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(pkg->header, RPMTAG_RPMVERSION, VERSION);
|
|
|
|
headerPutString(pkg->header, RPMTAG_BUILDHOST, buildHost());
|
|
|
|
headerPutUint32(pkg->header, RPMTAG_BUILDTIME, getBuildTime(), 1);
|
1999-11-13 01:20:49 +08:00
|
|
|
|
2008-04-10 20:52:36 +08:00
|
|
|
addPackageProvides(pkg->header);
|
2000-04-14 01:59:10 +08:00
|
|
|
|
2007-12-15 01:52:11 +08:00
|
|
|
{ char * optflags = rpmExpand("%{optflags}", NULL);
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(pkg->header, RPMTAG_OPTFLAGS, optflags);
|
2001-04-29 09:05:43 +08:00
|
|
|
optflags = _free(optflags);
|
2000-06-21 05:45:50 +08:00
|
|
|
}
|
|
|
|
|
2002-12-22 04:37:37 +08:00
|
|
|
if (spec->sourcePkgId != NULL) {
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutBin(pkg->header, RPMTAG_SOURCEPKGID, spec->sourcePkgId,16);
|
2002-12-22 04:37:37 +08:00
|
|
|
}
|
2000-01-25 04:02:32 +08:00
|
|
|
|
2007-12-15 16:39:15 +08:00
|
|
|
{ char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
|
2000-01-25 04:02:32 +08:00
|
|
|
char *binRpm, *binDir;
|
2008-05-12 21:20:13 +08:00
|
|
|
binRpm = headerFormat(pkg->header, binFormat, &errorString);
|
2001-04-29 09:05:43 +08:00
|
|
|
binFormat = _free(binFormat);
|
2000-01-25 04:02:32 +08:00
|
|
|
if (binRpm == NULL) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("Could not generate output "
|
2009-09-02 16:55:42 +08:00
|
|
|
"filename for package %s: %s\n"),
|
|
|
|
headerGetString(pkg->header, RPMTAG_NAME), errorString);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
fn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
|
|
|
|
if ((binDir = strchr(binRpm, '/')) != NULL) {
|
|
|
|
struct stat st;
|
2007-12-15 16:39:15 +08:00
|
|
|
char *dn;
|
2000-01-25 04:02:32 +08:00
|
|
|
*binDir = '\0';
|
|
|
|
dn = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
|
2007-12-03 22:33:18 +08:00
|
|
|
if (stat(dn, &st) < 0) {
|
2000-01-25 04:02:32 +08:00
|
|
|
switch(errno) {
|
|
|
|
case ENOENT:
|
2007-12-03 22:33:18 +08:00
|
|
|
if (mkdir(dn, 0755) == 0)
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
2000-01-25 04:02:32 +08:00
|
|
|
default:
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,_("cannot create %s: %s\n"),
|
2000-01-25 04:02:32 +08:00
|
|
|
dn, strerror(errno));
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
dn = _free(dn);
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
binRpm = _free(binRpm);
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
1998-03-21 06:38:00 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
memset(csa, 0, sizeof(*csa));
|
|
|
|
csa->cpioArchiveSize = 0;
|
2010-03-22 19:25:57 +08:00
|
|
|
csa->cpioFdIn = fdNew();
|
2010-03-22 18:49:45 +08:00
|
|
|
csa->cpioList = rpmfiLink(pkg->cpioList);
|
1998-03-21 06:38:00 +08:00
|
|
|
|
2007-12-02 03:06:00 +08:00
|
|
|
rc = writeRPM(&pkg->header, NULL, fn, csa, spec->passPhrase, NULL);
|
2002-12-24 12:04:20 +08:00
|
|
|
csa->cpioList = rpmfiFree(csa->cpioList);
|
2010-03-22 19:25:57 +08:00
|
|
|
csa->cpioFdIn = fdFree(csa->cpioFdIn);
|
2008-11-10 22:52:29 +08:00
|
|
|
if (rc == RPMRC_OK) {
|
|
|
|
/* Do check each written package if enabled */
|
|
|
|
char *pkgcheck = rpmExpand("%{?_build_pkgcheck} ", fn, NULL);
|
|
|
|
if (pkgcheck[0] != ' ') {
|
|
|
|
rc = checkPackages(pkgcheck);
|
|
|
|
}
|
|
|
|
pkgcheck = _free(pkgcheck);
|
|
|
|
rstrcat(&pkglist, fn);
|
|
|
|
rstrcat(&pkglist, " ");
|
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
fn = _free(fn);
|
2008-11-10 22:52:29 +08:00
|
|
|
if (rc != RPMRC_OK) {
|
|
|
|
pkglist = _free(pkglist);
|
2000-01-25 04:02:32 +08:00
|
|
|
return rc;
|
2008-11-10 22:52:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now check the package set if enabled */
|
|
|
|
if (pkglist != NULL) {
|
|
|
|
char *pkgcheck_set = rpmExpand("%{?_build_pkgcheck_set} ", pkglist, NULL);
|
|
|
|
if (pkgcheck_set[0] != ' ') { /* run only if _build_pkgcheck_set is defined */
|
|
|
|
checkPackages(pkgcheck_set);
|
|
|
|
}
|
|
|
|
pkgcheck_set = _free(pkgcheck_set);
|
|
|
|
pkglist = _free(pkglist);
|
1998-03-21 06:38:00 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_OK;
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
|
|
|
|
2007-12-07 16:43:53 +08:00
|
|
|
rpmRC packageSources(rpmSpec spec)
|
1998-03-21 06:38:00 +08:00
|
|
|
{
|
2001-05-04 05:00:18 +08:00
|
|
|
struct cpioSourceArchive_s csabuf;
|
|
|
|
CSA_t csa = &csabuf;
|
2007-12-07 16:43:53 +08:00
|
|
|
rpmRC rc;
|
1998-03-21 06:38:00 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
/* Add some cruft */
|
2008-06-19 20:43:45 +08:00
|
|
|
headerPutString(spec->sourceHeader, RPMTAG_RPMVERSION, VERSION);
|
|
|
|
headerPutString(spec->sourceHeader, RPMTAG_BUILDHOST, buildHost());
|
|
|
|
headerPutUint32(spec->sourceHeader, RPMTAG_BUILDTIME, getBuildTime(), 1);
|
1998-03-21 06:38:00 +08:00
|
|
|
|
2008-03-25 01:03:20 +08:00
|
|
|
spec->cookie = _free(spec->cookie);
|
1998-03-21 06:38:00 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
/* XXX this should be %_srpmdir */
|
2007-12-15 16:39:15 +08:00
|
|
|
{ char *fn = rpmGetPath("%{_srcrpmdir}/", spec->sourceRpmName,NULL);
|
2008-11-10 22:52:29 +08:00
|
|
|
char *pkgcheck = rpmExpand("%{?_build_pkgcheck_srpm} ", fn, NULL);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2000-01-25 04:02:32 +08:00
|
|
|
memset(csa, 0, sizeof(*csa));
|
|
|
|
csa->cpioArchiveSize = 0;
|
2010-03-22 19:25:57 +08:00
|
|
|
csa->cpioFdIn = fdNew();
|
2010-03-22 18:49:45 +08:00
|
|
|
csa->cpioList = rpmfiLink(spec->sourceCpioList);
|
1998-03-21 06:38:00 +08:00
|
|
|
|
2002-12-24 10:41:45 +08:00
|
|
|
spec->sourcePkgId = NULL;
|
2007-12-02 03:06:00 +08:00
|
|
|
rc = writeRPM(&spec->sourceHeader, &spec->sourcePkgId, fn,
|
2000-01-25 04:02:32 +08:00
|
|
|
csa, spec->passPhrase, &(spec->cookie));
|
2002-12-24 10:41:45 +08:00
|
|
|
|
2008-11-10 22:52:29 +08:00
|
|
|
/* Do check SRPM package if enabled */
|
|
|
|
if (rc == RPMRC_OK && pkgcheck[0] != ' ') {
|
|
|
|
rc = checkPackages(pkgcheck);
|
|
|
|
}
|
|
|
|
|
2002-12-24 12:04:20 +08:00
|
|
|
csa->cpioList = rpmfiFree(csa->cpioList);
|
2010-03-22 19:25:57 +08:00
|
|
|
csa->cpioFdIn = fdFree(csa->cpioFdIn);
|
2008-11-10 22:52:29 +08:00
|
|
|
pkgcheck = _free(pkgcheck);
|
2001-04-29 09:05:43 +08:00
|
|
|
fn = _free(fn);
|
2000-01-25 04:02:32 +08:00
|
|
|
}
|
|
|
|
return rc;
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|