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
|
|
|
|
2007-11-23 18:37:54 +08:00
|
|
|
#include "build/buildio.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
|
|
|
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1998-07-31 06:09:42 +08:00
|
|
|
|
2000-02-24 01:34:41 +08:00
|
|
|
extern int specedit;
|
1999-02-23 01:44:57 +08:00
|
|
|
|
2007-10-29 19:24:00 +08:00
|
|
|
#define SKIPSPACE(s) { while (*(s) && xisspace(*(s))) (s)++; }
|
2001-04-29 09:05:43 +08:00
|
|
|
#define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
|
|
|
|
#define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
|
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;
|
1998-11-21 04:18:22 +08:00
|
|
|
const char *fullName;
|
1998-07-31 06:09:42 +08:00
|
|
|
Package p;
|
|
|
|
|
|
|
|
/* "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 */
|
1999-07-20 00:20:02 +08:00
|
|
|
{ char *n;
|
1998-07-31 06:09:42 +08:00
|
|
|
if (flag == PART_SUBNAME) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerNVR(spec->packages->header, &pname, NULL, NULL);
|
1999-07-20 00:20:02 +08:00
|
|
|
fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
|
2001-05-01 06:32:22 +08:00
|
|
|
while (*pname != '\0') *n++ = *pname++;
|
1999-07-20 00:20:02 +08:00
|
|
|
*n++ = '-';
|
1998-07-31 06:09:42 +08:00
|
|
|
} else {
|
1999-07-20 00:20:02 +08:00
|
|
|
fullName = n = alloca(strlen(name)+1);
|
1998-07-31 06:09:42 +08:00
|
|
|
}
|
1999-07-20 00:20:02 +08:00
|
|
|
strcpy(n, 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) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerNVR(p->header, &pname, NULL, NULL);
|
1999-07-20 00:20:02 +08:00
|
|
|
if (pname && (! strcmp(fullName, pname))) {
|
1998-08-09 06:27:08 +08:00
|
|
|
break;
|
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
|
|
|
{
|
|
|
|
Package p;
|
|
|
|
Package pp;
|
|
|
|
|
2001-09-25 05:53:14 +08:00
|
|
|
p = xcalloc(1, sizeof(*p));
|
1998-07-31 06:09:42 +08:00
|
|
|
|
|
|
|
p->header = headerNew();
|
2002-12-24 15:21:04 +08:00
|
|
|
p->ds = NULL;
|
1998-07-31 06:09:42 +08:00
|
|
|
p->icon = NULL;
|
1999-03-27 04:07:34 +08:00
|
|
|
|
|
|
|
p->autoProv = 1;
|
|
|
|
p->autoReq = 1;
|
1998-07-31 06:09:42 +08:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
p->reqProv = NULL;
|
|
|
|
p->triggers = NULL;
|
|
|
|
p->triggerScripts = NULL;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
p->triggerFiles = NULL;
|
|
|
|
|
|
|
|
p->fileFile = NULL;
|
|
|
|
p->fileList = NULL;
|
|
|
|
|
|
|
|
p->cpioList = NULL;
|
|
|
|
|
|
|
|
p->preInFile = NULL;
|
|
|
|
p->postInFile = NULL;
|
|
|
|
p->preUnFile = NULL;
|
|
|
|
p->postUnFile = NULL;
|
|
|
|
p->verifyFile = NULL;
|
|
|
|
|
|
|
|
p->specialDoc = NULL;
|
|
|
|
|
1998-11-21 04:18:22 +08:00
|
|
|
if (spec->packages == NULL) {
|
1998-07-31 06:09:42 +08:00
|
|
|
spec->packages = p;
|
|
|
|
} else {
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
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
|
|
|
|
2001-10-16 01:53:34 +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);
|
|
|
|
|
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);
|
|
|
|
pkg->fileFile = _free(pkg->fileFile);
|
|
|
|
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);
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
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-21 20:23:02 +08:00
|
|
|
static inline struct Source *findSource(rpmSpec spec, int num, int flag)
|
1995-12-28 00:50:50 +08:00
|
|
|
{
|
1998-11-21 04:18:22 +08:00
|
|
|
struct Source *p;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
for (p = spec->sources; p != NULL; p = p->next)
|
|
|
|
if ((num == p->num) && (p->flags & flag)) return p;
|
1995-12-28 00:50:50 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
1995-12-28 00:50:50 +08:00
|
|
|
|
2007-12-14 01:32:37 +08:00
|
|
|
int parseNoSource(rpmSpec spec, const char * field, rpm_tag_t tag)
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
1999-07-20 00:20:02 +08:00
|
|
|
const char *f, *fe;
|
|
|
|
const char *name;
|
1998-07-26 05:00:26 +08:00
|
|
|
int num, flag;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
if (tag == RPMTAG_NOSOURCE) {
|
|
|
|
flag = RPMBUILD_ISSOURCE;
|
|
|
|
name = "source";
|
|
|
|
} else {
|
|
|
|
flag = RPMBUILD_ISPATCH;
|
|
|
|
name = "patch";
|
1996-05-08 02:49:33 +08:00
|
|
|
}
|
|
|
|
|
1999-07-20 00:20:02 +08:00
|
|
|
fe = field;
|
2001-05-01 06:32:22 +08:00
|
|
|
for (f = fe; *f != '\0'; f = fe) {
|
1998-11-21 04:18:22 +08:00
|
|
|
struct Source *p;
|
1999-07-20 00:20:02 +08:00
|
|
|
|
|
|
|
SKIPWHITE(f);
|
|
|
|
if (*f == '\0')
|
|
|
|
break;
|
|
|
|
fe = f;
|
|
|
|
SKIPNONWHITE(fe);
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*fe != '\0') fe++;
|
1999-07-20 00:20:02 +08:00
|
|
|
|
|
|
|
if (parseNum(f, &num)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("line %d: Bad number: %s\n"),
|
1999-07-20 00:20:02 +08:00
|
|
|
spec->lineNum, f);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1996-05-08 02:49:33 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
if (! (p = findSource(spec, num, flag))) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("line %d: Bad no%s number: %d\n"),
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->lineNum, name, num);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
1996-05-08 02:49:33 +08:00
|
|
|
}
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
p->flags |= RPMBUILD_ISNO;
|
1997-09-17 04:09:31 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
1995-12-12 06:52:59 +08:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:32:37 +08:00
|
|
|
int addSource(rpmSpec spec, Package pkg, const char *field, rpm_tag_t tag)
|
1995-11-28 06:31:21 +08:00
|
|
|
{
|
1998-01-13 05:31:29 +08:00
|
|
|
struct Source *p;
|
|
|
|
int flag = 0;
|
2007-12-14 21:17:59 +08:00
|
|
|
const char *name = NULL;
|
1999-07-20 00:20:02 +08:00
|
|
|
char *nump;
|
|
|
|
const char *fieldp = NULL;
|
1998-01-13 05:31:29 +08:00
|
|
|
char buf[BUFSIZ];
|
|
|
|
int num = 0;
|
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
buf[0] = '\0';
|
1998-01-13 05:31:29 +08:00
|
|
|
switch (tag) {
|
|
|
|
case RPMTAG_SOURCE:
|
|
|
|
flag = RPMBUILD_ISSOURCE;
|
|
|
|
name = "source";
|
|
|
|
fieldp = spec->line + 6;
|
|
|
|
break;
|
|
|
|
case RPMTAG_PATCH:
|
|
|
|
flag = RPMBUILD_ISPATCH;
|
|
|
|
name = "patch";
|
|
|
|
fieldp = spec->line + 5;
|
|
|
|
break;
|
|
|
|
case RPMTAG_ICON:
|
|
|
|
flag = RPMBUILD_ISICON;
|
1999-07-20 00:20:02 +08:00
|
|
|
fieldp = NULL;
|
1998-01-13 05:31:29 +08:00
|
|
|
break;
|
1995-12-14 23:52:51 +08:00
|
|
|
}
|
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
/* Get the number */
|
|
|
|
if (tag != RPMTAG_ICON) {
|
|
|
|
/* We already know that a ':' exists, and that there */
|
|
|
|
/* are no spaces before it. */
|
1998-06-29 12:42:36 +08:00
|
|
|
/* This also now allows for spaces and tabs between */
|
|
|
|
/* the number and the ':' */
|
1995-12-14 23:52:51 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
nump = buf;
|
1998-06-29 12:42:36 +08:00
|
|
|
while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
|
1998-01-13 05:31:29 +08:00
|
|
|
*nump++ = *fieldp++;
|
1996-02-22 01:19:52 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
*nump = '\0';
|
1995-12-14 23:52:51 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
nump = buf;
|
|
|
|
SKIPSPACE(nump);
|
2001-05-04 05:00:18 +08:00
|
|
|
if (nump == NULL || *nump == '\0') {
|
1998-01-13 05:31:29 +08:00
|
|
|
num = 0;
|
1996-02-22 01:19:52 +08:00
|
|
|
} else {
|
1998-01-13 05:31:29 +08:00
|
|
|
if (parseNum(buf, &num)) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("line %d: Bad %s number: %s\n"),
|
1998-01-13 05:31:29 +08:00
|
|
|
spec->lineNum, name, spec->line);
|
2007-12-07 16:43:53 +08:00
|
|
|
return RPMRC_FAIL;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1996-02-23 10:22:18 +08:00
|
|
|
}
|
1996-02-22 01:19:52 +08:00
|
|
|
}
|
1997-01-25 12:48:06 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
/* Create the entry and link it in */
|
2001-10-16 22:58:57 +08:00
|
|
|
p = xmalloc(sizeof(*p));
|
1998-01-13 05:31:29 +08:00
|
|
|
p->num = num;
|
1999-09-21 11:22:53 +08:00
|
|
|
p->fullSource = xstrdup(field);
|
1998-01-13 05:31:29 +08:00
|
|
|
p->flags = flag;
|
2001-05-07 03:17:14 +08:00
|
|
|
p->source = strrchr(p->fullSource, '/');
|
1998-01-13 05:31:29 +08:00
|
|
|
if (p->source) {
|
|
|
|
p->source++;
|
1997-01-25 12:48:06 +08:00
|
|
|
} else {
|
1998-01-13 05:31:29 +08:00
|
|
|
p->source = p->fullSource;
|
1997-01-25 12:48:06 +08:00
|
|
|
}
|
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
if (tag != RPMTAG_ICON) {
|
|
|
|
p->next = spec->sources;
|
|
|
|
spec->sources = p;
|
|
|
|
} else {
|
|
|
|
p->next = pkg->icon;
|
|
|
|
pkg->icon = p;
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
1995-12-28 00:50:50 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
spec->numSources++;
|
1995-12-28 00:50:50 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
if (tag != RPMTAG_ICON) {
|
1999-01-06 07:13:56 +08:00
|
|
|
const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
|
1998-09-06 04:02:08 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
sprintf(buf, "%s%d",
|
|
|
|
(flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
|
1998-08-02 23:14:38 +08:00
|
|
|
addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
|
1998-01-13 05:31:29 +08:00
|
|
|
sprintf(buf, "%sURL%d",
|
|
|
|
(flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
|
1998-08-02 23:14:38 +08:00
|
|
|
addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
|
2001-04-29 09:05:43 +08:00
|
|
|
body = _free(body);
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
1995-12-13 01:53:17 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
return 0;
|
1995-12-13 01:53:17 +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 newSl(void)
|
1999-02-23 01:44:57 +08:00
|
|
|
{
|
2001-05-07 03:17:14 +08:00
|
|
|
speclines sl = NULL;
|
2000-02-24 01:34:41 +08:00
|
|
|
if (specedit) {
|
2001-05-07 03:17:14 +08:00
|
|
|
sl = xmalloc(sizeof(*sl));
|
2000-02-24 01:34:41 +08:00
|
|
|
sl->sl_lines = NULL;
|
|
|
|
sl->sl_nalloc = 0;
|
|
|
|
sl->sl_nlines = 0;
|
|
|
|
}
|
1999-02-23 01:44:57 +08:00
|
|
|
return sl;
|
|
|
|
}
|
|
|
|
|
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);
|
2001-05-07 03:17:14 +08:00
|
|
|
return _free(sl);
|
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 newSt(void)
|
1999-02-23 01:44:57 +08:00
|
|
|
{
|
2001-05-07 03:17:14 +08:00
|
|
|
spectags st = NULL;
|
2000-02-24 01:34:41 +08:00
|
|
|
if (specedit) {
|
2001-05-07 03:17:14 +08:00
|
|
|
st = xmalloc(sizeof(*st));
|
2000-02-24 01:34:41 +08:00
|
|
|
st->st_t = NULL;
|
|
|
|
st->st_nalloc = 0;
|
|
|
|
st->st_ntags = 0;
|
|
|
|
}
|
1999-02-23 01:44:57 +08:00
|
|
|
return st;
|
|
|
|
}
|
|
|
|
|
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;
|
2001-04-29 09:05:43 +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);
|
2001-05-07 03:17:14 +08:00
|
|
|
return _free(st);
|
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
|
|
|
|
1999-02-23 01:44:57 +08:00
|
|
|
spec->sl = newSl();
|
|
|
|
spec->st = newSt();
|
|
|
|
|
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
|
|
|
|
1999-11-20 02:19:41 +08:00
|
|
|
spec->rootURL = 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;
|
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
spec->gotBuildRootURL = 0;
|
|
|
|
spec->buildRootURL = 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->passPhrase = NULL;
|
|
|
|
spec->timeCheck = 0;
|
|
|
|
spec->cookie = NULL;
|
|
|
|
|
|
|
|
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
|
|
|
|
1998-11-21 04:18:22 +08:00
|
|
|
spec->force = 0;
|
|
|
|
spec->anyarch = 0;
|
|
|
|
|
2007-09-12 05:03:27 +08:00
|
|
|
spec->macros = rpmGlobalMacroContext;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
return spec;
|
1997-07-25 21:09:05 +08:00
|
|
|
}
|
|
|
|
|
2007-09-21 20:23:02 +08:00
|
|
|
rpmSpec freeSpec(rpmSpec spec)
|
1995-12-13 01:53:17 +08:00
|
|
|
{
|
1998-07-26 05:00:26 +08:00
|
|
|
struct ReadLevelEntry *rl;
|
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
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
spec->buildRootURL = _free(spec->buildRootURL);
|
|
|
|
spec->buildSubdir = _free(spec->buildSubdir);
|
|
|
|
spec->rootURL = _free(spec->rootURL);
|
|
|
|
spec->specFile = _free(spec->specFile);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
#ifdef DEAD
|
|
|
|
{ struct OpenFileInfo *ofi;
|
1998-10-07 01:34:58 +08:00
|
|
|
while (spec->fileStack) {
|
|
|
|
ofi = spec->fileStack;
|
2001-04-29 09:05:43 +08:00
|
|
|
spec->fileStack = ofi->next;
|
1998-11-21 04:18:22 +08:00
|
|
|
ofi->next = NULL;
|
2001-04-29 09:05:43 +08:00
|
|
|
ofi->fileName = _free(ofi->fileName);
|
|
|
|
ofi = _free(ofi);
|
1998-10-07 01:34:58 +08:00
|
|
|
}
|
2001-05-07 03:17:14 +08:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
closeSpec(spec);
|
|
|
|
#endif
|
1998-10-07 01:34:58 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
while (spec->readStack) {
|
|
|
|
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;
|
2001-04-29 09:05:43 +08:00
|
|
|
rl = _free(rl);
|
1995-12-13 01:53:17 +08:00
|
|
|
}
|
|
|
|
|
2002-12-22 04:37:37 +08:00
|
|
|
spec->sourceRpmName = _free(spec->sourceRpmName);
|
|
|
|
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] =
|
|
|
|
freeSpec(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
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
spec->passPhrase = _free(spec->passPhrase);
|
|
|
|
spec->cookie = _free(spec->cookie);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
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
|
|
|
|
2002-12-22 10:11:05 +08:00
|
|
|
struct OpenFileInfo * newOpenFileInfo(void)
|
1998-10-07 01:34:58 +08:00
|
|
|
{
|
|
|
|
struct OpenFileInfo *ofi;
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
ofi = xmalloc(sizeof(*ofi));
|
1999-11-05 05:26:08 +08:00
|
|
|
ofi->fd = NULL;
|
1998-10-07 01:34:58 +08:00
|
|
|
ofi->fileName = NULL;
|
|
|
|
ofi->lineNum = 0;
|
|
|
|
ofi->readBuf[0] = '\0';
|
|
|
|
ofi->readPtr = NULL;
|
|
|
|
ofi->next = NULL;
|
|
|
|
|
|
|
|
return ofi;
|
|
|
|
}
|
2002-12-22 10:11:05 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Print copy of spec file, filling in Group/Description/Summary from specspo.
|
|
|
|
* @param spec spec file control structure
|
|
|
|
*/
|
|
|
|
static void
|
2007-09-21 20:23:02 +08:00
|
|
|
printNewSpecfile(rpmSpec spec)
|
2002-12-22 10:11:05 +08:00
|
|
|
{
|
|
|
|
Header h;
|
|
|
|
speclines sl = spec->sl;
|
|
|
|
spectags st = spec->st;
|
2007-12-15 01:52:11 +08:00
|
|
|
char * msgstr = NULL;
|
2002-12-22 10:11:05 +08:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if (sl == NULL || st == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < st->st_ntags; i++) {
|
|
|
|
spectag t = st->st_t + i;
|
2007-09-20 20:09:52 +08:00
|
|
|
const char * tn = rpmTagGetName(t->t_tag);
|
2002-12-22 10:11:05 +08:00
|
|
|
const char * errstr;
|
|
|
|
char fmt[1024];
|
|
|
|
|
|
|
|
fmt[0] = '\0';
|
|
|
|
if (t->t_msgid == NULL)
|
|
|
|
h = spec->packages->header;
|
|
|
|
else {
|
|
|
|
Package pkg;
|
|
|
|
char *fe;
|
|
|
|
|
|
|
|
strcpy(fmt, t->t_msgid);
|
|
|
|
for (fe = fmt; *fe && *fe != '('; fe++)
|
|
|
|
{} ;
|
|
|
|
if (*fe == '(') *fe = '\0';
|
|
|
|
h = NULL;
|
|
|
|
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
|
|
|
const char *pkgname;
|
|
|
|
h = pkg->header;
|
|
|
|
(void) headerNVR(h, &pkgname, NULL, NULL);
|
|
|
|
if (!strcmp(pkgname, fmt))
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
2002-12-22 10:11:05 +08:00
|
|
|
}
|
|
|
|
if (pkg == NULL || h == NULL)
|
|
|
|
h = spec->packages->header;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (h == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fmt[0] = '\0';
|
|
|
|
(void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}");
|
|
|
|
msgstr = _free(msgstr);
|
|
|
|
|
|
|
|
/* XXX this should use queryHeader(), but prints out tn as well. */
|
|
|
|
msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
|
|
|
|
if (msgstr == NULL) {
|
2007-11-19 22:25:24 +08:00
|
|
|
rpmlog(RPMLOG_ERR, _("can't query %s: %s\n"), tn, errstr);
|
2002-12-22 10:11:05 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(t->t_tag) {
|
|
|
|
case RPMTAG_SUMMARY:
|
|
|
|
case RPMTAG_GROUP:
|
|
|
|
sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
|
|
|
|
if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG))
|
|
|
|
continue;
|
|
|
|
{ char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr));
|
|
|
|
(void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr);
|
|
|
|
sl->sl_lines[t->t_startx] = buf;
|
|
|
|
}
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
2002-12-22 10:11:05 +08:00
|
|
|
case RPMTAG_DESCRIPTION:
|
|
|
|
for (j = 1; j < t->t_nlines; j++) {
|
|
|
|
if (*sl->sl_lines[t->t_startx + j] == '%')
|
2007-09-12 05:03:27 +08:00
|
|
|
continue;
|
2002-12-22 10:11:05 +08:00
|
|
|
sl->sl_lines[t->t_startx + j] =
|
|
|
|
_free(sl->sl_lines[t->t_startx + j]);
|
|
|
|
}
|
|
|
|
if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) {
|
|
|
|
sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr);
|
|
|
|
if (t->t_nlines > 2)
|
|
|
|
sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n");
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
2002-12-22 10:11:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
msgstr = _free(msgstr);
|
|
|
|
|
|
|
|
for (i = 0; i < sl->sl_nlines; i++) {
|
|
|
|
const char * s = sl->sl_lines[i];
|
|
|
|
if (s == NULL)
|
|
|
|
continue;
|
|
|
|
printf("%s", s);
|
|
|
|
if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
Package pkg;
|
|
|
|
char * buildRoot = NULL;
|
|
|
|
int recursing = 0;
|
|
|
|
char * passPhrase = "";
|
|
|
|
char *cookie = NULL;
|
|
|
|
int anyarch = 1;
|
|
|
|
int force = 1;
|
|
|
|
int res = 1;
|
|
|
|
int xx;
|
|
|
|
|
|
|
|
if (qva->qva_showPackage == NULL)
|
|
|
|
goto exit;
|
|
|
|
|
2007-09-12 05:03:27 +08:00
|
|
|
/* FIX: make spec abstract */
|
2002-12-22 10:11:05 +08:00
|
|
|
if (parseSpec(ts, arg, "/", buildRoot, recursing, passPhrase,
|
|
|
|
cookie, anyarch, force)
|
|
|
|
|| (spec = rpmtsSetSpec(ts, NULL)) == 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;
|
|
|
|
if (specedit) {
|
|
|
|
printNewSpecfile(spec);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next)
|
|
|
|
xx = qva->qva_showPackage(qva, ts, pkg->header);
|
|
|
|
|
|
|
|
exit:
|
|
|
|
spec = freeSpec(spec);
|
|
|
|
return res;
|
|
|
|
}
|