2000-08-28 03:18:25 +08:00
|
|
|
/** \ingroup rpmbuild
|
|
|
|
* \file build/spec.c
|
2000-01-25 04:02:32 +08:00
|
|
|
* Handle spec data structure.
|
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1995-12-13 01:53:17 +08:00
|
|
|
|
2008-02-03 22:24:07 +08:00
|
|
|
#include <rpm/header.h>
|
2007-12-08 20:02:32 +08:00
|
|
|
#include <rpm/rpmds.h>
|
|
|
|
#include <rpm/rpmfi.h>
|
|
|
|
#include <rpm/rpmts.h>
|
|
|
|
#include <rpm/rpmlog.h>
|
|
|
|
#include <rpm/rpmfileutil.h>
|
2002-04-12 00:55:19 +08:00
|
|
|
|
2008-02-25 18:24:22 +08:00
|
|
|
#include "rpmio/rpmlua.h"
|
2010-08-25 20:41:09 +08:00
|
|
|
#include "build/rpmbuild_internal.h"
|
2008-01-30 23:05:29 +08:00
|
|
|
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1998-07-31 06:09:42 +08:00
|
|
|
|
2008-03-18 15:10:13 +08:00
|
|
|
#define SKIPSPACE(s) { while (*(s) && risspace(*(s))) (s)++; }
|
1999-07-20 00:20:02 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2002-04-09 02:56:01 +08:00
|
|
|
* @param p trigger entry chain
|
2001-05-07 03:17:14 +08:00
|
|
|
* @return NULL always
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-07 03:17:14 +08:00
|
|
|
static inline
|
2007-09-12 05:03:27 +08:00
|
|
|
struct TriggerFileEntry * freeTriggerFiles(struct TriggerFileEntry * p)
|
1998-07-31 06:09:42 +08:00
|
|
|
{
|
1998-11-21 04:18:22 +08:00
|
|
|
struct TriggerFileEntry *o, *q = p;
|
1998-07-31 06:09:42 +08:00
|
|
|
|
1998-11-21 04:18:22 +08:00
|
|
|
while (q != NULL) {
|
|
|
|
o = q;
|
|
|
|
q = q->next;
|
2001-04-29 09:05:43 +08:00
|
|
|
o->fileName = _free(o->fileName);
|
|
|
|
o->script = _free(o->script);
|
|
|
|
o->prog = _free(o->prog);
|
|
|
|
o = _free(o);
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
2001-05-07 03:17:14 +08:00
|
|
|
return NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-05-07 03:17:14 +08:00
|
|
|
* Destroy source component chain.
|
2002-04-09 02:56:01 +08:00
|
|
|
* @param s source component chain
|
2001-05-07 03:17:14 +08:00
|
|
|
* @return NULL always
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-07 03:17:14 +08:00
|
|
|
static inline
|
2007-09-12 05:03:27 +08:00
|
|
|
struct Source * freeSources(struct Source * s)
|
1998-11-21 04:18:22 +08:00
|
|
|
{
|
|
|
|
struct Source *r, *t = s;
|
|
|
|
|
|
|
|
while (t != NULL) {
|
|
|
|
r = t;
|
|
|
|
t = t->next;
|
2001-04-29 09:05:43 +08:00
|
|
|
r->fullSource = _free(r->fullSource);
|
|
|
|
r = _free(r);
|
1998-11-21 04:18:22 +08:00
|
|
|
}
|
2001-05-07 03:17:14 +08:00
|
|
|
return NULL;
|
1998-11-21 04:18:22 +08:00
|
|
|
}
|
|
|
|
|
2007-12-07 16:43:53 +08:00
|
|
|
rpmRC lookupPackage(rpmSpec spec, const char *name, int flag,Package *pkg)
|
1998-07-31 06:09:42 +08:00
|
|
|
{
|
1999-07-20 00:20:02 +08:00
|
|
|
const char *pname;
|
2008-04-25 16:45:35 +08:00
|
|
|
char *fullName = NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
Package p;
|
2008-04-25 16:45:35 +08:00
|
|
|
|
1998-07-31 06:09:42 +08:00
|
|
|
/* "main" package */
|
1999-07-20 00:20:02 +08:00
|
|
|
if (name == NULL) {
|
|
|
|
if (pkg)
|
1998-07-31 06:09:42 +08:00
|
|
|
*pkg = spec->packages;
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_OK;
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Construct package name */
|
|
|
|
if (flag == PART_SUBNAME) {
|
2009-09-02 16:55:42 +08:00
|
|
|
pname = headerGetString(spec->packages->header, RPMTAG_NAME);
|
2008-04-25 16:45:35 +08:00
|
|
|
rasprintf(&fullName, "%s-%s", pname, name);
|
1998-07-31 06:09:42 +08:00
|
|
|
} else {
|
2008-04-25 16:45:35 +08:00
|
|
|
fullName = xstrdup(name);
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
|
|
|
|
1999-07-20 00:20:02 +08:00
|
|
|
/* Locate package with fullName */
|
1998-08-09 06:27:08 +08:00
|
|
|
for (p = spec->packages; p != NULL; p = p->next) {
|
2009-09-02 19:43:00 +08:00
|
|
|
pname = headerGetString(p->header, RPMTAG_NAME);
|
2009-08-31 16:08:05 +08:00
|
|
|
if (pname && (rstreq(fullName, pname))) {
|
1998-08-09 06:27:08 +08:00
|
|
|
break;
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
|
|
|
}
|
2008-04-25 16:45:35 +08:00
|
|
|
free(fullName);
|
1998-07-31 06:09:42 +08:00
|
|
|
|
1999-07-20 00:20:02 +08:00
|
|
|
if (pkg)
|
2007-09-12 05:03:27 +08:00
|
|
|
*pkg = p;
|
2007-12-07 16:43:53 +08:00
|
|
|
return ((p == NULL) ? RPMRC_FAIL : RPMRC_OK);
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
|
|
|
|
2007-09-21 20:23:02 +08:00
|
|
|
Package newPackage(rpmSpec spec)
|
1998-07-31 06:09:42 +08:00
|
|
|
{
|
2010-08-26 16:58:24 +08:00
|
|
|
Package p = xcalloc(1, sizeof(*p));
|
1998-07-31 06:09:42 +08:00
|
|
|
p->header = headerNew();
|
1999-03-27 04:07:34 +08:00
|
|
|
p->autoProv = 1;
|
|
|
|
p->autoReq = 1;
|
2010-08-26 17:21:33 +08:00
|
|
|
p->fileList = newStringBuf();
|
Add new %sepolicy section to the spec file format
The %sepolicy section is used to describe SELinux policy to be included
in a package. It's syntax is similar to other sections (%files, %pre,
%post, etc.) in that you can provide a string and -n after the
declaration to specify policy should be added to a subpackage.
For example:
%sepolicy
# policy in this section will be added to the main package
%sepolicy foo
# policy in this section will be added to the '<mainpackage>-foo' subpackage
%sepolicy -n bar
# policy in this section will be added to the 'bar' subpackage
The %sepolicy section contains zero or more %semodule directives, with the
following format:
%semodule [OPTIONS] path/to/module.pp
The available options are:
-b, --base
The module is a base module
-n, --name=NAME
The name of the module. If not given, assumes the name is the basename of
the module file with file extensions removed.
-t, --types=TYPES
One or more comma-separated strings specifying which policy types the
module can work with. To explicitly state that a module can work with any
policy type, "default" can be specified as the value. If not specified,
assumes the module can work with any policy type, and assigns the types as
"default".
Below is an example of this new format:
%sepolicy
%semodule -n foo -t mls policy/foo.pp
%semodule -n bar -t strict,targeted,mls -b policy/bar.pp
This also adds new header tags to store the new information:
RPMTAG_POLICYNAMES (string array)
RPMTAG_POLICYTYPES (string array)
RPMTAG_POLICYTYPESINDEXES (uint32 array)
RPMTAG_POLICYFLAGS (uint32 array)
The index of NAMES and FLAGS maps directly to the index of RPMTAG_POLICIES.
However, because a single policy can have multiple types, the mapping for
TYPES is not direct. For this, the index maps to TYPESINDEXES, which
contains the index of the policy that the type maps to. This is similar to
how DIRINDEXES is used to map DIRNAMES and BASENAMES. As an example, the
previous %sepolicy section would have the following header tags:
RPMTAG_POLICIES:
0: <foo.pp data, base64 encoded>
1: <bar.pp data, base64 encoded>
RPMTAG_POLICYNAMES:
0: foo
1: bar
RPMTAG_POLICYFLAGS:
0: 0
1: 1 # assumes flag 1 == BASE
RPMTAG_POILCYTYPES: RPMTAG_POLICYTYPESINDEXES:
0: mls 0: 0
1: strict 1: 1
2: targeted 2: 1
3: mls 3: 1
2010-08-31 04:32:29 +08:00
|
|
|
p->policyList = NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
|
1998-11-21 04:18:22 +08:00
|
|
|
if (spec->packages == NULL) {
|
1998-07-31 06:09:42 +08:00
|
|
|
spec->packages = p;
|
|
|
|
} else {
|
2010-08-26 16:58:24 +08:00
|
|
|
Package pp;
|
1998-07-31 06:09:42 +08:00
|
|
|
/* Always add package to end of list */
|
1998-11-21 04:18:22 +08:00
|
|
|
for (pp = spec->packages; pp->next != NULL; pp = pp->next)
|
2001-06-06 03:26:22 +08:00
|
|
|
{};
|
1998-07-31 06:09:42 +08:00
|
|
|
pp->next = p;
|
|
|
|
}
|
1998-11-21 04:18:22 +08:00
|
|
|
p->next = NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2010-08-25 19:13:10 +08:00
|
|
|
static Package freePackage(Package pkg)
|
1998-07-31 06:09:42 +08:00
|
|
|
{
|
2001-10-16 01:53:34 +08:00
|
|
|
if (pkg == NULL) return NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
|
2008-03-25 01:03:20 +08:00
|
|
|
pkg->preInFile = _free(pkg->preInFile);
|
|
|
|
pkg->postInFile = _free(pkg->postInFile);
|
|
|
|
pkg->preUnFile = _free(pkg->preUnFile);
|
|
|
|
pkg->postUnFile = _free(pkg->postUnFile);
|
|
|
|
pkg->verifyFile = _free(pkg->verifyFile);
|
2001-10-16 01:53:34 +08:00
|
|
|
|
2002-07-14 03:08:51 +08:00
|
|
|
pkg->header = headerFree(pkg->header);
|
2002-12-24 15:21:04 +08:00
|
|
|
pkg->ds = rpmdsFree(pkg->ds);
|
2001-10-16 01:53:34 +08:00
|
|
|
pkg->fileList = freeStringBuf(pkg->fileList);
|
2009-06-23 17:05:06 +08:00
|
|
|
pkg->fileFile = freeStringBuf(pkg->fileFile);
|
Add new %sepolicy section to the spec file format
The %sepolicy section is used to describe SELinux policy to be included
in a package. It's syntax is similar to other sections (%files, %pre,
%post, etc.) in that you can provide a string and -n after the
declaration to specify policy should be added to a subpackage.
For example:
%sepolicy
# policy in this section will be added to the main package
%sepolicy foo
# policy in this section will be added to the '<mainpackage>-foo' subpackage
%sepolicy -n bar
# policy in this section will be added to the 'bar' subpackage
The %sepolicy section contains zero or more %semodule directives, with the
following format:
%semodule [OPTIONS] path/to/module.pp
The available options are:
-b, --base
The module is a base module
-n, --name=NAME
The name of the module. If not given, assumes the name is the basename of
the module file with file extensions removed.
-t, --types=TYPES
One or more comma-separated strings specifying which policy types the
module can work with. To explicitly state that a module can work with any
policy type, "default" can be specified as the value. If not specified,
assumes the module can work with any policy type, and assigns the types as
"default".
Below is an example of this new format:
%sepolicy
%semodule -n foo -t mls policy/foo.pp
%semodule -n bar -t strict,targeted,mls -b policy/bar.pp
This also adds new header tags to store the new information:
RPMTAG_POLICYNAMES (string array)
RPMTAG_POLICYTYPES (string array)
RPMTAG_POLICYTYPESINDEXES (uint32 array)
RPMTAG_POLICYFLAGS (uint32 array)
The index of NAMES and FLAGS maps directly to the index of RPMTAG_POLICIES.
However, because a single policy can have multiple types, the mapping for
TYPES is not direct. For this, the index maps to TYPESINDEXES, which
contains the index of the policy that the type maps to. This is similar to
how DIRINDEXES is used to map DIRNAMES and BASENAMES. As an example, the
previous %sepolicy section would have the following header tags:
RPMTAG_POLICIES:
0: <foo.pp data, base64 encoded>
1: <bar.pp data, base64 encoded>
RPMTAG_POLICYNAMES:
0: foo
1: bar
RPMTAG_POLICYFLAGS:
0: 0
1: 1 # assumes flag 1 == BASE
RPMTAG_POILCYTYPES: RPMTAG_POLICYTYPESINDEXES:
0: mls 0: 0
1: strict 1: 1
2: targeted 2: 1
3: mls 3: 1
2010-08-31 04:32:29 +08:00
|
|
|
pkg->policyList = freeStringBuf(pkg->policyList);
|
2001-10-16 01:53:34 +08:00
|
|
|
if (pkg->cpioList) {
|
2002-05-20 02:42:25 +08:00
|
|
|
rpmfi fi = pkg->cpioList;
|
2001-10-16 01:53:34 +08:00
|
|
|
pkg->cpioList = NULL;
|
2002-08-20 06:27:44 +08:00
|
|
|
fi = rpmfiFree(fi);
|
2001-01-24 07:03:28 +08:00
|
|
|
}
|
1998-07-31 06:09:42 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
pkg->specialDoc = freeStringBuf(pkg->specialDoc);
|
2008-05-06 17:48:09 +08:00
|
|
|
pkg->specialDocDir = _free(pkg->specialDocDir);
|
2001-10-16 01:53:34 +08:00
|
|
|
pkg->icon = freeSources(pkg->icon);
|
|
|
|
pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
|
1998-07-31 06:09:42 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
pkg = _free(pkg);
|
2001-05-07 03:17:14 +08:00
|
|
|
return NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 18:30:12 +08:00
|
|
|
static Package freePackages(Package packages)
|
1998-07-31 06:09:42 +08:00
|
|
|
{
|
|
|
|
Package p;
|
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
while ((p = packages) != NULL) {
|
|
|
|
packages = p->next;
|
1998-11-21 04:18:22 +08:00
|
|
|
p->next = NULL;
|
2001-05-07 03:17:14 +08:00
|
|
|
p = freePackage(p);
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
2001-05-07 03:17:14 +08:00
|
|
|
return NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
1995-11-28 06:31:21 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2007-09-12 05:03:27 +08:00
|
|
|
static inline speclines freeSl(speclines sl)
|
1999-02-23 01:44:57 +08:00
|
|
|
{
|
|
|
|
int i;
|
2001-05-07 03:17:14 +08:00
|
|
|
if (sl == NULL) return NULL;
|
1999-02-23 01:44:57 +08:00
|
|
|
for (i = 0; i < sl->sl_nlines; i++)
|
2001-04-29 09:05:43 +08:00
|
|
|
sl->sl_lines[i] = _free(sl->sl_lines[i]);
|
|
|
|
sl->sl_lines = _free(sl->sl_lines);
|
2010-09-21 19:26:29 +08:00
|
|
|
_free(sl);
|
|
|
|
return NULL;
|
1999-02-23 01:44:57 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2007-09-12 05:03:27 +08:00
|
|
|
static inline spectags freeSt(spectags st)
|
1999-02-23 01:44:57 +08:00
|
|
|
{
|
|
|
|
int i;
|
2001-05-07 03:17:14 +08:00
|
|
|
if (st == NULL) return NULL;
|
1999-02-23 01:44:57 +08:00
|
|
|
for (i = 0; i < st->st_ntags; i++) {
|
2001-05-07 03:17:14 +08:00
|
|
|
spectag t = st->st_t + i;
|
2008-03-25 01:03:00 +08:00
|
|
|
t->t_lang = _free(t->t_lang);
|
|
|
|
t->t_msgid = _free(t->t_msgid);
|
1999-02-23 01:44:57 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
st->st_t = _free(st->st_t);
|
2010-09-21 19:26:29 +08:00
|
|
|
_free(st);
|
|
|
|
return NULL;
|
1999-02-23 01:44:57 +08:00
|
|
|
}
|
|
|
|
|
2007-09-21 20:23:02 +08:00
|
|
|
rpmSpec newSpec(void)
|
1995-12-13 01:53:17 +08:00
|
|
|
{
|
2007-09-21 20:23:02 +08:00
|
|
|
rpmSpec spec = xcalloc(1, sizeof(*spec));
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
spec->specFile = NULL;
|
1995-12-12 06:52:59 +08:00
|
|
|
|
2008-07-07 15:17:21 +08:00
|
|
|
spec->sl = NULL;
|
|
|
|
spec->st = NULL;
|
1999-02-23 01:44:57 +08:00
|
|
|
|
1998-10-07 01:34:58 +08:00
|
|
|
spec->fileStack = NULL;
|
1999-07-20 02:39:48 +08:00
|
|
|
spec->lbuf[0] = '\0';
|
|
|
|
spec->line = spec->lbuf;
|
|
|
|
spec->nextline = NULL;
|
1999-07-27 05:51:03 +08:00
|
|
|
spec->nextpeekc = '\0';
|
1998-11-21 04:18:22 +08:00
|
|
|
spec->lineNum = 0;
|
2001-04-29 09:05:43 +08:00
|
|
|
spec->readStack = xcalloc(1, sizeof(*spec->readStack));
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->readStack->next = NULL;
|
|
|
|
spec->readStack->reading = 1;
|
1995-12-14 23:52:51 +08:00
|
|
|
|
2008-04-05 01:37:48 +08:00
|
|
|
spec->rootDir = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->prep = NULL;
|
|
|
|
spec->build = NULL;
|
|
|
|
spec->install = NULL;
|
2002-12-22 04:37:37 +08:00
|
|
|
spec->check = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->clean = NULL;
|
1996-07-17 09:35:08 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->sources = NULL;
|
|
|
|
spec->packages = NULL;
|
|
|
|
spec->noSource = 0;
|
|
|
|
spec->numSources = 0;
|
1996-07-17 09:35:08 +08:00
|
|
|
|
2002-12-22 04:37:37 +08:00
|
|
|
spec->sourceRpmName = NULL;
|
|
|
|
spec->sourcePkgId = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->sourceHeader = NULL;
|
|
|
|
spec->sourceCpioList = NULL;
|
|
|
|
|
2008-04-05 01:37:48 +08:00
|
|
|
spec->buildRoot = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->buildSubdir = NULL;
|
1997-07-25 21:09:05 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->buildRestrictions = headerNew();
|
2001-05-07 03:17:14 +08:00
|
|
|
spec->BANames = NULL;
|
|
|
|
spec->BACount = 0;
|
|
|
|
spec->recursing = 0;
|
|
|
|
spec->BASpecs = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2010-09-01 23:03:05 +08:00
|
|
|
spec->flags = RPMSPEC_NONE;
|
1998-11-21 04:18:22 +08:00
|
|
|
|
2007-09-12 05:03:27 +08:00
|
|
|
spec->macros = rpmGlobalMacroContext;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2008-02-25 18:24:22 +08:00
|
|
|
#ifdef WITH_LUA
|
|
|
|
{
|
|
|
|
/* make sure patches and sources tables always exist */
|
|
|
|
rpmlua lua = NULL; /* global state */
|
|
|
|
rpmluaPushTable(lua, "patches");
|
|
|
|
rpmluaPushTable(lua, "sources");
|
|
|
|
rpmluaPop(lua);
|
|
|
|
rpmluaPop(lua);
|
|
|
|
}
|
|
|
|
#endif
|
1998-07-26 05:00:26 +08:00
|
|
|
return spec;
|
1997-07-25 21:09:05 +08:00
|
|
|
}
|
|
|
|
|
2010-09-01 22:29:27 +08:00
|
|
|
rpmSpec rpmSpecFree(rpmSpec spec)
|
1995-12-13 01:53:17 +08:00
|
|
|
{
|
1998-10-07 01:34:58 +08:00
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
if (spec == NULL) return NULL;
|
|
|
|
|
|
|
|
spec->sl = freeSl(spec->sl);
|
|
|
|
spec->st = freeSt(spec->st);
|
1999-02-23 01:44:57 +08:00
|
|
|
|
2001-05-06 03:28:32 +08:00
|
|
|
spec->prep = freeStringBuf(spec->prep);
|
|
|
|
spec->build = freeStringBuf(spec->build);
|
|
|
|
spec->install = freeStringBuf(spec->install);
|
2002-12-22 04:37:37 +08:00
|
|
|
spec->check = freeStringBuf(spec->check);
|
2001-05-06 03:28:32 +08:00
|
|
|
spec->clean = freeStringBuf(spec->clean);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2008-04-05 01:37:48 +08:00
|
|
|
spec->buildRoot = _free(spec->buildRoot);
|
2008-03-25 01:03:20 +08:00
|
|
|
spec->buildSubdir = _free(spec->buildSubdir);
|
|
|
|
spec->specFile = _free(spec->specFile);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
closeSpec(spec);
|
1998-10-07 01:34:58 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
while (spec->readStack) {
|
2009-09-07 22:00:49 +08:00
|
|
|
struct ReadLevelEntry *rl = spec->readStack;
|
2001-04-29 09:05:43 +08:00
|
|
|
spec->readStack = rl->next;
|
1998-11-21 04:18:22 +08:00
|
|
|
rl->next = NULL;
|
2009-09-07 22:00:49 +08:00
|
|
|
free(rl);
|
1995-12-13 01:53:17 +08:00
|
|
|
}
|
|
|
|
|
2008-03-25 01:03:20 +08:00
|
|
|
spec->sourceRpmName = _free(spec->sourceRpmName);
|
2002-12-22 04:37:37 +08:00
|
|
|
spec->sourcePkgId = _free(spec->sourcePkgId);
|
2002-07-14 03:08:51 +08:00
|
|
|
spec->sourceHeader = headerFree(spec->sourceHeader);
|
1995-12-18 22:56:49 +08:00
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
if (spec->sourceCpioList) {
|
2002-05-20 02:42:25 +08:00
|
|
|
rpmfi fi = spec->sourceCpioList;
|
2001-04-29 09:05:43 +08:00
|
|
|
spec->sourceCpioList = NULL;
|
2002-08-20 06:27:44 +08:00
|
|
|
fi = rpmfiFree(fi);
|
2001-01-24 07:03:28 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2002-07-14 03:08:51 +08:00
|
|
|
spec->buildRestrictions = headerFree(spec->buildRestrictions);
|
1995-12-18 22:56:49 +08:00
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
if (!spec->recursing) {
|
|
|
|
if (spec->BASpecs != NULL)
|
|
|
|
while (spec->BACount--) {
|
|
|
|
spec->BASpecs[spec->BACount] =
|
2010-09-01 22:29:27 +08:00
|
|
|
rpmSpecFree(spec->BASpecs[spec->BACount]);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
2001-05-07 03:17:14 +08:00
|
|
|
spec->BASpecs = _free(spec->BASpecs);
|
1995-12-18 22:56:49 +08:00
|
|
|
}
|
2001-05-07 03:17:14 +08:00
|
|
|
spec->BANames = _free(spec->BANames);
|
1995-12-18 22:56:49 +08:00
|
|
|
|
2008-02-25 18:24:22 +08:00
|
|
|
#ifdef WITH_LUA
|
|
|
|
rpmlua lua = NULL; /* global state */
|
|
|
|
rpmluaDelVar(lua, "patches");
|
|
|
|
rpmluaDelVar(lua, "sources");
|
|
|
|
#endif
|
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
spec->sources = freeSources(spec->sources);
|
|
|
|
spec->packages = freePackages(spec->packages);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
spec = _free(spec);
|
2001-05-07 03:17:14 +08:00
|
|
|
|
|
|
|
return spec;
|
1995-12-18 22:56:49 +08:00
|
|
|
}
|
1998-10-07 01:34:58 +08:00
|
|
|
|
2010-10-10 22:35:31 +08:00
|
|
|
Header rpmSpecSourceHeader(rpmSpec spec)
|
|
|
|
{
|
|
|
|
return spec->sourceHeader;
|
|
|
|
}
|
|
|
|
|
2010-10-22 18:46:14 +08:00
|
|
|
rpmds rpmSpecDS(rpmSpec spec, rpmTagVal tag)
|
2010-09-02 19:25:30 +08:00
|
|
|
{
|
|
|
|
return (spec != NULL) ? rpmdsNew(spec->buildRestrictions, tag, 0) : NULL;
|
|
|
|
}
|
|
|
|
|
2010-09-02 19:13:28 +08:00
|
|
|
rpmps rpmSpecCheckDeps(rpmts ts, rpmSpec spec)
|
|
|
|
{
|
|
|
|
rpmps probs = NULL;
|
|
|
|
|
2010-09-14 14:44:06 +08:00
|
|
|
rpmtsEmpty(ts);
|
2010-09-02 19:13:28 +08:00
|
|
|
|
2010-10-10 22:35:31 +08:00
|
|
|
rpmtsAddInstallElement(ts, rpmSpecSourceHeader(spec), NULL, 0, NULL);
|
2010-09-02 19:13:28 +08:00
|
|
|
rpmtsCheck(ts);
|
|
|
|
probs = rpmtsProblems(ts);
|
|
|
|
|
2010-09-14 14:44:06 +08:00
|
|
|
rpmtsEmpty(ts);
|
2010-09-02 19:13:28 +08:00
|
|
|
return probs;
|
|
|
|
}
|
|
|
|
|
2010-10-01 20:03:22 +08:00
|
|
|
struct rpmSpecIter_s {
|
|
|
|
void *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define SPEC_LISTITER_INIT(_itertype, _iteritem) \
|
|
|
|
_itertype iter = NULL; \
|
|
|
|
if (spec) { \
|
|
|
|
iter = xcalloc(1, sizeof(*iter)); \
|
|
|
|
iter->next = spec->_iteritem; \
|
|
|
|
} \
|
|
|
|
return iter
|
|
|
|
|
|
|
|
#define SPEC_LISTITER_NEXT(_valuetype) \
|
|
|
|
_valuetype item = NULL; \
|
|
|
|
if (iter) { \
|
|
|
|
item = iter->next; \
|
|
|
|
iter->next = (item) ? item->next : NULL; \
|
|
|
|
} \
|
|
|
|
return item
|
|
|
|
|
|
|
|
#define SPEC_LISTITER_FREE() \
|
|
|
|
free(iter); \
|
|
|
|
return NULL
|
|
|
|
|
|
|
|
|
|
|
|
rpmSpecPkgIter rpmSpecPkgIterInit(rpmSpec spec)
|
|
|
|
{
|
|
|
|
SPEC_LISTITER_INIT(rpmSpecPkgIter, packages);
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmSpecPkgIter rpmSpecPkgIterFree(rpmSpecPkgIter iter)
|
|
|
|
{
|
|
|
|
SPEC_LISTITER_FREE();
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmSpecPkg rpmSpecPkgIterNext(rpmSpecPkgIter iter)
|
|
|
|
{
|
|
|
|
SPEC_LISTITER_NEXT(rpmSpecPkg);
|
|
|
|
}
|
|
|
|
|
|
|
|
Header rpmSpecPkgHeader(rpmSpecPkg pkg)
|
|
|
|
{
|
|
|
|
return (pkg != NULL) ? pkg->header : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmSpecSrcIter rpmSpecSrcIterInit(rpmSpec spec)
|
|
|
|
{
|
|
|
|
SPEC_LISTITER_INIT(rpmSpecSrcIter, sources);
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmSpecSrcIter rpmSpecSrcIterFree(rpmSpecSrcIter iter)
|
|
|
|
{
|
|
|
|
SPEC_LISTITER_FREE();
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmSpecSrc rpmSpecSrcIterNext(rpmSpecSrcIter iter)
|
|
|
|
{
|
|
|
|
SPEC_LISTITER_NEXT(rpmSpecSrc);
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmSourceFlags rpmSpecSrcFlags(rpmSpecSrc src)
|
|
|
|
{
|
|
|
|
return (src != NULL) ? src->flags : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rpmSpecSrcNum(rpmSpecSrc src)
|
|
|
|
{
|
|
|
|
return (src != NULL) ? src->num : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char * rpmSpecSrcFilename(rpmSpecSrc src, int full)
|
|
|
|
{
|
|
|
|
const char *source = NULL;
|
|
|
|
if (src) {
|
|
|
|
source = full ? src->fullSource : src->source;
|
|
|
|
}
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
2010-10-01 20:14:34 +08:00
|
|
|
const char * rpmSpecGetSection(rpmSpec spec, int section)
|
|
|
|
{
|
|
|
|
if (spec) {
|
|
|
|
switch (section) {
|
|
|
|
case RPMBUILD_PREP: return getStringBuf(spec->prep);
|
|
|
|
case RPMBUILD_BUILD: return getStringBuf(spec->build);
|
|
|
|
case RPMBUILD_INSTALL: return getStringBuf(spec->install);
|
|
|
|
case RPMBUILD_CHECK: return getStringBuf(spec->check);
|
|
|
|
case RPMBUILD_CLEAN: return getStringBuf(spec->clean);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-12-22 10:11:05 +08:00
|
|
|
int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg)
|
|
|
|
{
|
2007-09-21 20:23:02 +08:00
|
|
|
rpmSpec spec = NULL;
|
2002-12-22 10:11:05 +08:00
|
|
|
int res = 1;
|
|
|
|
int xx;
|
|
|
|
|
|
|
|
if (qva->qva_showPackage == NULL)
|
|
|
|
goto exit;
|
|
|
|
|
2010-09-01 21:59:22 +08:00
|
|
|
spec = rpmSpecParse(arg, (RPMSPEC_ANYARCH|RPMSPEC_FORCE), NULL);
|
|
|
|
if (spec == NULL) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR,
|
2002-12-22 10:11:05 +08:00
|
|
|
_("query of specfile %s failed, can't parse\n"), arg);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = 0;
|
2010-10-12 19:41:35 +08:00
|
|
|
if (qva->qva_source == RPMQV_SPECRPMS) {
|
|
|
|
for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next)
|
|
|
|
xx = qva->qva_showPackage(qva, ts, pkg->header);
|
|
|
|
} else {
|
|
|
|
xx = qva->qva_showPackage(qva, ts, spec->sourceHeader);
|
|
|
|
}
|
2002-12-22 10:11:05 +08:00
|
|
|
|
|
|
|
exit:
|
2010-09-01 22:29:27 +08:00
|
|
|
spec = rpmSpecFree(spec);
|
2002-12-22 10:11:05 +08:00
|
|
|
return res;
|
|
|
|
}
|