--- /dev/null
+CC = gcc
+RANLIB = ranlib
+AR = ar
+STRIP = strip
+ARFLAGS = cr
+LDFLAGS =
+CFLAGS = -O2 -Wall -Wpointer-arith -Wno-char-subscripts
+INCDIR = -I. -I.. -I../build -I../lib -I../misc -I../popt -I../rpmdb -I../rpmio
+RPMDIR = ..
+DESTDIR = /usr/local
+
+XMLBUILD = rpmxmlbuild
+XMLBUILD_SRC = rpmxmlbuild.c
+XMLBUILD_OBJ = $(XMLBUILD_SRC:.c=.o)
+
+XMLLIB = libxmlrpm.a
+XMLLIB_SRC = xml2rpm.c xmlbuild.c xmlmisc.c xmlparse.c xmlstruct.c xmlverify.c
+XMLLIB_H = $(XMLLIB_SRC:.c=.h)
+XMLLIB_OBJ = $(XMLLIB_SRC:.c=.o)
+
+LIBS = $(XMLLIB) $(RPMDIR)/build/.libs/librpmbuild.a \
+ $(RPMDIR)/lib/.libs/librpm.a $(RPMDIR)/rpmdb/.libs/librpmdb.a \
+ $(RPMDIR)/rpmio/.libs/librpmio.a $(RPMDIR)/popt/.libs/libpopt.a \
+ -lz -lexpat -lbz2
+LIBDIR = -L. -L$(RPMDIR)/.libs -L/usr/lib
+
+all: $(XMLLIB) $(XMLBUILD)
+
+.c.o:
+ $(CC) $(CFLAGS) $(INCDIR) -c $?
+
+strip:
+ $(STRIP) $(XMLBUILD)
+
+install:
+ @(cp $(XMLBUILD) $(DESTDIR)/bin)
+ @(cp $(XMLLIB) $(DESTDIR)/lib)
+ @(cp $(XMLLIB_H) $(DESTDIR)/include)
+
+$(XMLLIB): $(XMLLIB_OBJ)
+ $(AR) $(ARFLAGS) $(XMLLIB) $(XMLLIB_OBJ)
+ $(RANLIB) $(XMLLIB)
+
+$(XMLBUILD): $(XMLLIB) $(XMLBUILD_OBJ)
+ $(CC) $(LDFLAGS) $(CFLAGS) $(INCDIR) -o $(XMLBUILD) $(XMLBUILD_OBJ) $(LIBS) $(LIBDIR)
+
+clean:
+ rm -rf $(XMLLIB) $(XMLBUILD) *.o core
--- /dev/null
+%attr(-,root,root) %{_usr}/man/man1/*
+%attr(-,root,root) %{_usr}/info/*
--- /dev/null
+echo "Pre-Installation script"
+/usr/sbin/ldconfig
--- /dev/null
+echo "Build script"
+./configure --prefix=/usr \
+ --with-curses \
+ --bindir=/bin
--- /dev/null
+echo "Clean script"
+rm -rf $RPM_BUILD_DIR/%{name}-%{version}
+rm -rf %{buildroot}
--- /dev/null
+%attr(-,root,root) /bin/bash
+%attr(-,root,root) /bin/sh
--- /dev/null
+echo "Install script"
+make DESTDIR=%{buildroot} install
+cd %{buildroot}/bin
+ln -sf bash sh
+rm -rf %{buildroot}/usr/info/dir
+
--- /dev/null
+echo "Prep script"
+rm -rf $RPM_BUILD_DIR/%{name}-%{version}
+rm -rf %{buildroot}
--- /dev/null
+<?xml version="1.0"?>
+<spec distribution="RPM Test" vendor="rpm.org"
+ packager="Jaco Greeff" packager-email="jaco@puxedo.org"
+ name="bash" version="2.05a" release="02test"
+ copyright="GPL"
+ url="http://www.gnu.org/software/bash/bash.html">
+
+ <source name="%{name}-%{version}.tar.bz2"
+ size="1434025" md5="c29b50db808003e39558a0f6354f4cad"
+ path="%{name}-%{version}">
+ <mirror name="GNU Main FTP Site" location="?" country="us"
+ path="ftp://ftp.gnu.org/pub/bash/%{name}-%{version}.tar.bz2" />
+ </source>
+
+ <buildrequires>
+ <require name="bash" />
+ <require name="binutils" />
+ <require name="diffutils" />
+ <require name="fileutils" />
+ <require name="gcc" />
+ <require name="glibc-devel" />
+ <require name="grep" />
+ <require name="make" />
+ <require name="sed" />
+ <require name="sh-utils" />
+ <require name="textutils" />
+ </buildrequires>
+
+ <!-- packages -->
+ <package group="System/Base" autoreqprov="no">
+ <requires>
+ <require name="glibc" />
+ </requires>
+ <summary>The Bash package contains the bash program.</summary>
+ <description>%{summary}
+Bash is the Bourne-Again SHell, which is a widely used command interpreter on Unix
+systems. Bash is a program that reads from standard input, the keyboard. A user types
+something and the program will evaluate what he has typed and do something with it,
+like running a program.</description>
+ <files list="%{name}.files.lst" />
+ </package>
+
+ <package name="bash-doc" group="Documentation/System/Base" autoreqprov="no">
+ <requires>
+ <require name="%{name}" />
+ </requires>
+ <summary>Documentation (info and man pages) for the bash package.</summary>
+ <description>%{summary}</description>
+ <pre script="%{name}-doc.pre.sh" />
+ <files list="%{name}-doc.files.lst" />
+ </package>
+
+ <!-- scripts to create the package -->
+ <prep script="%{name}.prep.sh">
+ <setup />
+ <script>echo "Prep completed"</script>
+ </prep>
+ <build script="%{name}.build.sh" />
+ <install script="%{name}.install.sh" />
+ <clean script="%{name}.clean.sh" />
+
+ <!-- changelog -->
+ <changelog>
+ <changes date="Mon Aug 26 2002" version="2.05a-02test"
+ author="Jaco Greeff" author-email="jaco@puxedo.org">
+ <change>Added setup macro to extract files</change>
+ <change>Initial version ready for jbj</change>
+ </changes>
+ <changes date="Tue Aug 20 2002" version="2.05a-01test"
+ author="Jaco Greeff" author-email="jaco@puxedo.org">
+ <change>Initial package created</change>
+ </changes>
+ </changelog>
+</spec>
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include "rpmbuild.h"
+
+#include "xmlbuild.h"
+
+#define RUN_HELP "\n Run \"rpmxmlbuild --help\" for a list of valid options."
+
+#define MASK_BP (RPMBUILD_PREP)
+#define MASK_BC (RPMBUILD_BUILD|MASK_BP)
+#define MASK_BI (RPMBUILD_INSTALL|MASK_BC)
+#define MASK_BL (RPMBUILD_FILECHECK)
+#define MASK_BB (RPMBUILD_PACKAGEBINARY|RPMBUILD_CLEAN|MASK_BI)
+#define MASK_BS (RPMBUILD_PACKAGESOURCE)
+#define MASK_BA (MASK_BB|MASK_BS)
+
+int usage()
+{
+ printf("Usage : rpmxmlbuild [options] <specfile>\n");
+ printf("General Options:\n");
+ printf("\t--help|-h|-? - Display this message\n");
+ printf("\t--quiet|-q - Don't display build information\n");
+ printf("\t--verbose|-v - Display verbose information\n");
+ printf("\n");
+ printf("Build Options:\n");
+ printf("\t-b{p|c|i|l|a|b|s} - Build spec file to the options specified.\n");
+ printf("\t (Options as per rpmbuild.)\n");
+ printf("\n");
+
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ char* szSpec = NULL;
+ int i = 0;
+ int nBuild = 0;
+ int nVerbose = 1;
+ int nQuiet = 0;
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (!strcasecmp(argv[i], "--help") ||
+ !strcasecmp(argv[i], "-h") ||
+ !strcasecmp(argv[i], "-?"))
+ return usage();
+ else if ((argv[i][1] == 'b') &&
+ (argv[i][2] != '\0') &&
+ (argv[i][3] == '\0')) {
+ switch (argv[i][2]) {
+ case 'a': nBuild = MASK_BA; break;
+ case 'b': nBuild = MASK_BB; break;
+ case 's': nBuild = MASK_BS; break;
+ case 'p': nBuild = MASK_BP; break;
+ case 'c': nBuild = MASK_BC; break;
+ case 'i': nBuild = MASK_BI; break;
+ case 'l': nBuild = MASK_BL; break;
+ default:
+ printf("error: Unknown option \"%s\". %s\n",
+ argv[i], RUN_HELP);
+ return -1;
+ }
+ }
+ else if (!strcasecmp(argv[i], "--verbose") ||
+ !strcasecmp(argv[i], "-v")) {
+ nVerbose = 1;
+ nQuiet = 0;
+ }
+ else if (!strcasecmp(argv[i], "--quiet") ||
+ !strcasecmp(argv[i], "-q")) {
+ nVerbose = 0;
+ nQuiet = 1;
+ }
+ else {
+ printf("error: Unknown option \"%s\". %s\n",
+ argv[i], RUN_HELP);
+ return -1;
+ }
+ }
+ else if (!szSpec)
+ szSpec = argv[i];
+ else {
+ printf("error: Extra characters \"%s\" on the command-line. %s\n",
+ argv[i], RUN_HELP);
+ return -2;
+ }
+ }
+
+ if (!szSpec) {
+ printf("error: No XML RPM spec specified. %s\n", RUN_HELP);
+ return -3;
+ }
+
+ rpmReadConfigFiles(NULL, NULL);
+ if (!nQuiet)
+ rpmIncreaseVerbosity();
+
+ return parseBuildXMLSpec(szSpec, nBuild, 0, nVerbose);
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rpmio.h"
+#include "header.h"
+#include "stringbuf.h"
+#include "rpmspec.h"
+#include "rpmbuild.h"
+#include "header_internal.h"
+
+#include "xml2rpm.h"
+#include "xmlstruct.h"
+
+// This is where our packaged scripts start (or the largest number
+// of the sources)
+int g_nMaxSourceNum = 511;
+
+static struct ReqComp {
+ const char* m_szCmp;
+ rpmsenseFlags m_rpmCmp;
+} sReqComp[] = {
+ {"le", RPMSENSE_LESS | RPMSENSE_EQUAL },
+ {"lt", RPMSENSE_LESS },
+ {"eq", RPMSENSE_EQUAL },
+ {"ge", RPMSENSE_GREATER | RPMSENSE_EQUAL},
+ {"gt", RPMSENSE_GREATER },
+ {NULL, 0 }
+ };
+
+Spec g_pSpec = NULL;
+const char* g_szDefLang = "C";
+
+#ifdef XML_DEBUG
+void printSourceInfo(struct Source* pSource)
+{
+ if (pSource) {
+ printf("D: Source (%08x){\n", (unsigned int)pSource);
+ printf("D: Source->fullSource (%08x): {%s}\n", (unsigned int)(pSource->fullSource), pSource->fullSource);
+ printf("D: Source->source (%08x): {%s}\n", (unsigned int)(pSource->source), pSource->source);
+ printf("D: Source->flags : {%08x}\n", pSource->flags);
+ printf("D: Source->num : {%d}\n", pSource->num);
+ printf("D: }\n");
+ }
+}
+#endif
+
+#ifdef XML_DEBUG
+void printHeaderInfo(Header pHeader)
+{
+ int i = 0;
+ int j = 0;
+ int nVal = 0;
+ indexEntry pIdx;
+ const struct headerTagTableEntry_s* pEntry;
+ char* pData;
+ int nCnt;
+ char szType[20];
+
+ if (pHeader) {
+ printf("D: Header->indexUsed : {%d}\n", pHeader->indexUsed);
+ printf("D: Header->indexAlloced : {%d}\n", pHeader->indexAlloced);
+ printf("D: Header->flags : {%d}\n", pHeader->flags);
+ printf("D: Header->nrefs : {%d}\n", pHeader->nrefs);
+ printf("D: Header->hv {\n");
+ printf("D: HV.hdrvecs : {%08x}\n", (unsigned int)(pHeader->hv.hdrvecs));
+ printf("D: HV.hdrdata : {%08x}\n", (unsigned int)(pHeader->hv.hdrdata));
+ printf("D: HV.hdrversion : {%d}\n", pHeader->hv.hdrversion);
+ printf("D: }\n");
+ printf("D: Header->blob (%08x): {\n", (unsigned int)(pHeader->blob));
+ pIdx = pHeader->index;
+ for (i = 0; i < pHeader->indexUsed; i++, pIdx++) {
+ pEntry = rpmTagTable;
+ while (pEntry->name && pEntry->val != pIdx->info.tag)
+ pEntry++;
+ nCnt = pIdx->info.count;
+ pData = pIdx->data;
+ switch (pIdx->info.type) {
+ case RPM_STRING_TYPE: sprintf(szType, "STRING"); break;
+ case RPM_STRING_ARRAY_TYPE: sprintf(szType, "STRING_ARRAY"); break;
+ case RPM_I18NSTRING_TYPE: sprintf(szType, "STRING_I18N"); break;
+ case RPM_CHAR_TYPE: sprintf(szType, "CHAR"); break;
+ case RPM_INT8_TYPE: sprintf(szType, "INT8"); break;
+ case RPM_INT16_TYPE: sprintf(szType, "INT16"); break;
+ case RPM_INT32_TYPE: sprintf(szType, "INT32"); break;
+ default: sprintf(szType, "OTHER"); break;
+ }
+ printf("D: %02d %s(%02d) %s\n", i, pEntry->name, nCnt, szType);
+ switch (pIdx->info.type) {
+ case RPM_STRING_TYPE:
+ case RPM_STRING_ARRAY_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ for (j = 0; j < nCnt; j++) {
+ if (strlen(pData))
+ printf("D: %02d {%s}\n", j, pData);
+ pData = strchr(pData, 0);
+ pData++;
+ }
+ break;
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ case RPM_INT16_TYPE:
+ case RPM_INT32_TYPE:
+ for (j = 0; j < nCnt; j++) {
+ switch (pIdx->info.type) {
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ nVal = *(((int_8*)pData)+j);
+ break;
+ case RPM_INT16_TYPE:
+ nVal = *(((uint_16*)pData)+j);
+ break;
+ case RPM_INT32_TYPE:
+ default:
+ nVal = *(((int_32*)pData)+j);
+ break;
+ }
+ printf("D: %02d {%08x}\n", j, nVal);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ printf("D: }\n");
+ }
+}
+#endif
+
+#ifdef XML_DEBUG
+void printMacroInfo(MacroContext pMacro)
+{
+ int i = 0;
+ MacroEntry pEntry = NULL;
+
+ if (pMacro) {
+ for (i = 0; i < pMacro->firstFree; i++) {
+ if ((pEntry = pMacro->macroTable[i]) &&
+ (pEntry->level >= RMIL_SPEC)) {
+ printf("D: %03d % 3d %s", i, pEntry->level,
+ pEntry->name);
+ if ((pEntry->opts) &&
+ (*pEntry->opts))
+ printf("(%s)", pEntry->opts);
+ printf("\n");
+ if ((pEntry->level >= RMIL_SPEC) &&
+ (pEntry->body) &&
+ (*pEntry->body))
+ printf("D: {%s}\n", pEntry->body);
+ }
+ }
+ }
+}
+#endif
+
+#ifdef XML_DEBUG
+void printSpecInfo(Spec pSpec)
+{
+ struct Source* pSource = NULL;
+ struct PackageStruct* pPackage = NULL;
+
+ printf("D: Spec(%08x) {\n", (unsigned int)pSpec);
+ if (pSpec) {
+ printf("D: Spec->specfile (%08x): {%s}\n", (unsigned int)(pSpec->specFile), pSpec->specFile);
+ printf("D: Spec->sourceRpmName (%08x): {%s}\n", (unsigned int)(pSpec->sourceRpmName), pSpec->sourceRpmName);
+ printf("D: Spec->buildRootURL (%08x): {%s}\n", (unsigned int)(pSpec->buildRootURL), pSpec->buildRootURL);
+ printf("D: Spec->buildSubdir (%08x): {%s}\n", (unsigned int)(pSpec->buildSubdir), pSpec->buildSubdir);
+ printf("D: Spec->rootURL (%08x): {%s}\n", (unsigned int)(pSpec->rootURL), pSpec->rootURL);
+ printf("D: Spec->BACount : {%d}\n", pSpec->BACount);
+ printf("D: Spec->recursing : {%d}\n", pSpec->recursing);
+ printf("D: Spec->force : {%d}\n", pSpec->force);
+ printf("D: Spec->anyarch : {%d}\n", pSpec->anyarch);
+ printf("D: Spec->gotBuildRootURL : {%d}\n", pSpec->gotBuildRootURL);
+ printf("D: Spec->timeCheck : {%d}\n", pSpec->timeCheck);
+ printf("D: Spec->passPhrase (%08x): {%s}\n", (unsigned int)(pSpec->passPhrase), pSpec->passPhrase);
+ printf("D: Spec->cookie (%08x): {%s}\n", (unsigned int)(pSpec->cookie), pSpec->cookie);
+ printf("D: Spec->numSources : {%d}\n", pSpec->numSources);
+ printf("D: Spec->noSource : {%d}\n", pSpec->noSource);
+ printf("D: Spec->sources : (%08x)\n", (unsigned int)(pSpec->sources));
+ pSource = pSpec->sources;
+ while (pSource) {
+ printSourceInfo(pSource);
+ pSource = pSource->next;
+ }
+ printf("D: Spec->buildRestrictions (%08x){\n", (unsigned int)(pSpec->buildRestrictions));
+ printHeaderInfo(pSpec->buildRestrictions);
+ printf("D: }\n");
+ printf("D: Spec->sourceHeader (%08x){\n", (unsigned int)(pSpec->sourceHeader));
+ printHeaderInfo(pSpec->sourceHeader);
+ printf("D: }\n");
+ printf("D: Spec->packages : {%08x}\n", (unsigned int)(pSpec->packages));
+ pPackage = pSpec->packages;
+ while (pPackage) {
+ printf("D: Package(%08x) {\n", (unsigned int)pPackage);
+ printf("D: Package->cpioList : {%08x}\n", (unsigned int)(pPackage->cpioList));
+ printf("D: Package->icon : {%08x}\n", (unsigned int)(pPackage->icon));
+ printf("D: Package->autoReq : {%d}\n", pPackage->autoReq);
+ printf("D: Package->autoProv : {%d}\n", pPackage->autoProv);
+ printf("D: Package->preInFile (%08x): {%s}\n", (unsigned int)(pPackage->preInFile), pPackage->preInFile);
+ printf("D: Package->postInFile (%08x): {%s}\n", (unsigned int)(pPackage->postInFile), pPackage->postInFile);
+ printf("D: Package->preUnFile (%08x): {%s}\n", (unsigned int)(pPackage->preUnFile), pPackage->preUnFile);
+ printf("D: Package->postUnFile (%08x): {%s}\n", (unsigned int)(pPackage->postUnFile), pPackage->postUnFile);
+ printf("D: Package->triggerFiles : {%08x}\n", (unsigned int)(pPackage->triggerFiles));
+ printf("D: Package->fileFile (%08x): {%s}\n", (unsigned int)(pPackage->fileFile), pPackage->fileFile);
+ printf("D: Package->fileFile (%08x): {%s}\n", (unsigned int)(pPackage->fileList), pPackage->fileList ? getStringBuf(pPackage->fileList) : NULL);
+ printf("D: Package->header (%08x){\n", (unsigned int)(pPackage->header));
+ printHeaderInfo(pPackage->header);
+ printf("D: }\n");
+ pPackage = pPackage->next;
+ printf("D: }\n");
+ }
+ printf("D: Spec->macros (%08x){\n", (unsigned int)(pSpec->macros));
+ printMacroInfo(pSpec->macros);
+ printf("D: }\n");
+ printf("D: Spec->prep (%08x): {%s}\n", (unsigned int)(pSpec->prep), pSpec->prep ? getStringBuf(pSpec->prep) : NULL);
+ printf("D: Spec->build (%08x): {%s}\n", (unsigned int)(pSpec->build), pSpec->build ? getStringBuf(pSpec->build) : NULL);
+ printf("D: Spec->install (%08x): {%s}\n", (unsigned int)(pSpec->install), pSpec->install ? getStringBuf(pSpec->install) : NULL);
+ printf("D: Spec->clean (%08x): {%s}\n", (unsigned int)(pSpec->clean), pSpec->clean ? getStringBuf(pSpec->clean) : NULL);
+ }
+ printf("D: }\n");
+}
+#endif
+
+void createRPMSource(const char* szName, int nNum,
+ Spec pSpec, int nType)
+{
+ struct Source* pSrc = NULL;
+ struct Source* pPrev = NULL;
+ char szTmpName[20];
+ char szPre[3];
+ char szType[7];
+
+ if (!szName || !pSpec)
+ return;
+
+ if ((nType & RPMBUILD_ISNO) == RPMBUILD_ISNO) {
+ pSpec->noSource++;
+ sprintf(szPre, "NO");
+ }
+ else {
+ pSpec->numSources++;
+ szPre[0] = '\0';
+ }
+ pSrc = malloc(sizeof(struct Source));
+ pSrc->fullSource = NULL;
+ newStrEx(szName, &(pSrc->fullSource));
+ if (!(pSrc->source = strrchr(pSrc->fullSource, '/')))
+ pSrc->source = pSrc->fullSource;
+ else
+ pSrc->source++;
+
+ pSrc->num = nNum;
+ pSrc->flags = nType;
+ pSrc->next = NULL;
+ if ((pPrev = pSpec->sources)) {
+ while (pPrev->next)
+ pPrev = pPrev->next;
+ pPrev->next = pSrc;
+ }
+ else
+ pSpec->sources = pSrc;
+
+ if ((nType & RPMBUILD_ISSOURCE) == RPMBUILD_ISSOURCE)
+ sprintf(szType, "SOURCE");
+ else
+ sprintf(szType, "PATCH");
+ sprintf(szTmpName, "%s%s%d", szPre, szType, nNum);
+ addMacro(pSpec->macros, szTmpName, NULL, pSrc->fullSource, RMIL_SPEC);
+ sprintf(szTmpName, "%s%sURL%d", szPre, szType, nNum);
+ addMacro(pSpec->macros, szTmpName, NULL, pSrc->source, RMIL_SPEC);
+
+ if (nNum > g_nMaxSourceNum)
+ g_nMaxSourceNum = nNum;
+}
+
+void convertXMLSource(const t_structXMLSource* pXMLSrc,
+ Spec pSpec, int nType)
+{
+ if (!pXMLSrc || !pSpec)
+ return;
+
+ createRPMSource(pXMLSrc->m_szName, pXMLSrc->m_nNum, pSpec, nType);
+ convertXMLSource(pXMLSrc->m_pNext, pSpec, nType);
+}
+
+StringBuf scriptsToStringBuf(const t_structXMLScripts* pScripts,
+ Spec pSpec)
+{
+ StringBuf pSb = NULL;
+ t_structXMLScript* pScript = NULL;
+ char* szTmp = NULL;
+
+ if (pScripts) {
+ pSb = newStringBuf();
+ if ((pScripts->m_szScript) &&
+ (szTmp = fileToStr(pScripts->m_szScript, NULL))) {
+ appendLineStringBuf(pSb, szTmp);
+ freeStr(&(szTmp));
+ createRPMSource(pScripts->m_szScript, g_nMaxSourceNum+1,
+ pSpec, RPMBUILD_ISSOURCE);
+ }
+ pScript = pScripts->m_pScripts;
+ while (pScript) {
+ if ((pScript->m_szScript) &&
+ (szTmp = fileToStr(pScript->m_szScript, NULL))) {
+ appendLineStringBuf(pSb, szTmp);
+ freeStr(&(szTmp));
+ createRPMSource(pScript->m_szScript, g_nMaxSourceNum+1,
+ pSpec, RPMBUILD_ISSOURCE);
+ }
+ if (pScript->m_szEntry)
+ appendLineStringBuf(pSb, pScript->m_szEntry);
+ pScript = pScript->m_pNext;
+ }
+ }
+
+ return pSb;
+}
+
+void convertXMLScripts(const t_structXMLScripts* pScripts,
+ struct PackageStruct* pPkg,
+ Spec pSpec,
+ int nScript, int nInterpreter)
+{
+ StringBuf pSb = NULL;
+
+ if (!pScripts || !pPkg)
+ return;
+
+ if ((pSb = scriptsToStringBuf(pScripts, pSpec))) {
+ headerAddEntry(pPkg->header,
+ nScript, RPM_STRING_TYPE,
+ getStringBuf(pSb), 1);
+ freeStringBuf(pSb);
+ }
+ if (pScripts->m_szInterpreter)
+ headerAddEntry(pPkg->header,
+ nInterpreter, RPM_STRING_TYPE,
+ pScripts->m_szInterpreter, 1);
+}
+
+void convertXMLPackage(const t_structXMLPackage* pXMLPkg,
+ const t_structXMLSpec* pXMLSpec,
+ Spec pSpec)
+{
+ struct PackageStruct* pPkg = NULL;
+ char* szPlatform = NULL;
+ char* szArch = NULL;
+ char* szOs = NULL;
+ char* szTmp = NULL;
+
+ if (!pXMLPkg || !pSpec)
+ return;
+
+ pPkg = newPackage(pSpec);
+ pPkg->autoReq = pXMLPkg->m_nAutoRequire;
+ pPkg->autoProv = pXMLPkg->m_nAutoProvide;
+ pPkg->header = headerNew();
+
+ szPlatform = rpmExpand("%{_target_platform}", NULL);
+ szArch = rpmExpand("%{_target_cpu}", NULL);
+ szOs = rpmExpand("%{_target_os}", NULL);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_OS, RPM_STRING_TYPE, szOs, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_ARCH, RPM_STRING_TYPE, szArch, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_RHNPLATFORM, RPM_STRING_TYPE, szArch, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_PLATFORM, RPM_STRING_TYPE, szPlatform, 1);
+ _free(szPlatform);
+ _free(szArch);
+ _free(szOs);
+
+ if (pXMLPkg->m_szName)
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_NAME,
+ RPM_STRING_TYPE, pXMLPkg->m_szName, 1);
+ else
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_NAME,
+ RPM_STRING_TYPE, pXMLSpec->m_szName, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_VERSION,
+ RPM_STRING_TYPE, pXMLSpec->m_szVersion, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_RELEASE,
+ RPM_STRING_TYPE, pXMLSpec->m_szRelease, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_GROUP,
+ RPM_STRING_TYPE, pXMLPkg->m_szGroup, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_RELEASE,
+ RPM_STRING_TYPE, pXMLSpec->m_szRelease, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_LICENSE,
+ RPM_STRING_TYPE, pXMLSpec->m_szCopyright, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_URL,
+ RPM_STRING_TYPE, pXMLSpec->m_szURL, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_DISTRIBUTION,
+ RPM_STRING_TYPE, pXMLSpec->m_szDistribution, 1);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_VENDOR,
+ RPM_STRING_TYPE, pXMLSpec->m_szVendor, 1);
+ headerAddOrAppendEntry(pPkg->header, HEADER_I18NTABLE,
+ RPM_STRING_ARRAY_TYPE, &g_szDefLang, 1);
+ headerAddI18NString(pPkg->header, RPMTAG_SUMMARY,
+ pXMLPkg->m_szSummary, g_szDefLang);
+ headerAddI18NString(pPkg->header, RPMTAG_DESCRIPTION,
+ pXMLPkg->m_szSummary, g_szDefLang);
+
+ if (pXMLSpec->m_szPackagerEmail || pXMLSpec->m_szPackager) {
+ szTmp = malloc(strlen(pXMLSpec->m_szPackager)+strlen(pXMLSpec->m_szPackagerEmail)+4);
+ if (pXMLSpec->m_szPackagerEmail && pXMLSpec->m_szPackager)
+ sprintf(szTmp, "%s <%s>", pXMLSpec->m_szPackager,
+ pXMLSpec->m_szPackagerEmail);
+ else
+ sprintf(szTmp, "%s", pXMLSpec->m_szPackager ? pXMLSpec->m_szPackager : pXMLSpec->m_szPackagerEmail);
+ headerAddOrAppendEntry(pPkg->header, RPMTAG_PACKAGER,
+ RPM_STRING_TYPE, szTmp, 1);
+ free(szTmp);
+ }
+
+ if (pXMLPkg->m_pFiles)
+ pPkg->fileList = fileToStrBuf(pXMLPkg->m_pFiles->m_szFileList, NULL);
+
+ convertXMLScripts(pXMLPkg->m_pPre, pPkg, pSpec,
+ RPMTAG_PREIN, RPMTAG_PREINPROG);
+ convertXMLScripts(pXMLPkg->m_pPost, pPkg, pSpec,
+ RPMTAG_POSTIN, RPMTAG_POSTINPROG);
+ convertXMLScripts(pXMLPkg->m_pPreUn, pPkg, pSpec,
+ RPMTAG_PREUN, RPMTAG_PREUNPROG);
+ convertXMLScripts(pXMLPkg->m_pPostUn, pPkg, pSpec,
+ RPMTAG_POSTUN, RPMTAG_POSTUNPROG);
+ convertXMLScripts(pXMLPkg->m_pVerify, pPkg, pSpec,
+ RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG);
+
+ convertXMLPackage(pXMLPkg->m_pNext, pXMLSpec, pSpec);
+}
+
+void convertXMLMacro(const t_structXMLMacro* pMacro,
+ Spec pSpec)
+{
+ if (!pMacro || !pSpec)
+ return;
+
+ addMacroEx(pMacro->m_szName, (char**)&(pMacro->m_szValue), 1);
+ convertXMLMacro(pMacro->m_pNext, pSpec);
+}
+
+void convertXMLBuildRequires(const t_structXMLSpec* pXMLSpec,
+ Spec pSpec)
+{
+ t_structXMLRequire* pRequire = NULL;
+ char* szTmp = NULL;
+ char* szVal = NULL;
+ int i = 0;
+ int nFlags = 0;
+ int nIndex = 0;
+ char* szVersion = NULL;
+
+ pRequire = pXMLSpec->m_pBuildRequires;
+ szVal = malloc(1);
+ szVal[0] = '\0';
+ while (pRequire) {
+ if (pRequire->m_szName) {
+ szTmp = malloc(strlen(szVal)+strlen(pRequire->m_szName)+2);
+ if (strlen(szVal))
+ sprintf(szTmp, "%s", pRequire->m_szName);
+ else
+ sprintf(szTmp, "%s %s", szVal, pRequire->m_szName);
+ free(szVal);
+ szVal = szTmp;
+ }
+ szVersion = NULL;
+ nFlags = 0;
+ if (pRequire->m_szCompare && pRequire->m_szVersion) {
+ for (i = 0; sReqComp[i].m_szCmp; i++)
+ if (!strcasecmp(sReqComp[i].m_szCmp, pRequire->m_szCompare)) {
+ nFlags = (sReqComp[i].m_rpmCmp | RPMSENSE_ANY) & ~RPMSENSE_SENSEMASK;
+ szVersion = pRequire->m_szVersion;
+ }
+ }
+ addReqProv(pSpec, pSpec->buildRestrictions, nFlags,
+ pRequire->m_szName, pRequire->m_szVersion, nIndex);
+ addReqProv(pSpec, pSpec->sourceHeader, nFlags,
+ pRequire->m_szName, pRequire->m_szVersion, nIndex);
+ pRequire = pRequire->m_pNext;
+ nIndex++;
+ }
+ if (pXMLSpec->m_szPackagerEmail || pXMLSpec->m_szPackager) {
+ szTmp = malloc(strlen(pXMLSpec->m_szPackager)+strlen(pXMLSpec->m_szPackagerEmail)+4);
+ if (pXMLSpec->m_szPackagerEmail && pXMLSpec->m_szPackager)
+ sprintf(szTmp, "%s <%s>", pXMLSpec->m_szPackager, pXMLSpec->m_szPackagerEmail);
+ else
+ sprintf(szTmp, "%s", pXMLSpec->m_szPackager ? pXMLSpec->m_szPackager : pXMLSpec->m_szPackagerEmail);
+ headerAddOrAppendEntry(pSpec->packages->header, RPMTAG_PACKAGER,
+ RPM_STRING_TYPE, szTmp, 1);
+ free(szTmp);
+ }
+ free(szVal);
+}
+
+Spec toRPMStruct(const t_structXMLSpec* pXMLSpec)
+{
+ Spec pSpec = NULL;
+ char* szTmp = NULL;
+
+ if (!pXMLSpec)
+ return NULL;
+
+ pSpec = g_pSpec;
+ newStrEx(pXMLSpec->m_szSpecName, (char**)&(pSpec->specFile));
+ if (pXMLSpec->m_pPackages) {
+ addMacroEx("group",
+ (char**)&(pXMLSpec->m_pPackages->m_szGroup), RMIL_SPEC);
+ addMacroEx("summary",
+ (char**)&(pXMLSpec->m_pPackages->m_szSummary), RMIL_SPEC);
+ }
+ pSpec->gotBuildRootURL = 1;
+
+ newStrEx(pXMLSpec->m_szBuildRootDir, (char**)(&(pSpec->buildRootURL)));
+ newStrEx(pXMLSpec->m_szBuildSubdir, (char**)(&(pSpec->buildSubdir)));
+ newStrEx(pXMLSpec->m_szRootDir, (char**)(&(pSpec->rootURL)));
+
+ convertXMLSource(pXMLSpec->m_pSources, pSpec, RPMBUILD_ISSOURCE);
+ convertXMLSource(pXMLSpec->m_pPatches, pSpec, RPMBUILD_ISPATCH);
+
+ pSpec->prep = scriptsToStringBuf(pXMLSpec->m_pPrep, pSpec);
+ pSpec->build = scriptsToStringBuf(pXMLSpec->m_pBuild, pSpec);
+ pSpec->install = scriptsToStringBuf(pXMLSpec->m_pInstall, pSpec);
+ pSpec->clean = scriptsToStringBuf(pXMLSpec->m_pClean, pSpec);
+
+ convertXMLPackage(pXMLSpec->m_pPackages, pXMLSpec, pSpec);
+
+ initSourceHeader(pSpec);
+ if (pXMLSpec->m_szPackagerEmail || pXMLSpec->m_szPackager) {
+ szTmp = malloc(strlen(pXMLSpec->m_szPackager)+strlen(pXMLSpec->m_szPackagerEmail)+4);
+ if (pXMLSpec->m_szPackagerEmail && pXMLSpec->m_szPackager)
+ sprintf(szTmp, "%s <%s>", pXMLSpec->m_szPackager,
+ pXMLSpec->m_szPackagerEmail);
+ else
+ sprintf(szTmp, "%s", pXMLSpec->m_szPackager ? pXMLSpec->m_szPackager : pXMLSpec->m_szPackagerEmail);
+ headerAddOrAppendEntry(pSpec->sourceHeader, RPMTAG_PACKAGER,
+ RPM_STRING_TYPE, szTmp, 1);
+ free(szTmp);
+ }
+
+ pSpec->buildRestrictions = headerNew();
+ convertXMLBuildRequires(pXMLSpec, pSpec);
+
+#ifdef XML_DEBUG
+ printSpecInfo(pSpec);
+#endif
+
+ return pSpec;
+}
--- /dev/null
+#ifndef _XML_TO_RPM_H_
+#define _XML_TO_RPM_H_
+
+#include "rpmspec.h"
+
+#include "xmlstruct.h"
+
+Spec toRPMStruct(const t_structXMLSpec* pXMLSpec);
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include "rpmio.h"
+#include "header.h"
+#include "stringbuf.h"
+#include "rpmspec.h"
+#include "rpmbuild.h"
+#include "header_internal.h"
+
+#include "xml2rpm.h"
+#include "xmlbuild.h"
+#include "xmlparse.h"
+#include "xmlstruct.h"
+
+extern Spec g_pSpec;
+
+int buildXMLSpec(t_structXMLSpec* pXMLSpec,
+ int nWhat,
+ int nTest)
+{
+ Spec pRPMSpec = NULL;
+ int nRet = 0;
+
+ if ((pRPMSpec = toRPMStruct(pXMLSpec))) {
+ nRet = buildSpec(pRPMSpec, nWhat, nTest);
+ if (g_pSpec)
+ freeSpec(g_pSpec);
+ g_pSpec = NULL;
+ }
+ else
+ nRet = -1;
+
+ return nRet;
+}
+
+int parseBuildXMLSpec(const char* szXMLSpec,
+ int nWhat,
+ int nTest,
+ int nVerbose)
+{
+ t_structXMLSpec* pXMLSpec = NULL;
+ int nRet = 0;
+
+ if ((pXMLSpec = parseXMLSpec(szXMLSpec, nVerbose))) {
+ nRet = buildXMLSpec(pXMLSpec, nWhat, 0);
+ freeXMLSpec(&pXMLSpec);
+ }
+ else
+ nRet = -1;
+
+ return nRet;
+}
--- /dev/null
+#ifndef _XML_BUILD_H_
+#define _XML_BUILD_H_
+
+#include "xmlstruct.h"
+
+int buildXMLSpec(t_structXMLSpec* pXMLSpec,
+ int nWhat,
+ int nTest);
+
+int parseBuildXMLSpec(const char* szXMLSpec,
+ int nWhat,
+ int nTest,
+ int nVerbose);
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rpmio.h"
+#include "header.h"
+#include "stringbuf.h"
+#include "rpmspec.h"
+#include "rpmbuild.h"
+#include "header_internal.h"
+
+#include "xmlmisc.h"
+
+extern Spec g_pSpec;
+
+void freeStr(char** pszStr)
+{
+ if (*pszStr != NULL)
+ free(*pszStr);
+ *pszStr = NULL;
+}
+
+char* newStr(const char* szValue,
+ char** pszStr)
+{
+ freeStr(pszStr);
+ if (szValue) {
+ *pszStr = malloc((strlen(szValue)+1)*sizeof(char));
+ sprintf(*pszStr, "%s", szValue);
+ }
+
+ return *pszStr;
+}
+
+char* newStrEx(const char* szValue,
+ char** pszStr)
+{
+ char* szBuffer = NULL;
+ int nLen;
+
+ if (g_pSpec == NULL)
+ return newStr(szValue, pszStr);
+
+ if (szValue) {
+ nLen = (strlen(szValue)*2)+1024;
+ szBuffer = malloc(nLen+1);
+ sprintf(szBuffer, "%s", szValue);
+ expandMacros(g_pSpec, g_pSpec->macros, szBuffer, nLen);
+ freeStr(pszStr);
+ newStr(szBuffer, pszStr);
+ free(szBuffer);
+ }
+ else
+ freeStr(pszStr);
+
+ return *pszStr;
+}
+
+void addMacroEx(char* szName, char** pszVar, int nLevel)
+{
+ if (g_pSpec && g_pSpec->macros)
+ addMacro(g_pSpec->macros, szName, NULL, newStrEx(*pszVar, pszVar), nLevel);
+}
+
+int strToBool(const char* szBool)
+{
+ int nBool = 0;
+
+ if (!strcasecmp(szBool, "on"))
+ nBool = 1;
+ else if (!strcasecmp(szBool, "off"))
+ nBool = 0;
+ else if (!strcasecmp(szBool, "true"))
+ nBool = 1;
+ else if (!strcasecmp(szBool, "false"))
+ nBool = 0;
+ else if (!strcasecmp(szBool, "yes"))
+ nBool = 1;
+ else if (!strcasecmp(szBool, "no"))
+ nBool = 0;
+ else if (!strcasecmp(szBool, "1"))
+ nBool = 1;
+ else if (!strcasecmp(szBool, "0"))
+ nBool = 0;
+
+ return nBool;
+}
+
+StringBuf fileToStrBuf(const char* szFile,
+ const char* szPrepend)
+{
+ FILE* fIn;
+ StringBuf pSb = NULL;
+ StringBuf pTmp;
+ int nLen;
+ char szBuffer[1025];
+ char* szTmp = NULL;
+ char** szaLines, **szaStart;
+
+ if ((szFile) &&
+ (fIn = fopen(szFile, "r"))) {
+ pTmp = newStringBuf();
+ if (szPrepend)
+ appendLineStringBuf(pTmp, szPrepend);
+ while (!feof(fIn)) {
+ nLen = fread(szBuffer, sizeof(char), 1024, fIn);
+ szBuffer[nLen] = '\0';
+ appendStringBuf(pTmp, szBuffer);
+ }
+ appendLineStringBuf(pTmp, "");
+ fclose(fIn);
+ szaStart = splitString(getStringBuf(pTmp), strlen(getStringBuf(pTmp)), '\n');
+ //newStrEx(getStringBuf(pSb), &szTmp);
+ //freeStringBuf(pSb);
+
+ pSb = newStringBuf();
+ for (szaLines = szaStart; *szaLines; szaLines++) {
+ if (!strncmp(*szaLines, "%setup", sizeof("%setup")-1)) {
+ //doSetupMacro(spec, *sazLines);
+ }
+ else if (!strncmp(*szaLines, "%patch", sizeof("%patch")-1)) {
+ //doPatchMacro(spec, *szaLines);
+ }
+ else {
+ newStrEx(*szaLines, &szTmp);
+ appendLineStringBuf(pSb, szTmp);
+ freeStr(&szTmp);
+ }
+ }
+ //appendStringBuf(pSb, szTmp);
+ //freeStr(&szTmp);
+ freeSplitString(szaStart);
+ freeStringBuf(pTmp);
+ }
+
+ return pSb;
+}
+
+char* fileToStr(const char* szFile,
+ const char* szPrepend)
+{
+ StringBuf pSb;
+ char* szRet = NULL;
+
+ if ((pSb = fileToStrBuf(szFile, szPrepend))) {
+ newStr(getStringBuf(pSb), &szRet);
+ freeStringBuf(pSb);
+ }
+
+ return szRet;
+}
--- /dev/null
+#ifndef _XML_MISC_H_
+#define _XML_MISC_H_
+
+#include "stringbuf.h"
+
+void freeStr(char** pszStr);
+char* newStr(const char* szValue,
+ char** pszStr);
+char* newStrEx(const char* szValue,
+ char** pszStr);
+
+void addMacroEx(char* szName,
+ char** pszVar,
+ int nLevel);
+
+int strToBool(const char* szBool);
+
+StringBuf fileToStrBuf(const char* szFile,
+ const char* szPrepend);
+char* fileToStr(const char* szFile,
+ const char* szPrepend);
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include <expat.h>
+
+#include "rpmbuild.h"
+
+#include "xmlparse.h"
+#include "xmlmisc.h"
+#include "xmlverify.h"
+#include "xmlstruct.h"
+
+void handleXMLStartLevel0(t_structXMLParse* pParse)
+{
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_SPEC:
+ pParse->m_pSpec = newXMLSpec(pParse->m_pAttrs, pParse->m_szXMLFile);
+ break;
+ default:
+ fprintf(stderr, "warning: %s(%d): Ignoring tag \"%s\" on level %d. (Function not implemented)\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_szName,
+ pParse->m_nLevel);
+ pParse->m_nWarnings++;
+ break;
+ }
+}
+
+/*f (!strcasecmp(szName, "pre")) {
+ pPkg = getLastXMLPackage(pParse->m_pSpec->m_pPackages);
+ pPkg->m_pPre = newXMLScript(attrToStruct(szaAttrs, &(pParse->m_pAttrs)));
+ }*/
+void handleXMLStartLevel1(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_MACRO:
+ addXMLMacro(pParse->m_pAttrs, &(pSpec->m_pMacros));
+ break;
+ case TAGVAL_SOURCE:
+ addXMLSource(pParse->m_pAttrs, &(pSpec->m_pSources));
+ break;
+ case TAGVAL_PATCH:
+ addXMLSource(pParse->m_pAttrs, &(pSpec->m_pPatches));
+ break;
+ case TAGVAL_PACKAGE:
+ addXMLPackage(pParse->m_pAttrs, &(pSpec->m_pPackages));
+ break;
+ case TAGVAL_PREP:
+ pSpec->m_pPrep = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_BUILD:
+ pSpec->m_pBuild = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_INSTALL:
+ pSpec->m_pInstall = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_CLEAN:
+ pSpec->m_pClean = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_BUILDREQUIRES:
+ case TAGVAL_CHANGELOG:
+ // we don't need to do anything
+ break;
+ default:
+ fprintf(stderr, "warning: %s(%d): Ignoring tag \"%s\" on level %d. (Function not implemented)\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_szName,
+ pParse->m_nLevel);
+ pParse->m_nWarnings++;
+ break;
+ }
+}
+
+void handleXMLStartLevel2(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+ t_structXMLSource* pSource = NULL;
+ t_structXMLPackage* pPkg = NULL;
+ t_structXMLScript* pScript = NULL;
+ t_structXMLAttr* pAttr = NULL;
+ StringBuf pSb = NULL;
+ int nNum = 0;
+ int nLevel = 0;
+ char* szTmp = NULL;
+ char* szPath = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_SOURCEMIRROR:
+ pSource = getLastXMLSource(pSpec->m_pSources);
+ addXMLMirror(pParse->m_pAttrs, &(pSource->m_pMirrors));
+ break;
+ case TAGVAL_PATCHMIRROR:
+ pSource = getLastXMLSource(pSpec->m_pPatches);
+ addXMLMirror(pParse->m_pAttrs, &(pSource->m_pMirrors));
+ break;
+ case TAGVAL_BUILDREQUIRE:
+ addXMLRequire(pParse->m_pAttrs, &(pSpec->m_pBuildRequires));
+ break;
+ case TAGVAL_CHANGES:
+ addXMLChanges(pParse->m_pAttrs, &(pSpec->m_pChangelog));
+ break;
+ case TAGVAL_PRE:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ pPkg->m_pPre = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_POST:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ pPkg->m_pPost = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_PREUN:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ pPkg->m_pPreUn = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_POSTUN:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ pPkg->m_pPostUn = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_VERIFY:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ pPkg->m_pVerify = newXMLScripts(pParse->m_pAttrs);
+ break;
+ case TAGVAL_FILES:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ pPkg->m_pFiles = newXMLFiles(pParse->m_pAttrs);
+ break;
+ case TAGVAL_SCRIPT: // prep, build, install, clean
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel-1]].m_nValue) {
+ case TAGVAL_PREP:
+ addXMLScript(pParse->m_pAttrs,
+ &(pSpec->m_pPrep->m_pScripts));
+ break;
+ case TAGVAL_BUILD:
+ addXMLScript(pParse->m_pAttrs,
+ &(pSpec->m_pBuild->m_pScripts));
+ break;
+ case TAGVAL_INSTALL:
+ addXMLScript(pParse->m_pAttrs,
+ &(pSpec->m_pInstall->m_pScripts));
+ break;
+ case TAGVAL_CLEAN:
+ addXMLScript(pParse->m_pAttrs,
+ &(pSpec->m_pClean->m_pScripts));
+ break;
+ default:
+ break;
+ }
+ break;
+ case TAGVAL_SETUPMACRO:
+ pScript = addXMLScript(NULL, &(pSpec->m_pPrep->m_pScripts));
+ if ((pAttr = getXMLAttr("source", pParse->m_pAttrs)))
+ attrSetInt(pAttr, "source", &nNum);
+ if ((pAttr = getXMLAttr("path", pParse->m_pAttrs)))
+ attrSetStr(pAttr, "path", &szPath);
+ else
+ newStrEx(pParse->m_pSpec->m_szBuildSubdir, &szPath);
+ if ((pSource = getXMLSource(nNum, pSpec->m_pSources))) {
+ nNum = strlen(pSource->m_szName);
+ szTmp = pSource->m_szName+(nNum-3);
+ pSb = newStringBuf();
+ nNum = 1;
+ if (!strcasecmp(szTmp, "bz2")) {
+ szTmp = NULL;
+ newStrEx("%{_bzip2bin} -dc ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ }
+ else if (!strcasecmp(szTmp, ".gz")) {
+ szTmp = NULL;
+ newStrEx("%{_gzipbin} -dc ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ }
+ else if (!strcasecmp(szTmp, "zip")) {
+ szTmp = NULL;
+ newStrEx("%{_unzipbin} ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ nNum = 0;
+ }
+ else if (!strcasecmp(szTmp, "tar")) {
+ szTmp = NULL;
+ newStrEx("cat ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ }
+ else {
+ fprintf(stderr, "error: %s(%d): Invalid compressed format for source in \"setup\" script.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser));
+ pParse->m_nErrors++;
+ freeStr(&szPath);
+ freeStringBuf(pSb);
+ return;
+ }
+ if (nNum && pParse->m_nVerbose)
+ appendStringBuf(pSb, " | tar -xvvf -");
+ else if (nNum)
+ appendStringBuf(pSb, " | tar -xf -");
+ appendLineStringBuf(pSb, "");
+ appendLineStringBuf(pSb, "STATUS=$?");
+ appendLineStringBuf(pSb, "if [ $STATUS -ne 0 ]; then");
+ appendLineStringBuf(pSb, " exit $STATUS");
+ appendLineStringBuf(pSb, "fi");
+ appendStringBuf(pSb, "cd ");
+ appendStringBuf(pSb, szPath);
+ appendLineStringBuf(pSb, "");
+ newStr(getStringBuf(pSb), (char**)&(pScript->m_szEntry));
+ freeStringBuf(pSb);
+ freeStr(&szTmp);
+ freeStr(&szPath);
+ }
+ else {
+ freeStr(&szPath);
+ fprintf(stderr, "error: %s(%d): Invalid \"setup\" script. Source not available.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser));
+ pParse->m_nErrors++;
+ }
+ break;
+ case TAGVAL_PATCHMACRO:
+ pScript = addXMLScript(NULL, &(pSpec->m_pPrep->m_pScripts));
+ if ((pAttr = getXMLAttr("patch", pParse->m_pAttrs)))
+ attrSetInt(pAttr, "patch", &nNum);
+ if ((pAttr = getXMLAttr("path", pParse->m_pAttrs)))
+ attrSetStr(pAttr, "path", &szPath);
+ else
+ newStrEx(pParse->m_pSpec->m_szBuildSubdir, &szPath);
+ if ((pAttr = getXMLAttr("level", pParse->m_pAttrs)))
+ attrSetInt(pAttr, "level", &nLevel);
+ if ((pSource = getXMLSource(nNum, pSpec->m_pPatches))) {
+ pSb = newStringBuf();
+ newStrEx("cd %{_builddir}", &szTmp);
+ appendLineStringBuf(pSb, szTmp);
+ freeStr(&szTmp);
+ appendStringBuf(pSb, "cd ");
+ appendStringBuf(pSb, szPath);
+ appendLineStringBuf(pSb, "");
+ nNum = strlen(pSource->m_szName);
+ szTmp = pSource->m_szName+(nNum-3);
+ nNum = 1;
+ if (!strcasecmp(szTmp, "bz2")) {
+ szTmp = NULL;
+ newStrEx("%{_bzip2bin} -dc ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ }
+ else if (!strcasecmp(szTmp, ".gz")) {
+ szTmp = NULL;
+ newStrEx("%{_gzipbin} -dc ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ }
+ else {
+ szTmp = NULL;
+ newStrEx("cat ", &szTmp);
+ appendStringBuf(pSb, szTmp);
+ appendStringBuf(pSb, pSource->m_szName);
+ }
+ freeStr(&szTmp);
+ szTmp = malloc(strlen(" > patch -p1234567890 -s ")+strlen(pSource->m_szName)+1);
+ sprintf(szTmp, " | patch -p%d -s", nLevel);
+ appendStringBuf(pSb, szTmp);
+ appendLineStringBuf(pSb, "");
+ appendLineStringBuf(pSb, "STATUS=$?");
+ appendLineStringBuf(pSb, "if [ $STATUS -ne 0 ]; then");
+ appendLineStringBuf(pSb, " exit $STATUS");
+ appendLineStringBuf(pSb, "fi");
+ appendLineStringBuf(pSb, "");
+ newStr(getStringBuf(pSb), (char**)&(pScript->m_szEntry));
+ freeStringBuf(pSb);
+ freeStr(&szTmp);
+ freeStr(&szPath);
+ }
+ else {
+ freeStr(&szPath);
+ fprintf(stderr, "error: %s(%d): Invalid \"patch\" script. Patch not available.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser));
+ pParse->m_nErrors++;
+ }
+ break;
+ case TAGVAL_SUMMARY:
+ case TAGVAL_DESCRIPTION:
+ case TAGVAL_REQUIRES:
+ // we don't need to do anything
+ break;
+ default:
+ fprintf(stderr, "warning: %s(%d): Ignoring tag \"%s\" on level %d. (Function not implemented)\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_szName,
+ pParse->m_nLevel);
+ pParse->m_nWarnings++;
+ break;
+ }
+}
+
+void handleXMLStartLevel3(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+ t_structXMLPackage* pPkg = NULL;
+ t_structXMLChanges* pChanges = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_REQUIRE:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ addXMLRequire(pParse->m_pAttrs, &(pPkg->m_pRequires));
+ break;
+ case TAGVAL_CHANGE:
+ pChanges = getLastXMLChanges(pSpec->m_pChangelog);
+ addXMLChange(pParse->m_pAttrs, &(pChanges->m_pChanges));
+ break;
+ case TAGVAL_SCRIPT: // pre, post, ...
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel-1]].m_nValue) {
+ case TAGVAL_PRE:
+ addXMLScript(pParse->m_pAttrs,
+ &(pPkg->m_pPre->m_pScripts));
+ break;
+ case TAGVAL_POST:
+ addXMLScript(pParse->m_pAttrs,
+ &(pPkg->m_pPost->m_pScripts));
+ break;
+ case TAGVAL_PREUN:
+ addXMLScript(pParse->m_pAttrs,
+ &(pPkg->m_pPreUn->m_pScripts));
+ break;
+ case TAGVAL_POSTUN:
+ addXMLScript(pParse->m_pAttrs,
+ &(pPkg->m_pPostUn->m_pScripts));
+ break;
+ case TAGVAL_VERIFY:
+ addXMLScript(pParse->m_pAttrs,
+ &(pPkg->m_pVerify->m_pScripts));
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ fprintf(stderr, "warning: %s(%d): Ignoring tag \"%s\" on level %d. (Function not implemented)\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_szName,
+ pParse->m_nLevel);
+ pParse->m_nWarnings++;
+ break;
+ }
+}
+
+void startXMLCB(void* pData,
+ const XML_Char* szName,
+ const XML_Char** szaAttrs)
+{
+ t_structXMLParse* pParse = NULL;
+ int nTagPos;
+
+ if (!(pParse = (t_structXMLParse*)pData))
+ return;
+
+ if ((nTagPos = verifyXMLPath(szName, pParse)) == -1) {
+ pParse->m_nLevel++;
+ return;
+ }
+
+ if (verifyXMLAttrs(szaAttrs, pParse, nTagPos) == -1) {
+ pParse->m_nLevel++;
+ return;
+ }
+
+ pParse->m_naTree[pParse->m_nLevel] = nTagPos;
+ switch (pParse->m_nLevel) {
+ case 0:
+ handleXMLStartLevel0(pParse);
+ break;
+ case 1:
+ handleXMLStartLevel1(pParse);
+ break;
+ case 2:
+ handleXMLStartLevel2(pParse);
+ break;
+ case 3:
+ handleXMLStartLevel3(pParse);
+ break;
+ default:
+ fprintf(stderr, "warning: %s(%d): XML tag nesting of %d levels not handled Ignoring tag \"%s\".\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pParse->m_nLevel,
+ szName);
+ pParse->m_nWarnings++;
+ break;
+ }
+
+ pParse->m_nLevel++;
+ pParse->m_nLastGoodLevel = pParse->m_nLevel;
+ return;
+}
+
+void handleXMLEndLevel0(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ default:
+ break;
+ }
+}
+
+void handleXMLEndLevel1(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+ t_structXMLMacro* pMacro = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_MACRO:
+ pMacro = getLastXMLMacro(pSpec->m_pMacros);
+ newStr(pParse->m_szValue, &(pMacro->m_szValue));
+ break;
+ default:
+ break;
+ }
+}
+
+void handleXMLEndLevel2(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+ t_structXMLPackage* pPkg = NULL;
+ t_structXMLScript* pScript = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_SUMMARY:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ newStrEx(pParse->m_szValue, &(pPkg->m_szSummary));
+ break;
+ case TAGVAL_DESCRIPTION:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ newStrEx(pParse->m_szValue, &(pPkg->m_szDescription));
+ break;
+ case TAGVAL_SCRIPT:
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel-1]].m_nValue) {
+ case TAGVAL_PREP:
+ pScript = getLastXMLScript(pSpec->m_pPrep->m_pScripts);
+ break;
+ case TAGVAL_BUILD:
+ pScript = getLastXMLScript(pSpec->m_pBuild->m_pScripts);
+ break;
+ case TAGVAL_INSTALL:
+ pScript = getLastXMLScript(pSpec->m_pInstall->m_pScripts);
+ break;
+ case TAGVAL_CLEAN:
+ pScript = getLastXMLScript(pSpec->m_pClean->m_pScripts);
+ break;
+ default:
+ break;
+ }
+ if (pScript)
+ newStrEx(pParse->m_szValue, (char**)&(pScript->m_szEntry));
+ break;
+ default:
+ break;
+ }
+}
+
+void handleXMLEndLevel3(t_structXMLParse* pParse)
+{
+ t_structXMLSpec* pSpec = NULL;
+ t_structXMLPackage* pPkg = NULL;
+ t_structXMLScript* pScript = NULL;
+
+ pSpec = pParse->m_pSpec;
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel]].m_nValue) {
+ case TAGVAL_SCRIPT:
+ pPkg = getLastXMLPackage(pSpec->m_pPackages);
+ switch (g_pXMLTags[pParse->m_naTree[pParse->m_nLevel-1]].m_nValue) {
+ case TAGVAL_PRE:
+ pScript = getLastXMLScript(pPkg->m_pPre->m_pScripts);
+ break;
+ case TAGVAL_POST:
+ pScript = getLastXMLScript(pPkg->m_pPost->m_pScripts);
+ break;
+ case TAGVAL_PREUN:
+ pScript = getLastXMLScript(pPkg->m_pPreUn->m_pScripts);
+ break;
+ case TAGVAL_POSTUN:
+ pScript = getLastXMLScript(pPkg->m_pPostUn->m_pScripts);
+ break;
+ case TAGVAL_VERIFY:
+ pScript = getLastXMLScript(pPkg->m_pVerify->m_pScripts);
+ break;
+ default:
+ break;
+ }
+ if (pScript)
+ newStrEx(pParse->m_szValue,
+ (char**)&(pScript->m_szEntry));
+ break;
+ default:
+ break;
+ }
+}
+
+void endXMLCB(void* pData,
+ const XML_Char* szName)
+{
+ t_structXMLParse* pParse = NULL;
+
+ if ((pParse = (t_structXMLParse*)pData)) {
+ pParse->m_nLevel--;
+ switch (pParse->m_nLevel) {
+ case 0:
+ handleXMLEndLevel0(pParse);
+ break;
+ case 1:
+ handleXMLEndLevel1(pParse);
+ break;
+ case 2:
+ handleXMLEndLevel2(pParse);
+ break;
+ case 3:
+ handleXMLEndLevel3(pParse);
+ break;
+ default:
+ break;
+ }
+ freeStr(&(pParse->m_szValue));
+ }
+}
+
+void dataXMLCB(void* pData,
+ const XML_Char* szValue,
+ int nLen)
+{
+ t_structXMLParse* pParse = NULL;
+ char* szTmp = NULL;
+ char* szTmpValue = NULL;
+ char* szPos = NULL;
+
+ if ((pParse = (t_structXMLParse*)pData)) {
+ szTmp = malloc(nLen+2);
+ szTmp[nLen] = '\0';
+ snprintf(szTmp, nLen+1, "%s", szValue);
+ szPos = szTmp;
+ while ((*szPos == ' ') ||
+ (*szPos == '\t') ||
+ (*szPos == '\r') ||
+ (*szPos == '\n'))
+ szPos++;
+
+ if (strlen(szPos)) {
+ if (pParse->m_szValue) {
+ szTmpValue = malloc(strlen(szPos)+strlen(pParse->m_szValue)+1);
+ sprintf(szTmpValue, "%s%s", pParse->m_szValue, szPos);
+ newStr(szTmpValue, &(pParse->m_szValue));
+ free(szTmpValue);
+ }
+ else
+ newStr(szPos, &(pParse->m_szValue));
+ }
+ free(szTmp);
+ }
+}
+
+t_structXMLSpec* parseXMLSpec(const char* szFile, int nVerbose)
+{
+ XML_Parser pParser = NULL;
+ t_structXMLParse* pSParse = NULL;
+ t_structXMLSpec* pSpec = NULL;
+ FILE* fIn = NULL;
+ int nLen = 0;
+ char szBuffer[1024+1];
+
+ pSParse = malloc(sizeof(t_structXMLParse));
+ pSParse->m_szXMLFile = (char*)szFile;
+ pSParse->m_szValue = NULL;
+ pSParse->m_nLevel = 0;
+ pSParse->m_nLastGoodLevel = 0;
+ pSParse->m_nWarnings = 0;
+ pSParse->m_nErrors = 0;
+ pSParse->m_pSpec = NULL;
+ pSParse->m_pAttrs = NULL;
+ pSParse->m_nVerbose = nVerbose;
+
+ if ((fIn = fopen(szFile, "r"))) {
+ if ((pParser = XML_ParserCreate(NULL))) {
+ pSParse->m_pParser = pParser;
+ XML_SetStartElementHandler(pParser, &startXMLCB);
+ XML_SetEndElementHandler(pParser, &endXMLCB);
+ XML_SetCharacterDataHandler(pParser, &dataXMLCB);
+ XML_SetUserData(pParser, pSParse);
+ while (!feof(fIn)) {
+ nLen = fread(szBuffer, sizeof(char), 1024, fIn);
+ if (!XML_Parse(pParser, szBuffer, nLen, 0)) {
+ fprintf(stderr, "fatal: %s(%d): %s \n", szFile,
+ XML_GetCurrentLineNumber(pParser),
+ XML_ErrorString(XML_GetErrorCode(pParser)));
+ pSParse->m_nErrors++;
+ }
+ }
+ if (nVerbose)
+ printf("+ XML parse completed with %d error(s), %d warning(s).\n", pSParse->m_nErrors, pSParse->m_nWarnings);
+ XML_Parse(pParser, szBuffer, 0, 1);
+ XML_ParserFree(pParser);
+ }
+ fclose(fIn);
+ }
+ else {
+ free(pSParse);
+ fprintf(stderr, "fatal: Open of \"%s\" failed.\n", szFile);
+ return NULL;
+ }
+
+ freeXMLAttr(&(pSParse->m_pAttrs));
+ if (pSParse->m_nErrors)
+ freeXMLSpec(&(pSParse->m_pSpec));
+
+ pSpec = pSParse->m_pSpec;
+ free(pSParse);
+ return pSpec;
+}
--- /dev/null
+#ifndef _XML_PARSE_H_
+#define _XML_PARSE_H_
+
+#include <expat.h>
+
+#include "xmlstruct.h"
+
+#define MAX_XML_LEVELS 10
+#define MAX_XML_ATTRS 20
+
+typedef struct structXMLParse
+{
+ char* m_szXMLFile;
+ XML_Parser m_pParser;
+ char* m_szValue;
+ int m_nLevel;
+ int m_nLastGoodLevel;
+ int m_nErrors;
+ int m_nWarnings;
+ int m_naTree[MAX_XML_LEVELS];
+ int m_nVerbose;
+ t_structXMLAttr* m_pAttrs;
+ t_structXMLSpec* m_pSpec;
+} t_structXMLParse;
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include "rpmio.h"
+#include "header.h"
+#include "stringbuf.h"
+#include "rpmspec.h"
+#include "header_internal.h"
+
+#include "xmlmisc.h"
+#include "xmlstruct.h"
+#include "xmlverify.h"
+
+extern Spec g_pSpec;
+char* g_szSpecPath = NULL;
+
+void attrSetStr(const t_structXMLAttr* pAttr,
+ const char* szParam,
+ char** pszVar)
+{
+ if (pAttr && !strcasecmp(pAttr->m_szName, szParam))
+ newStrEx(pAttr->m_szValue, pszVar);
+}
+
+void attrSetInt(const t_structXMLAttr* pAttr,
+ const char* szParam,
+ int* pnVar)
+{
+ if (pAttr && !strcasecmp(pAttr->m_szName, szParam))
+ (*pnVar) = atoi(pAttr->m_szValue);
+}
+
+void attrSetBool(const t_structXMLAttr* pAttr,
+ const char* szParam,
+ int* pnVar)
+{
+ if (pAttr && !strcasecmp(pAttr->m_szName, szParam))
+ (*pnVar) = strToBool(pAttr->m_szValue);
+}
+
+t_structXMLAttr* newXMLAttr(const char* szName,
+ const char* szValue,
+ int nType)
+{
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pAttr = malloc(sizeof(t_structXMLAttr)))) {
+ pAttr->m_szName = NULL;
+ pAttr->m_szValue = NULL;
+ pAttr->m_nType = nType;
+ pAttr->m_pNext = NULL;
+
+ newStrEx(szName, &(pAttr->m_szName));
+ newStrEx(szValue, &(pAttr->m_szValue));
+ }
+
+ return pAttr;
+}
+
+int freeXMLAttr(t_structXMLAttr** ppAttr)
+{
+ if (*ppAttr) {
+ freeStr(&((*ppAttr)->m_szName));
+ freeStr(&((*ppAttr)->m_szValue));
+ freeXMLAttr(&((*ppAttr)->m_pNext));
+ free(*ppAttr);
+ *ppAttr = NULL;
+ }
+
+ return 0;
+}
+
+t_structXMLAttr* addXMLAttr(const char* szName,
+ const char* szValue,
+ int nType,
+ t_structXMLAttr** ppAttr)
+{
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pAttr = getLastXMLAttr(*ppAttr)))
+ pAttr = (pAttr->m_pNext = newXMLAttr(szName, szValue, nType));
+ else
+ pAttr = (*ppAttr = newXMLAttr(szName, szValue, nType));
+
+ return pAttr;
+}
+
+t_structXMLAttr* getLastXMLAttr(t_structXMLAttr* pAttr)
+{
+ while (pAttr && (pAttr->m_pNext))
+ pAttr = pAttr->m_pNext;
+
+ return pAttr;
+}
+
+t_structXMLAttr* getXMLAttr(const char* szName,
+ t_structXMLAttr* pAttr)
+{
+ while (pAttr && (strcasecmp(szName, pAttr->m_szName) != 0))
+ pAttr = pAttr->m_pNext;
+
+ return pAttr;
+}
+
+t_structXMLMacro* newXMLMacro(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLMacro* pMacro = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pMacro = malloc(sizeof(t_structXMLMacro)))) {
+ pMacro->m_szName = NULL;
+ pMacro->m_szValue = NULL;
+ pMacro->m_pNext = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "name", &(pMacro->m_szName));
+ } while ((pAttr = pAttr->m_pNext));
+ //addMacroEx(pMacro->m_szName, (char**)&(pMacro->m_szValue), 1);
+ }
+
+ return pMacro;
+}
+
+int freeXMLMacro(t_structXMLMacro** ppMacro)
+{
+ if (*ppMacro) {
+ freeStr(&((*ppMacro)->m_szName));
+ freeStr(&((*ppMacro)->m_szValue));
+ freeXMLMacro(&((*ppMacro)->m_pNext));
+ free(*ppMacro);
+ }
+ *ppMacro = NULL;
+
+ return 0;
+}
+
+t_structXMLMacro* addXMLMacro(const t_structXMLAttr* pAttrs,
+ t_structXMLMacro** ppMacro)
+{
+ t_structXMLMacro* pMacro = NULL;
+
+ if ((pMacro = getLastXMLMacro(*ppMacro)))
+ pMacro = (pMacro->m_pNext = newXMLMacro(pAttrs));
+ else
+ pMacro = (*ppMacro = newXMLMacro(pAttrs));
+
+ return pMacro;
+}
+
+t_structXMLMacro* getLastXMLMacro(t_structXMLMacro* pMacro)
+{
+ while (pMacro && (pMacro->m_pNext))
+ pMacro = pMacro->m_pNext;
+
+ return pMacro;
+}
+
+t_structXMLMirror* newXMLMirror(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLMirror* pMirror = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pMirror = malloc(sizeof(t_structXMLMirror)))) {
+ pMirror->m_szName = NULL;
+ pMirror->m_szLocation = NULL;
+ pMirror->m_szCountry = NULL;
+ pMirror->m_szPath = NULL;
+ pMirror->m_nTries = 0;
+ pMirror->m_pNext = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "name", &(pMirror->m_szName));
+ attrSetStr(pAttr, "location", &(pMirror->m_szLocation));
+ attrSetStr(pAttr, "country", &(pMirror->m_szCountry));
+ attrSetStr(pAttr, "path", &(pMirror->m_szPath));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+
+ return pMirror;
+}
+
+int freeXMLMirror(t_structXMLMirror** ppMirror)
+{
+ if (*ppMirror) {
+ freeStr(&((*ppMirror)->m_szName));
+ freeStr(&((*ppMirror)->m_szLocation));
+ freeStr(&((*ppMirror)->m_szCountry));
+ freeStr(&((*ppMirror)->m_szPath));
+ freeXMLMirror(&((*ppMirror)->m_pNext));
+ free(*ppMirror);
+ }
+ *ppMirror = NULL;
+
+ return 0;
+}
+
+t_structXMLMirror* addXMLMirror(const t_structXMLAttr* pAttrs,
+ t_structXMLMirror** ppMirror)
+{
+ t_structXMLMirror* pMirror = NULL;
+
+ if ((pMirror = getLastXMLMirror(*ppMirror)))
+ pMirror = (pMirror->m_pNext = newXMLMirror(pAttrs));
+ else
+ pMirror = (*ppMirror = newXMLMirror(pAttrs));
+
+ return pMirror;
+}
+
+t_structXMLMirror* getLastXMLMirror(t_structXMLMirror* pMirror)
+{
+ while (pMirror && (pMirror->m_pNext))
+ pMirror = pMirror->m_pNext;
+
+ return pMirror;
+}
+
+t_structXMLSource* newXMLSource(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLSource* pSource = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pSource = malloc(sizeof(t_structXMLSource)))) {
+ pSource->m_szName = NULL;
+ pSource->m_szMD5 = NULL;
+ pSource->m_szDirectory = NULL;
+ pSource->m_nSize = 0;
+ pSource->m_nNum = -1;
+ pSource->m_pMirrors = NULL;
+ pSource->m_pNext = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "name", &(pSource->m_szName));
+ attrSetInt(pAttr, "size", &(pSource->m_nSize));
+ attrSetStr(pAttr, "md5", &(pSource->m_szMD5));
+ attrSetStr(pAttr, "directory", &(pSource->m_szDirectory));
+ attrSetInt(pAttr, "number", &(pSource->m_nNum));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+
+ return pSource;
+}
+
+int freeXMLSource(t_structXMLSource** ppSource)
+{
+ if (*ppSource) {
+ freeStr(&((*ppSource)->m_szName));
+ freeStr(&((*ppSource)->m_szMD5));
+ freeStr(&((*ppSource)->m_szDirectory));
+ freeXMLMirror(&((*ppSource)->m_pMirrors));
+ freeXMLSource(&((*ppSource)->m_pNext));
+ free(*ppSource);
+ }
+ *ppSource = NULL;
+
+ return 0;
+}
+
+t_structXMLSource* addXMLSource(const t_structXMLAttr* pAttrs,
+ t_structXMLSource** ppSource)
+{
+ t_structXMLSource* pSource = NULL;
+
+ if ((pSource = getLastXMLSource(*ppSource))) {
+ pSource->m_pNext = newXMLSource(pAttrs);
+ if (pSource->m_pNext->m_nNum == -1)
+ pSource->m_pNext->m_nNum = pSource->m_nNum + 1;
+ pSource = pSource->m_pNext;
+ }
+ else {
+ pSource = (*ppSource = newXMLSource(pAttrs));
+ if (pSource->m_nNum == -1)
+ pSource->m_nNum = 0;
+ }
+
+ return pSource;
+}
+
+t_structXMLSource* getLastXMLSource(t_structXMLSource* pSource)
+{
+ while (pSource && (pSource->m_pNext))
+ pSource = pSource->m_pNext;
+
+ return pSource;
+}
+
+t_structXMLSource* getXMLSource(int nNum,
+ t_structXMLSource* pSource)
+{
+ while (pSource && (pSource->m_nNum != nNum))
+ pSource = pSource->m_pNext;
+
+ return pSource;
+}
+
+t_structXMLRequire* newXMLRequire(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLRequire* pRequire = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pRequire = malloc(sizeof(t_structXMLRequire)))) {
+ pRequire->m_szName = NULL;
+ pRequire->m_szVersion = NULL;
+ pRequire->m_szRelease = NULL;
+ pRequire->m_szEpoch = NULL;
+ pRequire->m_szCompare = NULL;
+ pRequire->m_pNext = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "name", &(pRequire->m_szName));
+ attrSetStr(pAttr, "version", &(pRequire->m_szVersion));
+ attrSetStr(pAttr, "release", &(pRequire->m_szRelease));
+ attrSetStr(pAttr, "epoch", &(pRequire->m_szEpoch));
+ attrSetStr(pAttr, "compare", &(pRequire->m_szCompare));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+
+ return pRequire;
+}
+
+int freeXMLRequire(t_structXMLRequire** ppRequire)
+{
+ if (*ppRequire) {
+ freeStr(&((*ppRequire)->m_szName));
+ freeStr(&((*ppRequire)->m_szVersion));
+ freeStr(&((*ppRequire)->m_szRelease));
+ freeStr(&((*ppRequire)->m_szEpoch));
+ freeStr(&((*ppRequire)->m_szCompare));
+ freeXMLRequire(&((*ppRequire)->m_pNext));
+ free(*ppRequire);
+ }
+ *ppRequire = NULL;
+
+ return 0;
+}
+
+t_structXMLRequire* addXMLRequire(const t_structXMLAttr* pAttrs,
+ t_structXMLRequire** ppRequire)
+{
+ t_structXMLRequire* pRequire = NULL;
+
+ if ((pRequire = getLastXMLRequire(*ppRequire)))
+ pRequire = (pRequire->m_pNext = newXMLRequire(pAttrs));
+ else
+ pRequire = (*ppRequire = newXMLRequire(pAttrs));
+
+ return pRequire;
+}
+
+t_structXMLRequire* getLastXMLRequire(t_structXMLRequire* pRequire)
+{
+ while (pRequire && (pRequire->m_pNext))
+ pRequire = pRequire->m_pNext;
+
+ return pRequire;
+}
+
+t_structXMLScript* newXMLScript(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLScript* pScript = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pScript = malloc(sizeof(t_structXMLScript)))) {
+ pScript->m_szInterpreter = NULL;
+ pScript->m_szScript = NULL;
+ pScript->m_szEntry = NULL;
+ pScript->m_pNext = NULL;
+
+ if ((pAttr = (t_structXMLAttr*)pAttrs)) {
+ do {
+ attrSetStr(pAttr, "interpreter",
+ &(pScript->m_szInterpreter));
+ attrSetStr(pAttr, "script",
+ &(pScript->m_szScript));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+ }
+
+ return pScript;
+}
+
+int freeXMLScript(t_structXMLScript** ppScript)
+{
+ if (*ppScript) {
+ freeStr(&((*ppScript)->m_szInterpreter));
+ freeStr(&((*ppScript)->m_szScript));
+ freeStr(&((*ppScript)->m_szEntry));
+ freeXMLScript(&((*ppScript)->m_pNext));
+ free(*ppScript);
+ }
+ *ppScript = NULL;
+
+ return 0;
+}
+
+t_structXMLScript* addXMLScript(const t_structXMLAttr* pAttrs,
+ t_structXMLScript** ppScript)
+{
+ t_structXMLScript* pScript = NULL;
+
+ if ((pScript = getLastXMLScript(*ppScript)))
+ pScript = (pScript->m_pNext = newXMLScript(pAttrs));
+ else
+ pScript = (*ppScript = newXMLScript(pAttrs));
+
+ return pScript;
+}
+
+t_structXMLScript* getLastXMLScript(t_structXMLScript* pScript)
+{
+ while (pScript && (pScript->m_pNext))
+ pScript = pScript->m_pNext;
+
+ return pScript;
+}
+
+t_structXMLScripts* newXMLScripts(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLScripts* pScripts = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pScripts = malloc(sizeof(t_structXMLScripts)))) {
+ pScripts->m_szInterpreter = NULL;
+ pScripts->m_szScript = NULL;
+ pScripts->m_pScripts = NULL;
+
+ if ((pAttr = (t_structXMLAttr*)pAttrs)) {
+ do {
+ attrSetStr(pAttr, "interpreter", &(pScripts->m_szInterpreter));
+ attrSetStr(pAttr, "script", &(pScripts->m_szScript));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+ }
+
+ return pScripts;
+}
+
+int freeXMLScripts(t_structXMLScripts** ppScripts)
+{
+ if (*ppScripts) {
+ freeStr(&((*ppScripts)->m_szInterpreter));
+ freeStr(&((*ppScripts)->m_szScript));
+ freeXMLScript(&((*ppScripts)->m_pScripts));
+ free(*ppScripts);
+ }
+ *ppScripts = NULL;
+
+ return 0;
+}
+
+t_structXMLFiles* newXMLFiles(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLFiles* pFiles = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pFiles = malloc(sizeof(t_structXMLFiles)))) {
+ pFiles->m_szFileList = NULL;
+ pFiles->m_szUID = NULL;
+ pFiles->m_szGID = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "list", &(pFiles->m_szFileList));
+ attrSetStr(pAttr, "uid", &(pFiles->m_szUID));
+ attrSetStr(pAttr, "gid", &(pFiles->m_szGID));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+
+ return pFiles;
+}
+
+int freeXMLFiles(t_structXMLFiles** ppFiles)
+{
+ if (*ppFiles) {
+ freeStr(&((*ppFiles)->m_szFileList));
+ freeStr(&((*ppFiles)->m_szUID));
+ freeStr(&((*ppFiles)->m_szGID));
+ free(*ppFiles);
+ }
+ *ppFiles = NULL;
+
+ return 0;
+}
+
+t_structXMLPackage* newXMLPackage(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLPackage* pPackage = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pPackage = malloc(sizeof(t_structXMLPackage)))) {
+ pPackage->m_szName = NULL;
+ pPackage->m_szGroup = NULL;
+ pPackage->m_szSummary = NULL;
+ pPackage->m_szDescription = NULL;
+ pPackage->m_pPre = NULL;
+ pPackage->m_pPost = NULL;
+ pPackage->m_pPreUn = NULL;
+ pPackage->m_pPostUn = NULL;
+ pPackage->m_pVerify = NULL;
+ pPackage->m_nAutoRequire = 1;
+ pPackage->m_nAutoProvide = 1;
+ pPackage->m_nAutoSuggest = 0;
+ pPackage->m_pFiles = NULL;
+ pPackage->m_pRequires = NULL;
+ pPackage->m_pSuggests = NULL;
+ pPackage->m_pObsoletes = NULL;
+ pPackage->m_pProvides = NULL;
+ pPackage->m_pNext = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "name", &(pPackage->m_szName));
+ attrSetStr(pAttr, "group", &(pPackage->m_szGroup));
+ attrSetBool(pAttr, "autorequire", &(pPackage->m_nAutoRequire));
+ attrSetBool(pAttr, "autoprovide", &(pPackage->m_nAutoProvide));
+ attrSetBool(pAttr, "autosuggest", &(pPackage->m_nAutoSuggest));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+
+ return pPackage;
+}
+
+int freeXMLPackage(t_structXMLPackage** ppPackage)
+{
+ if (*ppPackage) {
+ freeStr(&((*ppPackage)->m_szName));
+ freeStr(&((*ppPackage)->m_szGroup));
+ freeStr(&((*ppPackage)->m_szSummary));
+ freeStr(&((*ppPackage)->m_szDescription));
+ freeXMLFiles(&((*ppPackage)->m_pFiles));
+ freeXMLScripts(&((*ppPackage)->m_pPre));
+ freeXMLScripts(&((*ppPackage)->m_pPost));
+ freeXMLScripts(&((*ppPackage)->m_pPreUn));
+ freeXMLScripts(&((*ppPackage)->m_pPostUn));
+ freeXMLScripts(&((*ppPackage)->m_pVerify));
+ freeXMLRequire(&((*ppPackage)->m_pRequires));
+ freeXMLRequire(&((*ppPackage)->m_pSuggests));
+ freeXMLRequire(&((*ppPackage)->m_pObsoletes));
+ freeXMLRequire(&((*ppPackage)->m_pProvides));
+ freeXMLPackage(&((*ppPackage)->m_pNext));
+ free(*ppPackage);
+ }
+ *ppPackage = NULL;
+
+ return 0;
+}
+
+t_structXMLPackage* addXMLPackage(const t_structXMLAttr* pAttrs,
+ t_structXMLPackage** ppPackage)
+{
+ t_structXMLPackage* pPackage = NULL;
+
+ if ((pPackage = getLastXMLPackage(*ppPackage)))
+ pPackage = (pPackage->m_pNext = newXMLPackage(pAttrs));
+ else
+ pPackage = (*ppPackage = newXMLPackage(pAttrs));
+
+ return pPackage;
+}
+
+t_structXMLPackage* getLastXMLPackage(t_structXMLPackage* pPackage)
+{
+ while (pPackage && (pPackage->m_pNext))
+ pPackage = pPackage->m_pNext;
+
+ return pPackage;
+}
+
+t_structXMLChange* newXMLChange(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLChange* pChange = NULL;
+
+ if ((pChange = malloc(sizeof(t_structXMLChange)))) {
+ pChange->m_szValue = NULL;
+ pChange->m_pNext = NULL;
+ }
+
+ return pChange;
+}
+
+int freeXMLChange(t_structXMLChange** ppChange)
+{
+ if (*ppChange) {
+ freeStr(&((*ppChange)->m_szValue));
+ freeXMLChange(&((*ppChange)->m_pNext));
+ free(*ppChange);
+ }
+ *ppChange = NULL;
+
+ return 0;
+}
+
+t_structXMLChange* addXMLChange(const t_structXMLAttr* pAttrs,
+ t_structXMLChange** ppChange)
+{
+ t_structXMLChange* pChange = NULL;
+
+ if ((pChange = getLastXMLChange(*ppChange)))
+ pChange = (pChange->m_pNext = newXMLChange(pAttrs));
+ else
+ pChange = (*ppChange = newXMLChange(pAttrs));
+ return pChange;
+}
+
+t_structXMLChange* getLastXMLChange(t_structXMLChange* pChange)
+{
+ while (pChange && (pChange->m_pNext))
+ pChange = pChange->m_pNext;
+
+ return pChange;
+}
+
+t_structXMLChanges* newXMLChanges(const t_structXMLAttr* pAttrs)
+{
+ t_structXMLChanges* pChanges = NULL;
+ t_structXMLAttr* pAttr = NULL;
+
+ if ((pChanges = malloc(sizeof(t_structXMLChanges)))) {
+ pChanges->m_szDate = NULL;
+ pChanges->m_szVersion = NULL;
+ pChanges->m_szAuthor = NULL;
+ pChanges->m_szAuthorEmail = NULL;
+ pChanges->m_pChanges = NULL;
+ pChanges->m_pNext = NULL;
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "date", &(pChanges->m_szDate));
+ attrSetStr(pAttr, "version", &(pChanges->m_szVersion));
+ attrSetStr(pAttr, "author", &(pChanges->m_szAuthor));
+ attrSetStr(pAttr, "author-email", &(pChanges->m_szAuthorEmail));
+ } while ((pAttr = pAttr->m_pNext));
+ }
+
+ return pChanges;
+}
+
+int freeXMLChanges(t_structXMLChanges** ppChanges)
+{
+ if (*ppChanges) {
+ freeStr(&((*ppChanges)->m_szDate));
+ freeStr(&((*ppChanges)->m_szVersion));
+ freeStr(&((*ppChanges)->m_szAuthor));
+ freeStr(&((*ppChanges)->m_szAuthorEmail));
+ freeXMLChanges(&((*ppChanges)->m_pNext));
+ free(*ppChanges);
+ }
+ *ppChanges = NULL;
+
+ return 0;
+}
+
+t_structXMLChanges* addXMLChanges(const t_structXMLAttr* pAttrs,
+ t_structXMLChanges** ppChanges)
+{
+ t_structXMLChanges* pChanges = NULL;
+
+ if ((pChanges = getLastXMLChanges(*ppChanges)))
+ pChanges = (pChanges->m_pNext = newXMLChanges(pAttrs));
+ else
+ pChanges = (*ppChanges = newXMLChanges(pAttrs));
+
+ return pChanges;
+}
+
+t_structXMLChanges* getLastXMLChanges(t_structXMLChanges* pChanges)
+{
+ while (pChanges && (pChanges->m_pNext))
+ pChanges = pChanges->m_pNext;
+
+ return pChanges;
+}
+
+t_structXMLSpec* newXMLSpec(const t_structXMLAttr* pAttrs,
+ const char* szXMLFile)
+{
+ t_structXMLSpec* pSpec = NULL;
+ t_structXMLAttr* pAttr = NULL;
+ char* szTmp = NULL;
+ int nLen;
+
+ if ((pSpec = malloc(sizeof(t_structXMLSpec)))) {
+ pSpec->m_szSpecName = NULL;
+ pSpec->m_szBuildRootDir = NULL;
+ pSpec->m_szBuildSubdir = NULL;
+ pSpec->m_szRootDir = NULL;
+ pSpec->m_szName = NULL;
+ pSpec->m_szVersion = NULL;
+ pSpec->m_szRelease = NULL;
+ pSpec->m_szEpoch = NULL;
+ pSpec->m_szDistribution = NULL;
+ pSpec->m_szVendor = NULL;
+ pSpec->m_szPackager = NULL;
+ pSpec->m_szPackagerEmail = NULL;
+ pSpec->m_szCopyright = NULL;
+ pSpec->m_szURL = NULL;
+ pSpec->m_pBuildRequires = NULL;
+ pSpec->m_pBuildConflicts = NULL;
+ pSpec->m_pBuildSuggests = NULL;
+ pSpec->m_pPrep = NULL;
+ pSpec->m_pBuild = NULL;
+ pSpec->m_pInstall = NULL;
+ pSpec->m_pClean = NULL;
+ pSpec->m_pMacros = NULL;
+ pSpec->m_pSources = NULL;
+ pSpec->m_pPatches = NULL;
+ pSpec->m_pPackages = NULL;
+ pSpec->m_pChangelog = NULL;
+ g_pSpec = newSpec();
+
+ pAttr = (t_structXMLAttr*)pAttrs;
+ do {
+ attrSetStr(pAttr, "name", &(pSpec->m_szName));
+ attrSetStr(pAttr, "version", &(pSpec->m_szVersion));
+ attrSetStr(pAttr, "release", &(pSpec->m_szRelease));
+ attrSetStr(pAttr, "epoch", &(pSpec->m_szEpoch));
+ attrSetStr(pAttr, "distribution", &(pSpec->m_szDistribution));
+ attrSetStr(pAttr, "vendor", &(pSpec->m_szVendor));
+ attrSetStr(pAttr, "packager", &(pSpec->m_szPackager));
+ attrSetStr(pAttr, "packager-email", &(pSpec->m_szPackagerEmail));
+ attrSetStr(pAttr, "copyright", &(pSpec->m_szCopyright));
+ attrSetStr(pAttr, "url", &(pSpec->m_szURL));
+ attrSetStr(pAttr, "buildroot", &(pSpec->m_szBuildRootDir));
+ attrSetStr(pAttr, "builddir", &(pSpec->m_szBuildSubdir));
+ } while ((pAttr = pAttr->m_pNext));
+
+ addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
+ szTmp = (char*)rpmGetPath(szXMLFile, NULL);
+ newStr(szTmp, &(pSpec->m_szSpecName));
+ free(szTmp);
+ if ((szTmp = rindex(pSpec->m_szSpecName, '/'))) {
+ szTmp++;
+ nLen = szTmp-(pSpec->m_szSpecName);
+ g_szSpecPath = malloc(nLen+1);
+ snprintf(g_szSpecPath, nLen, "%s", pSpec->m_szSpecName);
+ }
+ szTmp = malloc(4097);
+ if (pSpec->m_szBuildRootDir == NULL) {
+ snprintf(szTmp, 4096, "%%{_tmppath}/rpmxml-%s-%s", pSpec->m_szName,
+ pSpec->m_szVersion);
+ newStrEx(szTmp, &(pSpec->m_szBuildRootDir));
+ }
+ if (pSpec->m_szBuildSubdir == NULL) {
+ snprintf(szTmp, 4096, "%s-%s", pSpec->m_szName,
+ pSpec->m_szVersion);
+ newStrEx(szTmp, &(pSpec->m_szBuildSubdir));
+ }
+ free(szTmp);
+ if (pSpec->m_szRootDir == NULL)
+ newStrEx("/", &(pSpec->m_szRootDir));
+ addMacroEx("name", (char**)&(pSpec->m_szName), RMIL_SPEC);
+ addMacroEx("version", (char**)&(pSpec->m_szVersion), RMIL_SPEC);
+ addMacroEx("PACKAGE_VERSION", (char**)&(pSpec->m_szVersion), -1);
+ addMacroEx("release", (char**)&(pSpec->m_szRelease), RMIL_SPEC);
+ addMacroEx("PACKAGE_RELEASE", (char**)&(pSpec->m_szRelease), -2);
+ addMacroEx("copyright", (char**)&(pSpec->m_szCopyright), RMIL_SPEC);
+ addMacroEx("url", (char**)&(pSpec->m_szURL), RMIL_SPEC);
+ addMacroEx("distribution", (char**)&(pSpec->m_szDistribution), RMIL_SPEC);
+ addMacroEx("vendor", (char**)&(pSpec->m_szVendor), RMIL_SPEC);
+ addMacroEx("buildroot", (char**)&(pSpec->m_szBuildRootDir), RMIL_SPEC);
+ addMacroEx("buildsubdir", (char**)&(pSpec->m_szBuildSubdir), RMIL_SPEC);
+ if (pSpec->m_szPackagerEmail || pSpec->m_szPackager) {
+ szTmp = malloc(strlen(pSpec->m_szPackager)+strlen(pSpec->m_szPackagerEmail)+4);
+ if (pSpec->m_szPackagerEmail && pSpec->m_szPackager)
+ sprintf(szTmp, "%s <%s>", pSpec->m_szPackager, pSpec->m_szPackagerEmail);
+ else
+ sprintf(szTmp, "%s", pSpec->m_szPackager ? pSpec->m_szPackager : pSpec->m_szPackagerEmail);
+ addMacroEx("packager", (char**)&(szTmp), RMIL_SPEC);
+ free(szTmp);
+ }
+ }
+
+ return pSpec;
+}
+
+int freeXMLSpec(t_structXMLSpec** ppSpec)
+{
+ if (*ppSpec) {
+ freeStr(&((*ppSpec)->m_szSpecName));
+ freeStr(&((*ppSpec)->m_szBuildRootDir));
+ freeStr(&((*ppSpec)->m_szBuildSubdir));
+ freeStr(&((*ppSpec)->m_szRootDir));
+ freeStr(&((*ppSpec)->m_szName));
+ freeStr(&((*ppSpec)->m_szVersion));
+ freeStr(&((*ppSpec)->m_szRelease));
+ freeStr(&((*ppSpec)->m_szEpoch));
+ freeStr(&((*ppSpec)->m_szDistribution));
+ freeStr(&((*ppSpec)->m_szVendor));
+ freeStr(&((*ppSpec)->m_szPackager));
+ freeStr(&((*ppSpec)->m_szPackagerEmail));
+ freeStr(&((*ppSpec)->m_szCopyright));
+ freeStr(&((*ppSpec)->m_szURL));
+ freeXMLRequire(&((*ppSpec)->m_pBuildRequires));
+ freeXMLRequire(&((*ppSpec)->m_pBuildConflicts));
+ freeXMLRequire(&((*ppSpec)->m_pBuildSuggests));
+ freeXMLScripts(&((*ppSpec)->m_pPrep));
+ freeXMLScripts(&((*ppSpec)->m_pBuild));
+ freeXMLScripts(&((*ppSpec)->m_pInstall));
+ freeXMLScripts(&((*ppSpec)->m_pClean));
+ freeXMLMacro(&((*ppSpec)->m_pMacros));
+ freeXMLSource(&((*ppSpec)->m_pSources));
+ freeXMLSource(&((*ppSpec)->m_pPatches));
+ freeXMLPackage(&((*ppSpec)->m_pPackages));
+ freeXMLChanges(&((*ppSpec)->m_pChangelog));
+ if (g_pSpec)
+ freeSpec(g_pSpec);
+ g_pSpec = NULL;
+ if (g_szSpecPath)
+ freeStr(&g_szSpecPath);
+ free(*ppSpec);
+ }
+ *ppSpec = NULL;
+
+ return 0;
+}
--- /dev/null
+#ifndef _XML_STRUCT_H_
+#define _XML_STRUCT_H_
+
+#include "xmlmisc.h"
+
+typedef struct structXMLAttr
+{
+ char* m_szName;
+ char* m_szValue;
+ int m_nType;
+ struct structXMLAttr* m_pNext;
+} t_structXMLAttr;
+
+typedef struct structXMLMacro
+{
+ char* m_szName;
+ char* m_szValue;
+ struct structXMLMacro* m_pNext;
+} t_structXMLMacro;
+
+typedef struct structXMLMirror
+{
+ char* m_szName;
+ char* m_szLocation;
+ char* m_szCountry;
+ char* m_szPath;
+ int m_nTries;
+ struct structXMLMirror* m_pNext;
+} t_structXMLMirror;
+
+typedef struct structXMLSource
+{
+ char* m_szName;
+ int m_nSize;
+ char* m_szMD5;
+ char* m_szDirectory;
+ int m_nNum;
+ struct structXMLMirror* m_pMirrors;
+ struct structXMLSource* m_pNext;
+} t_structXMLSource;
+
+typedef struct structXMLRequire
+{
+ char* m_szName;
+ char* m_szVersion;
+ char* m_szRelease;
+ char* m_szEpoch;
+ char* m_szCompare;
+ struct structXMLRequire* m_pNext;
+} t_structXMLRequire;
+
+typedef struct structXMLScript
+{
+ char* m_szInterpreter;
+ char* m_szScript;
+ char* m_szEntry;
+ struct structXMLScript* m_pNext;
+} t_structXMLScript;
+
+typedef struct structXMLScripts
+{
+ char* m_szInterpreter;
+ char* m_szScript;
+ struct structXMLScript* m_pScripts;
+} t_structXMLScripts;
+
+typedef struct structXMLFiles
+{
+ char* m_szFileList;
+ char* m_szUID;
+ char* m_szGID;
+} t_structXMLFiles;
+
+typedef struct structXMLPackage
+{
+ char* m_szName;
+ char* m_szGroup;
+ char* m_szSummary;
+ char* m_szDescription;
+ int m_nAutoRequire;
+ int m_nAutoProvide;
+ int m_nAutoSuggest;
+ struct structXMLFiles* m_pFiles;
+ struct structXMLScripts* m_pPre;
+ struct structXMLScripts* m_pPost;
+ struct structXMLScripts* m_pPreUn;
+ struct structXMLScripts* m_pPostUn;
+ struct structXMLScripts* m_pVerify;
+ struct structXMLRequire* m_pRequires;
+ struct structXMLRequire* m_pSuggests;
+ struct structXMLRequire* m_pObsoletes;
+ struct structXMLRequire* m_pProvides;
+ struct structXMLPackage* m_pNext;
+} t_structXMLPackage;
+
+typedef struct structXMLChange
+{
+ char* m_szValue;
+ struct structXMLChange* m_pNext;
+} t_structXMLChange;
+
+typedef struct structXMLChanges
+{
+ char* m_szDate;
+ char* m_szVersion;
+ char* m_szAuthor;
+ char* m_szAuthorEmail;
+ struct structXMLChange* m_pChanges;
+ struct structXMLChanges* m_pNext;
+} t_structXMLChanges;
+
+typedef struct structXMLSpec
+{
+ char* m_szSpecName;
+ char* m_szBuildRootDir;
+ char* m_szBuildSubdir;
+ char* m_szRootDir;
+ char* m_szName;
+ char* m_szVersion;
+ char* m_szRelease;
+ char* m_szEpoch;
+ char* m_szDistribution;
+ char* m_szVendor;
+ char* m_szPackager;
+ char* m_szPackagerEmail;
+ char* m_szCopyright;
+ char* m_szURL;
+ struct structXMLRequire* m_pBuildRequires;
+ struct structXMLRequire* m_pBuildConflicts;
+ struct structXMLRequire* m_pBuildSuggests;
+ struct structXMLScripts* m_pPrep;
+ struct structXMLScripts* m_pBuild;
+ struct structXMLScripts* m_pInstall;
+ struct structXMLScripts* m_pClean;
+ struct structXMLMacro* m_pMacros;
+ struct structXMLSource* m_pSources;
+ struct structXMLSource* m_pPatches;
+ struct structXMLPackage* m_pPackages;
+ struct structXMLChanges* m_pChangelog;
+} t_structXMLSpec;
+
+void attrSetStr(const t_structXMLAttr* pAttr,
+ const char* szParam,
+ char** pszVar);
+void attrSetInt(const t_structXMLAttr* pAttr,
+ const char* szParam,
+ int* pnVar);
+void attrSetBool(const t_structXMLAttr* pAttr,
+ const char* szParam,
+ int* pnVar);
+
+t_structXMLAttr* newXMLAttr(const char* szName,
+ const char* szValue,
+ int nType);
+int freeXMLAttr(t_structXMLAttr** ppAttr);
+t_structXMLAttr* addXMLAttr(const char* szName,
+ const char* szValue,
+ int nType,
+ t_structXMLAttr** ppAttr);
+t_structXMLAttr* getLastXMLAttr(t_structXMLAttr* pAttr);
+t_structXMLAttr* getXMLAttr(const char* szName,
+ t_structXMLAttr* pAttr);
+
+t_structXMLSpec* parseXMLSpec(const char* szFile, int nVerbose);
+
+t_structXMLMacro* newXMLMacro(const t_structXMLAttr* pAttrs);
+int freeXMLMacro(t_structXMLMacro** ppMacro);
+t_structXMLMacro* addXMLMacro(const t_structXMLAttr* pAttrs,
+ t_structXMLMacro** ppMacro);
+t_structXMLMacro* getLastXMLMacro(t_structXMLMacro* pMacro);
+
+t_structXMLMirror* newXMLMirror(const t_structXMLAttr* pAttrs);
+int freeXMLMirror(t_structXMLMirror** ppMirror);
+t_structXMLMirror* addXMLMirror(const t_structXMLAttr* pAttrs,
+ t_structXMLMirror** ppMirror);
+t_structXMLMirror* getLastXMLMirror(t_structXMLMirror* pMirror);
+
+t_structXMLSource* newXMLSource(const t_structXMLAttr* pAttrs);
+int freeXMLSource(t_structXMLSource** ppSource);
+t_structXMLSource* addXMLSource(const t_structXMLAttr* pAttrs,
+ t_structXMLSource** ppSource);
+t_structXMLSource* getLastXMLSource(t_structXMLSource* pSource);
+t_structXMLSource* getXMLSource(int nNum,
+ t_structXMLSource* pSource);
+
+t_structXMLRequire* newXMLRequire(const t_structXMLAttr* pAttrs);
+int freeXMLRequire(t_structXMLRequire** ppRequire);
+t_structXMLRequire* addXMLRequire(const t_structXMLAttr* pAttrs,
+ t_structXMLRequire** ppRequire);
+t_structXMLRequire* getLastXMLRequire(t_structXMLRequire* pRequire);
+
+t_structXMLScript* newXMLScript(const t_structXMLAttr* pAttrs);
+int freeXMLScript(t_structXMLScript** ppScript);
+t_structXMLScript* addXMLScript(const t_structXMLAttr* pAttrs,
+ t_structXMLScript** ppScript);
+t_structXMLScript* getLastXMLScript(t_structXMLScript* pScript);
+
+t_structXMLScripts* newXMLScripts(const t_structXMLAttr* pAttrs);
+int freeXMLScripts(t_structXMLScripts** ppScripts);
+
+t_structXMLFiles* newXMLFiles(const t_structXMLAttr* pAttrs);
+int freeXMLFiles(t_structXMLFiles** ppFiles);
+
+t_structXMLPackage* newXMLPackage(const t_structXMLAttr* pAttrs);
+int freeXMLPackage(t_structXMLPackage** ppPackage);
+t_structXMLPackage* addXMLPackage(const t_structXMLAttr* pAttrs,
+ t_structXMLPackage** ppPackage);
+t_structXMLPackage* getLastXMLPackage(t_structXMLPackage* pPackage);
+
+t_structXMLChange* newXMLChange(const t_structXMLAttr* pAttrs);
+int freeXMLChange(t_structXMLChange** ppChange);
+t_structXMLChange* addXMLChange(const t_structXMLAttr* pAttrs,
+ t_structXMLChange** ppChange);
+t_structXMLChange* getLastXMLChange(t_structXMLChange* pChange);
+
+t_structXMLChanges* newXMLChanges(const t_structXMLAttr* pAttrs);
+int freeXMLChanges(t_structXMLChanges** ppChanges);
+t_structXMLChanges* addXMLChanges(const t_structXMLAttr* pAttrs,
+ t_structXMLChanges** ppChanges);
+t_structXMLChanges* getLastXMLChanges(t_structXMLChanges* pChanges);
+
+t_structXMLSpec* newXMLSpec(const t_structXMLAttr* pAttrs,
+ const char* szXMLFile);
+int freeXMLSpec(t_structXMLSpec** ppSpec);
+
+#endif
--- /dev/null
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+// This is a hack to make sure we can include the
+// xmlverify header file
+#define NO_XMLTAGS_EXTERN 1
+
+#include "xmlparse.h"
+#include "xmlverify.h"
+
+extern char* g_szSpecPath;
+
+t_structXMLTags g_pXMLTags[] =
+{
+ {
+ "spec", TAGVAL_SPEC, 0,
+ {
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {"version", ATTRTYPE_ANY, 1},
+ {"release", ATTRTYPE_ANY, 1},
+ {"epoch", ATTRTYPE_NUMERIC, 0},
+ {"buildroot", ATTRTYPE_ANY, 0},
+ {"builddir", ATTRTYPE_ANY, 0},
+ {"url", ATTRTYPE_URL, 0},
+ {"copyright", ATTRTYPE_ANY, 0},
+ {"distribution", ATTRTYPE_ANY, 1},
+ {"vendor", ATTRTYPE_ANY, 1},
+ {"packager", ATTRTYPE_ANY, 1},
+ {"packager-email", ATTRTYPE_EMAIL, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ },
+ },
+ {
+ "macro", TAGVAL_MACRO, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "source", TAGVAL_SOURCE, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_SRCFILE, 1},
+ {"size", ATTRTYPE_NUMERIC, 0},
+ {"md5", ATTRTYPE_MD5, 0},
+ {"path", ATTRTYPE_ANY, 0},
+ {"number", ATTRTYPE_NUMERIC, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "mirror", TAGVAL_SOURCEMIRROR, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_SOURCE,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 0},
+ {"location", ATTRTYPE_ANY, 0},
+ {"country", ATTRTYPE_COUNTRY, 0},
+ {"path", ATTRTYPE_URL, 1},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+
+ {
+ "patch", TAGVAL_PATCH, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_SRCFILE, 1},
+ {"size", ATTRTYPE_NUMERIC, 0},
+ {"md5", ATTRTYPE_MD5, 0},
+ {"path", ATTRTYPE_ANY, 0},
+ {"number", ATTRTYPE_NUMERIC, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "mirror", TAGVAL_PATCHMIRROR, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PATCH,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 0},
+ {"location", ATTRTYPE_ANY, 0},
+ {"country", ATTRTYPE_COUNTRY, 0},
+ {"path", ATTRTYPE_URL, 1},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "buildrequires", TAGVAL_BUILDREQUIRES, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "require", TAGVAL_BUILDREQUIRE, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_BUILDREQUIRES,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {"version", ATTRTYPE_ANY, 0},
+ {"cmp", ATTRTYPE_CMP, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "buildsuggests", TAGVAL_BUILDSUGGESTS, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "suggest", TAGVAL_BUILDSUGGEST, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_BUILDSUGGESTS,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {"version", ATTRTYPE_ANY, 0},
+ {"cmp", ATTRTYPE_CMP, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ { "package", TAGVAL_PACKAGE, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 0},
+ {"group", ATTRTYPE_ANY, 1},
+ {"autoreqprov", ATTRTYPE_BOOL, 0},
+ {"autoprov", ATTRTYPE_BOOL, 0},
+ {"autoreq", ATTRTYPE_BOOL, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "requires", TAGVAL_REQUIRES, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "require", TAGVAL_REQUIRE, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_REQUIRES,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {"version", ATTRTYPE_ANY, 0},
+ {"cmp", ATTRTYPE_CMP, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "provides", TAGVAL_PROVIDES, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "provide", TAGVAL_PROVIDE, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_PROVIDES,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "obsoletes", TAGVAL_OBSOLETES, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "obsolete", TAGVAL_OBSOLETE, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_OBSOLETES,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "suggests", TAGVAL_SUGGESTS, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "suggest", TAGVAL_SUGGEST, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_SUGGESTS,
+ TAGVAL_LAST
+ },
+ {
+ {"name", ATTRTYPE_ANY, 1},
+ {"version", ATTRTYPE_ANY, 0},
+ {"cmp", ATTRTYPE_CMP, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "summary", TAGVAL_SUMMARY, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "description", TAGVAL_DESCRIPTION, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "pre", TAGVAL_PRE, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_PRE,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "post", TAGVAL_POST, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_POST,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "preun", TAGVAL_PREUN, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_PREUN,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "postun", TAGVAL_POSTUN, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_POSTUN,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {"verify", TAGVAL_VERIFY, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_VERIFY,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "files", TAGVAL_FILES, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PACKAGE,
+ TAGVAL_LAST
+ },
+ {
+ {"uid", ATTRTYPE_ANY, 0},
+ {"gid", ATTRTYPE_ANY, 0},
+ {"list", ATTRTYPE_SCRIPT, 1},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "prep", TAGVAL_PREP, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PREP,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "setup", TAGVAL_SETUPMACRO, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PREP,
+ TAGVAL_LAST
+ },
+ {
+ {"source", ATTRTYPE_NUMERIC, 0},
+ {"path", ATTRTYPE_ANY, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "patch", TAGVAL_PATCHMACRO, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_PREP,
+ TAGVAL_LAST
+ },
+ {
+ {"patch", ATTRTYPE_NUMERIC, 0},
+ {"level", ATTRTYPE_NUMERIC, 0},
+ {"path", ATTRTYPE_ANY, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "build", TAGVAL_BUILD, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_BUILD,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "install", TAGVAL_INSTALL, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_INSTALL,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "clean", TAGVAL_CLEAN, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "script", TAGVAL_SCRIPT, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_CLEAN,
+ TAGVAL_LAST
+ },
+ {
+ {"interpreter", ATTRTYPE_ANY, 0},
+ {"script", ATTRTYPE_SCRIPT, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "changelog", TAGVAL_CHANGELOG, 1,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "changes", TAGVAL_CHANGES, 2,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_CHANGELOG,
+ TAGVAL_LAST
+ },
+ {
+ {"date", ATTRTYPE_ANY, 1},
+ {"version", ATTRTYPE_ANY, 0},
+ {"author", ATTRTYPE_ANY, 0},
+ {"author-email", ATTRTYPE_EMAIL, 0},
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ "change", TAGVAL_CHANGE, 3,
+ {
+ TAGVAL_SPEC,
+ TAGVAL_CHANGELOG,
+ TAGVAL_CHANGES,
+ TAGVAL_CHANGE,
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ },
+ {
+ NULL, TAGVAL_LAST, 0,
+ {
+ TAGVAL_LAST
+ },
+ {
+ {NULL, ATTRTYPE_ANY, 1}
+ }
+ }
+};
+
+int verifyXMLPath(const char* szName,
+ t_structXMLParse* pParse)
+{
+ int nFound = -1;
+ int i = 0;
+ int j = 0;
+ int nValue = 0;
+
+ if (pParse->m_nLevel == MAX_XML_LEVELS)
+ return -1;
+
+ while ((nFound == -1) && (g_pXMLTags[i].m_nValue != TAGVAL_LAST)) {
+ if (g_pXMLTags[i].m_nLevel == pParse->m_nLevel) {
+ if (!strcasecmp(szName, g_pXMLTags[i].m_szName)) {
+ nFound = i;
+ for (j = 0; j < pParse->m_nLevel; j++) {
+ // NB: Remember that we are storing the position
+ // of the tag, not the actualv value!!!
+ nValue = g_pXMLTags[pParse->m_naTree[j]].m_nValue;
+ if (nValue != g_pXMLTags[i].m_naTree[j])
+ nFound = -1;
+ }
+ }
+ }
+ i++;
+ }
+
+ if (nFound == -1) {
+ pParse->m_nWarnings++;
+ fprintf(stderr, "warning: %s(%d): Unexpected XML structure/tag \"%s\" found. (Ignoring)\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser), szName);
+ }
+
+ return nFound;
+}
+
+int verifyXMLAttr(const char* szAttr,
+ t_structXMLParse* pParse,
+ int nTagPos)
+{
+ int nFound = -1;
+ int i = 0;
+
+ while ((nFound == -1) && (g_pXMLTags[nTagPos].m_saAttrs[i].m_szName)) {
+ if (!strcasecmp(szAttr, g_pXMLTags[nTagPos].m_saAttrs[i].m_szName))
+ nFound = i;
+ i++;
+ }
+
+ if (nFound == -1) {
+ pParse->m_nWarnings++;
+ fprintf(stderr, "warning: %s(%d): Unexpected tag attribute \"%s\" for tag \"%s\" found.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ szAttr, g_pXMLTags[nTagPos].m_szName);
+ }
+
+ return nFound;
+}
+
+int verifyXMLAttrType(const t_structXMLAttr* pAttr,
+ const t_structXMLAttrAttr* pAttrAttr,
+ t_structXMLParse* pParse,
+ int nTagPos)
+{
+ int i = 0;
+ int nError = 0;
+ char* szTmp;
+ char* szOld;
+ FILE* fTmp;
+
+ if (!pAttr->m_szValue || !strlen(pAttr->m_szValue)) {
+ pParse->m_nErrors++;
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" does not have a value.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ return ++nError;
+ }
+
+ switch (pAttrAttr->m_nType) {
+ case ATTRTYPE_ALPHA:
+ while ((!nError) && (pAttr->m_szValue[i])) {
+ if (!isalpha(pAttr->m_szValue[i])) {
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" contains non-alphabetic characters.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ nError++;
+ }
+ i++;
+ }
+ break;
+ case ATTRTYPE_NUMERIC:
+ while ((!nError) && (pAttr->m_szValue[i])) {
+ if (!isdigit(pAttr->m_szValue[i])) {
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" contains non-numeric characters.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ nError++;
+ }
+ i++;
+ }
+ break;
+ case ATTRTYPE_BOOL:
+ nError++;
+ if (!strcasecmp(pAttr->m_szValue, "yes") ||
+ !strcasecmp(pAttr->m_szValue, "no") ||
+ !strcasecmp(pAttr->m_szValue, "true") ||
+ !strcasecmp(pAttr->m_szValue, "false") ||
+ !strcasecmp(pAttr->m_szValue, "0") ||
+ !strcasecmp(pAttr->m_szValue, "1"))
+ nError = 0;
+ if (nError) {
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" does not contain a valid boolean value. Allowed values are: \"yes\"/\"no\", \"true\"/\"false\" or \"1\"/\"0\" combinations.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ }
+ break;
+ case ATTRTYPE_EMAIL:
+ break;
+ case ATTRTYPE_DATE:
+ break;
+ case ATTRTYPE_CMP:
+ nError++;
+ if (!strcasecmp(pAttr->m_szValue, "eq") ||
+ !strcasecmp(pAttr->m_szValue, "lt") ||
+ !strcasecmp(pAttr->m_szValue, "le") ||
+ !strcasecmp(pAttr->m_szValue, "gt") ||
+ !strcasecmp(pAttr->m_szValue, "ge"))
+ nError = 0;
+ if (nError) {
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" does not contain a valid comparison value. Allowed values are: \"eq\" (equal), \"lt\" (less), \"le\" (less or equal), \"gt\" (greater) and \"ge\" (greater or equal).\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ }
+ break;
+ case ATTRTYPE_SCRIPT:
+ /*nError++;
+ szTmp = NULL;
+ szOld = NULL;
+ newStr(pAttr->m_szValue, &szOld);
+ if (g_szSpecPath) {
+ szTmp = malloc(strlen(g_szSpecPath)+strlen(szOld)+2);
+ sprintf(szTmp, "%s/%s", g_szSpecPath, szOld);
+ }
+ else {
+ szTmp = malloc(strlen(szOld)+2);
+ sprintf(szTmp, "%s", szOld);
+ }
+ newStrEx(szTmp, (char**)&(pAttr->m_szValue));
+ if ((fTmp = fopen(pAttr->m_szValue, "r"))) {
+ nError = 0;
+ fclose(fTmp);
+ freeStr(&szOld);
+ }
+ freeStr(&szTmp);
+ if (!nError)
+ break;
+ newStrEx(szOld, (char**)&(pAttr->m_szValue));
+ freeStr(&szOld);
+ nError = 0;*/
+ case ATTRTYPE_SRCFILE:
+ nError++;
+ szTmp = NULL;
+ szOld = NULL;
+ newStr(pAttr->m_szValue, &szOld);
+ szTmp = malloc(strlen("%%{_sourcedir}")+strlen(pAttr->m_szValue)+2);
+ sprintf(szTmp, "%%{_sourcedir}/%s", szOld);
+ newStrEx(szTmp, (char**)&(pAttr->m_szValue));
+ if ((fTmp = fopen(pAttr->m_szValue, "r"))) {
+ nError = 0;
+ fclose(fTmp);
+ }
+
+ if (nError) {
+ fprintf(stderr, "error: %s(%d): File \"%s\" (attribute \"%s\" for tag \"%s\") does not exist.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szValue,
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ newStr(szOld, (char**)&(pAttr->m_szValue));
+ }
+ freeStr(&szTmp);
+ freeStr(&szOld);
+ break;
+ case ATTRTYPE_URL:
+ break;
+ case ATTRTYPE_MD5:
+ if (strlen(pAttr->m_szValue) != 32) {
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" does not contain a valid MD5 sum.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ nError++;
+ }
+ break;
+ case ATTRTYPE_COUNTRY:
+ if (strlen(pAttr->m_szValue) != 2) {
+ fprintf(stderr, "error: %s(%d): Attribute \"%s\" for tag \"%s\" does not contain a valid country code.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ nError++;
+ }
+ case ATTRTYPE_ANY:
+ default:
+ break;
+ }
+
+ return nError;
+}
+
+int verifyXMLAttrs(const char** szaAttrs,
+ t_structXMLParse* pParse,
+ int nTagPos)
+
+{
+ int i = 0;
+ int nRet = 1;
+ int nFound = 0;
+ int nAttrPos = 0;
+ t_structXMLAttr* pAttr = NULL;
+
+ // add all tags
+ freeXMLAttr(&(pParse->m_pAttrs));
+ for (i = 0; szaAttrs[i]; i += 2) {
+ if ((nAttrPos = verifyXMLAttr(szaAttrs[i], pParse, nTagPos)) != -1)
+ addXMLAttr(szaAttrs[i], szaAttrs[i+1],
+ g_pXMLTags[nTagPos].m_saAttrs[nAttrPos].m_nType,
+ &(pParse->m_pAttrs));
+ }
+
+ // verify mandatory tags and check attribute type
+ for (i = 0; g_pXMLTags[nTagPos].m_saAttrs[i].m_szName; i++) {
+ pAttr = pParse->m_pAttrs;
+ nFound = 0;
+ while ((!nFound) && (pAttr)) {
+ if (!strcasecmp(pAttr->m_szName,
+ g_pXMLTags[nTagPos].m_saAttrs[i].m_szName)) {
+ nFound = 1;
+ pParse->m_nErrors += verifyXMLAttrType(pAttr,
+ &(g_pXMLTags[nTagPos].m_saAttrs[i]),
+ pParse, nTagPos);
+ }
+ else
+ pAttr = pAttr->m_pNext;
+ }
+ if ((!nFound) && (g_pXMLTags[nTagPos].m_saAttrs[i].m_nMandatory)) {
+ pParse->m_nErrors++;
+ fprintf(stderr, "error: %s(%d): Mandatory attribute (%s) for tag \"%s\" not found.\n",
+ pParse->m_szXMLFile,
+ XML_GetCurrentLineNumber(pParse->m_pParser),
+ g_pXMLTags[nTagPos].m_saAttrs[i].m_szName,
+ g_pXMLTags[nTagPos].m_szName);
+ nRet = -1;
+ }
+ }
+
+ return nRet;
+}
--- /dev/null
+#ifndef _XML_VERIFY_H_
+#define _XML_VERIFY_H_
+
+#include "xmlparse.h"
+
+typedef enum enumXMLTagVals
+{
+ TAGVAL_SPEC = 0,
+ TAGVAL_MACRO,
+ TAGVAL_SOURCE,
+ TAGVAL_SOURCEMIRROR,
+ TAGVAL_PATCH,
+ TAGVAL_PATCHMIRROR,
+ TAGVAL_BUILDREQUIRES,
+ TAGVAL_BUILDREQUIRE,
+ TAGVAL_BUILDSUGGESTS,
+ TAGVAL_BUILDSUGGEST,
+ TAGVAL_PACKAGE,
+ TAGVAL_PROVIDE,
+ TAGVAL_PROVIDES,
+ TAGVAL_REQUIRES,
+ TAGVAL_REQUIRE,
+ TAGVAL_OBSOLETES,
+ TAGVAL_OBSOLETE,
+ TAGVAL_SUGGESTS,
+ TAGVAL_SUGGEST,
+ TAGVAL_SUMMARY,
+ TAGVAL_DESCRIPTION,
+ TAGVAL_PRE,
+ TAGVAL_POST,
+ TAGVAL_PREUN,
+ TAGVAL_POSTUN,
+ TAGVAL_VERIFY,
+ TAGVAL_FILES,
+ TAGVAL_PREP,
+ TAGVAL_BUILD,
+ TAGVAL_INSTALL,
+ TAGVAL_CLEAN,
+ TAGVAL_SCRIPT,
+ TAGVAL_SETUPMACRO,
+ TAGVAL_PATCHMACRO,
+ TAGVAL_CHANGELOG,
+ TAGVAL_CHANGES,
+ TAGVAL_CHANGE,
+ TAGVAL_LAST = 0xFFFF
+} t_enumXMLTagVals;
+
+typedef enum enumXMLAttrTypes
+{
+ ATTRTYPE_ANY = 0,
+ ATTRTYPE_ALPHA,
+ ATTRTYPE_NUMERIC,
+ ATTRTYPE_BOOL,
+ ATTRTYPE_EMAIL,
+ ATTRTYPE_DATE,
+ ATTRTYPE_CMP,
+ ATTRTYPE_SRCFILE,
+ ATTRTYPE_SCRIPT,
+ ATTRTYPE_URL,
+ ATTRTYPE_MD5,
+ ATTRTYPE_COUNTRY,
+ ATTRTYPE_LAST = 0xFFFF
+} t_enumXMLAttrTypes;
+
+typedef struct structXMLAttrAttr
+{
+ char* m_szName;
+ int m_nType;
+ int m_nMandatory;
+} t_structXMLAttrAttr;
+
+typedef struct structXMLTags
+{
+ char* m_szName;
+ int m_nValue;
+ int m_nLevel;
+ int m_naTree[MAX_XML_LEVELS];
+ t_structXMLAttrAttr m_saAttrs[MAX_XML_ATTRS];
+} t_structXMLTags;
+
+#ifndef NO_XMLTAGS_EXTERN
+extern t_structXMLTags g_pXMLTags[];
+#endif
+
+int verifyXMLPath(const char* szName,
+ t_structXMLParse* pParse);
+
+int verifyXMLAttr(const char* szAttr,
+ t_structXMLParse* pParse,
+ int nTagPos);
+
+int verifyXMLAttrs(const char** szaAttrs,
+ t_structXMLParse* pParse,
+ int nTagPos);
+
+#endif
+