home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
rpm
/
build
/
vspec.c
< prev
Wrap
C/C++ Source or Header
|
1997-09-17
|
5KB
|
207 lines
/* Routine to "verify" a parsed spec file */
/***************
Here's what we do
. check for duplicate fields
. make sure a certain set of fields are present
. in subpackages, make sure a certain set of fields are present
. in subpackages, make sure certain fields are *not* present
. check for duplicate sources/patch numbers
. do some checking on the field values for legit characters
****************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "header.h"
#include "spec.h"
#include "specP.h"
#include "messages.h"
#include "rpmlib.h"
#include "stringbuf.h"
#include "misc.h"
#define EMPTY(s) ((!(s)) || (!(*(s))))
#define OOPS(s) {fprintf(stderr, "verifySpec: %s\n", s); res = 1;}
#define MUST 1
struct packageFieldsRec {
int tag;
int present;
int shouldBePresent;
};
struct fieldNamesRec {
int tag;
char *name;
};
static int checkHeaderTags(Header inh, struct packageFieldsRec *pfr);
static char *tagName(int tag);
/* This is a list of tags related to the "main" package. */
/* Only list those that must or must not be present. */
static struct packageFieldsRec packageFields[] = {
{ RPMTAG_NAME, 0, MUST },
{ RPMTAG_VERSION, 0, MUST },
{ RPMTAG_RELEASE, 0, MUST },
/* { RPMTAG_SUMMARY, 0, MUST }, */
{ RPMTAG_DESCRIPTION, 0, MUST },
{ RPMTAG_COPYRIGHT, 0, MUST },
/* { RPMTAG_PACKAGER, 0, MUST }, */
{ RPMTAG_GROUP, 0, MUST },
{ 0, 0, 0 },
};
/* This is a list of tags related to "sub" packages. */
/* Only list those that must or must not be present. */
static struct packageFieldsRec subpackageFields[] = {
{ RPMTAG_NAME, 0, MUST }, /* This is inserted automaticaly */
{ RPMTAG_SUMMARY, 0, MUST },
{ RPMTAG_DESCRIPTION, 0, MUST },
{ RPMTAG_GROUP, 0, MUST },
{ RPMTAG_NAME, 0, 0 },
{ RPMTAG_COPYRIGHT, 0, 0 },
{ RPMTAG_PACKAGER, 0, 0 },
{ RPMTAG_BUILDROOT, 0, 0 },
{ 0, 0, 0 },
};
static struct packageFieldsRec *findTag(int tag, struct packageFieldsRec *pfr)
{
struct packageFieldsRec *p = pfr;
while (p->tag) {
if (p->tag == tag)
return p;
p++;
}
return NULL;
}
static char *tagName(int tag)
{
int i = 0;
static char nameBuf[1024];
char *s;
strcpy(nameBuf, "(unknown)");
while (i < rpmTagTableSize) {
if (tag == rpmTagTable[i].val) {
strcpy(nameBuf, rpmTagTable[i].name + 7);
s = nameBuf+1;
while (*s) {
*s = tolower(*s);
s++;
}
}
i++;
}
return nameBuf;
}
static int checkHeaderTags(Header inh, struct packageFieldsRec *pfr)
{
Header h;
HeaderIterator headerIter;
int res = 0;
int_32 tag, lastTag, type, c;
void *ptr;
struct packageFieldsRec *p;
/* Sort the index, so it'll be easy to catch dups */
h = headerCopy(inh);
headerSort(h);
headerIter = headerInitIterator(h);
lastTag = 0;
while (headerNextIterator(headerIter, &tag, &type, &ptr, &c)) {
if (tag == lastTag) {
rpmError(RPMERR_BADSPEC, "Duplicate fields for : %s",
tagName(tag));
res = 1;
}
p = findTag(tag, pfr);
if (p)
p->present = 1;
lastTag = tag;
}
headerFreeIterator(headerIter);
headerFree(h);
p = pfr;
while (p->tag) {
if (p->shouldBePresent != p->present) {
rpmError(RPMERR_BADSPEC, "Field must%s be present%s: %s",
p->present ? " NOT" : "", p->present ? "" : " ",
tagName(p->tag));
res = 1;
}
p->present = 0; /* hack to clear it for next time :-) */
p++;
}
return res;
}
int verifySpec(Spec s)
{
int res = 0;
struct PackageRec *pr;
struct packageFieldsRec *fields;
char name[1024];
char *val;
if (EMPTY(s->name)) {
OOPS("No Name field");
}
/* Check each package/subpackage */
pr = s->packages;
fields = packageFields;
while (pr) {
if (! pr->subname) {
if (pr->newname) {
strcpy(name, pr->newname);
} else {
strcpy(name, s->name);
}
} else {
sprintf(name, "%s-%s", s->name, pr->subname);
}
printf("* Package: %s\n", name);
if (checkHeaderTags(pr->header, fields)) {
res = 1;
}
val = NULL;
headerGetEntry(pr->header, RPMTAG_VERSION, NULL, (void *) &val, NULL);
if (val && strchr(val, '-')) {
rpmError(RPMERR_BADSPEC, "Illegal '-' char in version: %s\n", val);
res = 1;
}
val = NULL;
headerGetEntry(pr->header, RPMTAG_RELEASE, NULL, (void *) &val, NULL);
if (val && strchr(val, '-')) {
rpmError(RPMERR_BADSPEC, "Illegal '-' char in release: %s\n", val);
res = 1;
}
pr = pr->next;
fields = subpackageFields;
}
return res;
}