diff options
author | jbj <devnull@localhost> | 1998-07-25 21:00:26 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 1998-07-25 21:00:26 +0000 |
commit | e4151252f8c4e422e18f83616392e3dc53d6d1ab (patch) | |
tree | 2cf6ab880ad881f509ba84c4657dd978592c1698 /build | |
parent | c617a31606aec7fccaf26e0947f15f4cbacf089b (diff) | |
download | librpm-tizen-e4151252f8c4e422e18f83616392e3dc53d6d1ab.tar.gz librpm-tizen-e4151252f8c4e422e18f83616392e3dc53d6d1ab.tar.bz2 librpm-tizen-e4151252f8c4e422e18f83616392e3dc53d6d1ab.zip |
Aggregate system includes into system.h.
Rearrange functions to minimize exported routines in librpmbuild API.
VS: ----------------------------------------------------------------------
CVS patchset: 2183
CVS date: 1998/07/25 21:00:26
Diffstat (limited to 'build')
-rw-r--r-- | build/Makefile.in | 2 | ||||
-rw-r--r-- | build/build.c | 263 | ||||
-rw-r--r-- | build/files.c | 2017 | ||||
-rw-r--r-- | build/macro.c | 15 | ||||
-rw-r--r-- | build/misc.c | 188 | ||||
-rw-r--r-- | build/misc.h | 5 | ||||
-rw-r--r-- | build/myftw.c | 15 | ||||
-rw-r--r-- | build/names.c | 7 | ||||
-rw-r--r-- | build/pack.c | 11 | ||||
-rw-r--r-- | build/package.c | 4 | ||||
-rw-r--r-- | build/parseBuildInstallClean.c | 2 | ||||
-rw-r--r-- | build/parseChangelog.c | 10 | ||||
-rw-r--r-- | build/parseDescription.c | 2 | ||||
-rw-r--r-- | build/parseFiles.c | 3 | ||||
-rw-r--r-- | build/parsePreamble.c | 328 | ||||
-rw-r--r-- | build/parsePrep.c | 7 | ||||
-rw-r--r-- | build/parseReqs.c | 2 | ||||
-rw-r--r-- | build/parseScript.c | 4 | ||||
-rw-r--r-- | build/parseSpec.c | 6 | ||||
-rw-r--r-- | build/part.c | 2 | ||||
-rw-r--r-- | build/read.c | 44 | ||||
-rw-r--r-- | build/reqprov.c | 145 | ||||
-rw-r--r-- | build/reqprov.h | 3 | ||||
-rw-r--r-- | build/spec.c | 286 | ||||
-rw-r--r-- | build/spec.h | 9 |
25 files changed, 1660 insertions, 1720 deletions
diff --git a/build/Makefile.in b/build/Makefile.in index c5251db71..b013509e1 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -33,7 +33,7 @@ $(PROGS): $(LIBOBJECTS) pack.o: pack.c $(CC) $(CFLAGS) -DVERSION=\"$(VERSION)\" -o $@ -c $< -reqprov.o: reqprov.c +files.o: files.c $(CC) $(CFLAGS) -DFINDPROVIDES=\"$(FINDPROVIDES)\" -DFINDREQUIRES=\"$(FINDREQUIRES)\" -o $@ -c $< spec.o: spec.c diff --git a/build/build.c b/build/build.c index 49e4d288a..8ffc02d8d 100644 --- a/build/build.c +++ b/build/build.c @@ -1,13 +1,4 @@ -#include "config.h" - -#ifdef HAVE_ALLOCA_A -#include <alloca.h> -#endif - -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <stdlib.h> +#include "system.h" #include "misc.h" #include "spec.h" @@ -18,84 +9,80 @@ #include "pack.h" #include "files.h" +#ifdef DYING static void doRmSource(Spec spec); static int writeVars(Spec spec, FILE *f); +#endif -int buildSpec(Spec spec, int what, int test) +static void doRmSource(Spec spec) { - int x, rc; + struct Source *p; + Package pkg; + char buf[BUFSIZ]; + + unlink(spec->specFile); - if (!spec->inBuildArchitectures && spec->buildArchitectureCount) { - /* When iterating over buildArchitectures, do the source */ - /* packaging on the first run, and skip RMSOURCE altogether */ - x = 0; - while (x < spec->buildArchitectureCount) { - if ((rc = buildSpec(spec->buildArchitectureSpecs[x], - (what & ~RPMBUILD_RMSOURCE) | - (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)), - test))) { - return rc; - } - x++; - } - } else { - if (what & RPMBUILD_PREP) { - if ((rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test))) { - return rc; - } - } - if (what & RPMBUILD_BUILD) { - if ((rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test))) { - return rc; - } - } - if (what & RPMBUILD_INSTALL) { - if ((rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test))) { - return rc; - } + p = spec->sources; + while (p) { + if (! (p->flags & RPMBUILD_ISNO)) { + sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), p->source); + unlink(buf); } + p = p->next; + } - if (what & RPMBUILD_PACKAGESOURCE) { - if ((rc = processSourceFiles(spec))) { - return rc; + pkg = spec->packages; + while (pkg) { + p = pkg->icon; + while (p) { + if (! (p->flags & RPMBUILD_ISNO)) { + sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), p->source); + unlink(buf); } + p = p->next; } + pkg = pkg->next; + } +} - if ((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) || - (what & RPMBUILD_FILECHECK)) { - if ((rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, - test))) { - return rc; - } - } +static int writeVars(Spec spec, FILE *f) +{ + char *arch, *os, *s; + + rpmGetArchInfo(&arch, NULL); + rpmGetOsInfo(&os, NULL); - if (what & RPMBUILD_PACKAGESOURCE && !test) { - if ((rc = packageSources(spec))) { - return rc; - } - } - if (what & RPMBUILD_PACKAGEBINARY && !test) { - if ((rc = packageBinaries(spec))) { - return rc; - } - } - - if (what & RPMBUILD_CLEAN) { - if ((rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test))) { - return rc; - } - } - if (what & RPMBUILD_RMBUILD) { - if ((rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test))) { - return rc; - } - } - } + fprintf(f, "RPM_SOURCE_DIR=\"%s\"\n", rpmGetVar(RPMVAR_SOURCEDIR)); + fprintf(f, "RPM_BUILD_DIR=\"%s\"\n", rpmGetVar(RPMVAR_BUILDDIR)); + fprintf(f, "RPM_DOC_DIR=\"%s\"\n", spec->docDir); + fprintf(f, "RPM_OPT_FLAGS=\"%s\"\n", rpmGetVar(RPMVAR_OPTFLAGS)); + fprintf(f, "RPM_ARCH=\"%s\"\n", arch); + fprintf(f, "RPM_OS=\"%s\"\n", os); + fprintf(f, "export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_DOC_DIR " + "RPM_OPT_FLAGS RPM_ARCH RPM_OS\n"); - if (what & RPMBUILD_RMSOURCE) { - doRmSource(spec); + if (spec->buildRoot) { + fprintf(f, "RPM_BUILD_ROOT=\"%s\"\n", spec->buildRoot); + fprintf(f, "export RPM_BUILD_ROOT\n"); + /* This could really be checked internally */ + fprintf(f, "if [ -z \"$RPM_BUILD_ROOT\" -o -z \"`echo $RPM_BUILD_ROOT | sed -e 's#/##g'`\" ]; then\n"); + fprintf(f, " echo 'Warning: Spec contains BuildRoot: tag that is either empty or is set to \"/\"'\n"); + fprintf(f, " exit 1\n"); + fprintf(f, "fi\n"); } + headerGetEntry(spec->packages->header, RPMTAG_NAME, + NULL, (void **)&s, NULL); + fprintf(f, "RPM_PACKAGE_NAME=\"%s\"\n", s); + headerGetEntry(spec->packages->header, RPMTAG_VERSION, + NULL, (void **)&s, NULL); + fprintf(f, "RPM_PACKAGE_VERSION=\"%s\"\n", s); + headerGetEntry(spec->packages->header, RPMTAG_RELEASE, + NULL, (void **)&s, NULL); + fprintf(f, "RPM_PACKAGE_RELEASE=\"%s\"\n", s); + fprintf(f, "export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION " + "RPM_PACKAGE_RELEASE\n"); + return 0; } @@ -198,74 +185,80 @@ int doScript(Spec spec, int what, char *name, StringBuf sb, int test) return 0; } -static int writeVars(Spec spec, FILE *f) +int buildSpec(Spec spec, int what, int test) { - char *arch, *os, *s; - - rpmGetArchInfo(&arch, NULL); - rpmGetOsInfo(&os, NULL); - - fprintf(f, "RPM_SOURCE_DIR=\"%s\"\n", rpmGetVar(RPMVAR_SOURCEDIR)); - fprintf(f, "RPM_BUILD_DIR=\"%s\"\n", rpmGetVar(RPMVAR_BUILDDIR)); - fprintf(f, "RPM_DOC_DIR=\"%s\"\n", spec->docDir); - fprintf(f, "RPM_OPT_FLAGS=\"%s\"\n", rpmGetVar(RPMVAR_OPTFLAGS)); - fprintf(f, "RPM_ARCH=\"%s\"\n", arch); - fprintf(f, "RPM_OS=\"%s\"\n", os); - fprintf(f, "export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_DOC_DIR " - "RPM_OPT_FLAGS RPM_ARCH RPM_OS\n"); - - if (spec->buildRoot) { - fprintf(f, "RPM_BUILD_ROOT=\"%s\"\n", spec->buildRoot); - fprintf(f, "export RPM_BUILD_ROOT\n"); - /* This could really be checked internally */ - fprintf(f, "if [ -z \"$RPM_BUILD_ROOT\" -o -z \"`echo $RPM_BUILD_ROOT | sed -e 's#/##g'`\" ]; then\n"); - fprintf(f, " echo 'Warning: Spec contains BuildRoot: tag that is either empty or is set to \"/\"'\n"); - fprintf(f, " exit 1\n"); - fprintf(f, "fi\n"); - } + int x, rc; - headerGetEntry(spec->packages->header, RPMTAG_NAME, - NULL, (void **)&s, NULL); - fprintf(f, "RPM_PACKAGE_NAME=\"%s\"\n", s); - headerGetEntry(spec->packages->header, RPMTAG_VERSION, - NULL, (void **)&s, NULL); - fprintf(f, "RPM_PACKAGE_VERSION=\"%s\"\n", s); - headerGetEntry(spec->packages->header, RPMTAG_RELEASE, - NULL, (void **)&s, NULL); - fprintf(f, "RPM_PACKAGE_RELEASE=\"%s\"\n", s); - fprintf(f, "export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION " - "RPM_PACKAGE_RELEASE\n"); - - return 0; -} + if (!spec->inBuildArchitectures && spec->buildArchitectureCount) { + /* When iterating over buildArchitectures, do the source */ + /* packaging on the first run, and skip RMSOURCE altogether */ + x = 0; + while (x < spec->buildArchitectureCount) { + if ((rc = buildSpec(spec->buildArchitectureSpecs[x], + (what & ~RPMBUILD_RMSOURCE) | + (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)), + test))) { + return rc; + } + x++; + } + } else { + if (what & RPMBUILD_PREP) { + if ((rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test))) { + return rc; + } + } + if (what & RPMBUILD_BUILD) { + if ((rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test))) { + return rc; + } + } + if (what & RPMBUILD_INSTALL) { + if ((rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test))) { + return rc; + } + } -static void doRmSource(Spec spec) -{ - struct Source *p; - Package pkg; - char buf[BUFSIZ]; - - unlink(spec->specFile); + if (what & RPMBUILD_PACKAGESOURCE) { + if ((rc = processSourceFiles(spec))) { + return rc; + } + } - p = spec->sources; - while (p) { - if (! (p->flags & RPMBUILD_ISNO)) { - sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), p->source); - unlink(buf); + if ((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) || + (what & RPMBUILD_FILECHECK)) { + if ((rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, + test))) { + return rc; + } } - p = p->next; - } - pkg = spec->packages; - while (pkg) { - p = pkg->icon; - while (p) { - if (! (p->flags & RPMBUILD_ISNO)) { - sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), p->source); - unlink(buf); + if (what & RPMBUILD_PACKAGESOURCE && !test) { + if ((rc = packageSources(spec))) { + return rc; + } + } + if (what & RPMBUILD_PACKAGEBINARY && !test) { + if ((rc = packageBinaries(spec))) { + return rc; + } + } + + if (what & RPMBUILD_CLEAN) { + if ((rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test))) { + return rc; + } + } + if (what & RPMBUILD_RMBUILD) { + if ((rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test))) { + return rc; } - p = p->next; } - pkg = pkg->next; } + + if (what & RPMBUILD_RMSOURCE) { + doRmSource(spec); + } + + return 0; } diff --git a/build/files.c b/build/files.c index 3ac47913f..e0a38d391 100644 --- a/build/files.c +++ b/build/files.c @@ -1,15 +1,8 @@ -#include "config.h" -#ifdef HAVE_GLOB_H -# include <glob.h> -#else -# include "misc-glob.h" -#endif +#include "system.h" -#include <string.h> -#include <malloc.h> -#include <stdlib.h> -#include <sys/types.h> #include <regex.h> +#include <signal.h> /* getOutputFrom() */ +#include <time.h> #include "spec.h" #include "package.h" @@ -24,6 +17,8 @@ #include "messages.h" #include "macro.h" #include "build.h" +#include "read.h" +#include "reqprov.h" #define MAXDOCDIR 1024 @@ -84,6 +79,7 @@ struct FileList { int fileListRecsUsed; }; +#ifdef DYING static int processPackageFiles(Spec spec, Package pkg, int installSpecialDoc, int test); static void freeFileList(struct FileListRec *fileList, int count); @@ -105,427 +101,594 @@ static void genCpioListAndHeader(struct FileList *fl, struct cpioFileMapping **cpioList, int *cpioCount, Header h, int isSrc); static char *strtokWithQuotes(char *s, char *delim); +#endif -int processSourceFiles(Spec spec) +/* glob_pattern_p() taken from bash + * Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc. + * + * Return nonzero if PATTERN has any special globbing chars in it. + */ +static int myGlobPatternP (char *pattern) { - struct Source *srcPtr; - char buf[BUFSIZ]; - StringBuf sourceFiles; - int x, isSpec = 1; - struct FileList fl; - char *s, **files, **fp, *fn; - struct stat sb; - HeaderIterator hi; - int tag, type, count; - Package pkg; - void * ptr; + register char *p = pattern; + register char c; + int open = 0; + + while ((c = *p++) != '\0') + switch (c) { + case '?': + case '*': + return (1); + case '[': /* Only accept an open brace if there is a close */ + open++; /* brace to match it. Bracket expressions must be */ + continue; /* complete, according to Posix.2 */ + case ']': + if (open) + return (1); + continue; + case '\\': + if (*p++ == '\0') + return (0); + } - sourceFiles = newStringBuf(); - spec->sourceHeader = headerNew(); + return (0); +} - /* Only specific tags are added to the source package header */ - hi = headerInitIterator(spec->packages->header); - while (headerNextIterator(hi, &tag, &type, &ptr, &count)) { - switch (tag) { - case RPMTAG_NAME: - case RPMTAG_VERSION: - case RPMTAG_RELEASE: - case RPMTAG_SERIAL: - case RPMTAG_SUMMARY: - case RPMTAG_DESCRIPTION: - case RPMTAG_PACKAGER: - case RPMTAG_DISTRIBUTION: - case RPMTAG_VENDOR: - case RPMTAG_COPYRIGHT: - case RPMTAG_GROUP: - case RPMTAG_OS: - case RPMTAG_ARCH: - case RPMTAG_CHANGELOGTIME: - case RPMTAG_CHANGELOGNAME: - case RPMTAG_CHANGELOGTEXT: - case RPMTAG_URL: - case HEADER_I18NTABLE: - headerAddEntry(spec->sourceHeader, tag, type, ptr, count); - break; - default: - /* do not copy */ - break; - } - if (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE) { - FREE(ptr); - } +static int glob_error(const char *foo, int bar) +{ + return 1; +} + +/* strtokWithQuotes() modified from glibc strtok() */ +/* Copyright (C) 1991, 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +static char *strtokWithQuotes(char *s, char *delim) +{ + static char *olds = NULL; + char *token; + + if (s == NULL) { + s = olds; } - headerFreeIterator(hi); - /* Construct the file list and source entries */ - appendLineStringBuf(sourceFiles, spec->specFile); - srcPtr = spec->sources; - while (srcPtr) { - if (srcPtr->flags & RPMBUILD_ISSOURCE) { - headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_SOURCE, - RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1); - if (srcPtr->flags & RPMBUILD_ISNO) { - headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOSOURCE, - RPM_INT32_TYPE, &srcPtr->num, 1); - } - } - if (srcPtr->flags & RPMBUILD_ISPATCH) { - headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_PATCH, - RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1); - if (srcPtr->flags & RPMBUILD_ISNO) { - headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOPATCH, - RPM_INT32_TYPE, &srcPtr->num, 1); - } - } - sprintf(buf, "%s%s/%s", - srcPtr->flags & RPMBUILD_ISNO ? "!" : "", - rpmGetVar(RPMVAR_SOURCEDIR), srcPtr->source); - appendLineStringBuf(sourceFiles, buf); - srcPtr = srcPtr->next; + /* Skip leading delimiters */ + s += strspn(s, delim); + if (*s == '\0') { + return NULL; } - pkg = spec->packages; - while (pkg) { - srcPtr = pkg->icon; - while (srcPtr) { - sprintf(buf, "%s%s/%s", - srcPtr->flags & RPMBUILD_ISNO ? "!" : "", - rpmGetVar(RPMVAR_SOURCEDIR), srcPtr->source); - appendLineStringBuf(sourceFiles, buf); - srcPtr = srcPtr->next; - } - pkg = pkg->next; + /* Find the end of the token. */ + token = s; + if (*token == '"') { + token++; + /* Find next " char */ + s = strchr(token, '"'); + } else { + s = strpbrk(token, delim); } - spec->sourceCpioList = NULL; - spec->sourceCpioCount = 0; + /* Terminate it */ + if (s == NULL) { + /* This token finishes the string */ + olds = strchr(token, '\0'); + } else { + /* Terminate the token and make olds point past it */ + *s = '\0'; + olds = s+1; + } - fl.fileList = malloc((spec->numSources + 1) * sizeof(struct FileListRec)); - fl.processingFailed = 0; - fl.fileListRecsUsed = 0; - fl.totalFileSize = 0; - fl.prefix = NULL; + return token; +} - s = getStringBuf(sourceFiles); - files = splitString(s, strlen(s), '\n'); - fp = files; +static void timeCheck(int tc, Header h) +{ + int *mtime; + char **file; + int count, x, currentTime; - /* The first source file is the spec file */ + headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &file, &count); + headerGetEntry(h, RPMTAG_FILEMTIMES, NULL, (void **) &mtime, NULL); + + currentTime = time(NULL); + x = 0; - while (*fp) { - s = *fp; - SKIPSPACE(s); - if (! *s) { - fp++; continue; + while (x < count) { + if (currentTime - mtime[x] > tc) { + rpmMessage(RPMMESS_WARNING, "TIMECHECK failure: %s\n", file[x]); } + x++; + } +} - fl.fileList[x].flags = isSpec ? RPMFILE_SPECFILE : 0; - /* files with leading ! are no source files */ - if (*s == '!') { - fl.fileList[x].flags |= RPMFILE_GHOST; - s++; - } - fl.fileList[x].diskName = strdup(s); - fn = strrchr(s, '/'); - if (fn) { - fn++; - } else { - fn = s; - } - fl.fileList[x].fileName = strdup(fn); - fl.fileList[x].verifyFlags = RPMVERIFY_ALL; - stat(s, &sb); - fl.fileList[x].mode = sb.st_mode; - fl.fileList[x].uid = sb.st_uid; - fl.fileList[x].gid = sb.st_gid; - fl.fileList[x].uname = getUname(sb.st_uid); - fl.fileList[x].gname = getGname(sb.st_gid); - fl.fileList[x].size = sb.st_size; - fl.fileList[x].mtime = sb.st_mtime; - fl.fileList[x].rdev = sb.st_rdev; - fl.fileList[x].device = sb.st_dev; - fl.fileList[x].inode = sb.st_ino; - fl.fileList[x].lang = strdup(""); - - fl.totalFileSize += sb.st_size; - - if (! (fl.fileList[x].uname && fl.fileList[x].gname)) { - rpmError(RPMERR_BADSPEC, "Bad owner/group: %s", s); - fl.processingFailed = 1; +static int parseForVerify(char *buf, struct FileList *fl) +{ + char *p, *start, *end, *name; + char ourbuf[BUFSIZ]; + int not, verifyFlags; + int *resultVerify; + + if (!(p = start = strstr(buf, "%verify"))) { + if (!(p = start = strstr(buf, "%defverify"))) { + return 0; } + name = "%defverify"; + resultVerify = &(fl->defVerifyFlags); + p += 10; + } else { + name = "%verify"; + resultVerify = &(fl->currentVerifyFlags); + p += 7; + } - isSpec = 0; - fp++; - x++; + SKIPSPACE(p); + + if (*p != '(') { + rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; } - fl.fileListRecsUsed = x; - freeSplitString(files); + p++; - if (! fl.processingFailed) { - genCpioListAndHeader(&fl, &(spec->sourceCpioList), - &(spec->sourceCpioCount), spec->sourceHeader, 1); + end = p; + while (*end && *end != ')') { + end++; } - freeStringBuf(sourceFiles); - freeFileList(fl.fileList, fl.fileListRecsUsed); - return fl.processingFailed; -} + if (! *end) { + rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } -int processBinaryFiles(Spec spec, int installSpecialDoc, int test) -{ - Package pkg; - int res, rc; - char *name; - - pkg = spec->packages; - res = 0; - while (pkg) { - if (!pkg->fileList) { - pkg = pkg->next; - continue; - } + strncpy(ourbuf, p, end-p); + ourbuf[end-p] = '\0'; + while (start <= end) { + *start++ = ' '; + } - headerGetEntry(pkg->header, RPMTAG_NAME, NULL, (void **)&name, NULL); - rpmMessage(RPMMESS_NORMAL, "Processing files: %s\n", name); - - if ((rc = processPackageFiles(spec, pkg, installSpecialDoc, test))) { - res = rc; + p = strtok(ourbuf, ", \n\t"); + not = 0; + verifyFlags = RPMVERIFY_NONE; + while (p) { + if (!strcmp(p, "not")) { + not = 1; + } else if (!strcmp(p, "md5")) { + verifyFlags |= RPMVERIFY_MD5; + } else if (!strcmp(p, "size")) { + verifyFlags |= RPMVERIFY_FILESIZE; + } else if (!strcmp(p, "link")) { + verifyFlags |= RPMVERIFY_LINKTO; + } else if (!strcmp(p, "user")) { + verifyFlags |= RPMVERIFY_USER; + } else if (!strcmp(p, "group")) { + verifyFlags |= RPMVERIFY_GROUP; + } else if (!strcmp(p, "mtime")) { + verifyFlags |= RPMVERIFY_MTIME; + } else if (!strcmp(p, "mode")) { + verifyFlags |= RPMVERIFY_MODE; + } else if (!strcmp(p, "rdev")) { + verifyFlags |= RPMVERIFY_RDEV; + } else { + rpmError(RPMERR_BADSPEC, "Invalid %s token: %s", name, p); + fl->processingFailed = 1; + return RPMERR_BADSPEC; } - - generateAutoReqProv(spec, pkg, pkg->cpioList, pkg->cpioCount); - printReqs(spec, pkg); - - pkg = pkg->next; + p = strtok(NULL, ", \n\t"); } - return res; + *resultVerify = not ? ~(verifyFlags) : verifyFlags; + + return 0; } -static int processPackageFiles(Spec spec, Package pkg, - int installSpecialDoc, int test) +static int parseForAttr(char *buf, struct FileList *fl) { - struct FileList fl; - char *s, **files, **fp, *fileName; - char buf[BUFSIZ]; - FILE *f; + char *p, *s, *start, *end, *name; + char ourbuf[1024]; + int x, defattr = 0; + struct AttrRec *resultAttr; - struct AttrRec specialDocAttrRec; - char *specialDoc = NULL; - - pkg->cpioList = NULL; - pkg->cpioCount = 0; + if (!(p = start = strstr(buf, "%attr"))) { + if (!(p = start = strstr(buf, "%defattr"))) { + return 0; + } + defattr = 1; + name = "%defattr"; + resultAttr = &(fl->def); + p += 8; + } else { + name = "%attr"; + resultAttr = &(fl->current); + p += 5; + } - if (pkg->fileFile) { - if (spec->buildSubdir) { - sprintf(buf, "%s/%s/%s", rpmGetVar(RPMVAR_BUILDDIR), - spec->buildSubdir, pkg->fileFile); - } else { - sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_BUILDDIR), pkg->fileFile); + resultAttr->PmodeString = resultAttr->Uname = resultAttr->Gname = NULL; + + SKIPSPACE(p); + + if (*p != '(') { + rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + p++; + + end = p; + while (*end && *end != ')') { + end++; + } + + if (! *end) { + rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + + if (defattr) { + s = end; + s++; + SKIPSPACE(s); + if (*s) { + rpmError(RPMERR_BADSPEC, + "No files after %%defattr(): %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; } - if ((f = fopen(buf, "r")) == NULL) { - rpmError(RPMERR_BADFILENAME, - "Could not open %%files file: %s", pkg->fileFile); - return RPMERR_BADFILENAME; + } + + strncpy(ourbuf, p, end-p); + ourbuf[end-p] = '\0'; + + resultAttr->PmodeString = strtok(ourbuf, ", \n\t"); + resultAttr->Uname = strtok(NULL, ", \n\t"); + resultAttr->Gname = strtok(NULL, ", \n\t"); + resultAttr->PdirmodeString = strtok(NULL, ", \n\t"); + + if (! (resultAttr->PmodeString && + resultAttr->Uname && resultAttr->Gname)) { + rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); + resultAttr->PmodeString = resultAttr->Uname = resultAttr->Gname = NULL; + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + + /* Do a quick test on the mode argument and adjust for "-" */ + if (!strcmp(resultAttr->PmodeString, "-")) { + resultAttr->PmodeString = NULL; + } else { + x = sscanf(resultAttr->PmodeString, "%o", &(resultAttr->Pmode)); + if ((x == 0) || (resultAttr->Pmode >> 12)) { + rpmError(RPMERR_BADSPEC, "Bad %s() mode spec: %s", name, buf); + resultAttr->PmodeString = resultAttr->Uname = + resultAttr->Gname = NULL; + fl->processingFailed = 1; + return RPMERR_BADSPEC; } - while (fgets(buf, sizeof(buf), f)) { - handleComments(buf); - if (expandMacros(spec, &spec->macros, buf, sizeof(buf))) { - rpmError(RPMERR_BADSPEC, "line: %s", buf); + resultAttr->PmodeString = strdup(resultAttr->PmodeString); + } + if (resultAttr->PdirmodeString) { + /* The processing here is slightly different to maintain */ + /* compatibility with old spec files. */ + if (!strcmp(resultAttr->PdirmodeString, "-")) { + resultAttr->PdirmodeString = strdup(resultAttr->PdirmodeString); + } else { + x = sscanf(resultAttr->PdirmodeString, "%o", + &(resultAttr->Pdirmode)); + if ((x == 0) || (resultAttr->Pdirmode >> 12)) { + rpmError(RPMERR_BADSPEC, + "Bad %s() dirmode spec: %s", name, buf); + resultAttr->PmodeString = resultAttr->Uname = + resultAttr->Gname = resultAttr->PdirmodeString = NULL; + fl->processingFailed = 1; return RPMERR_BADSPEC; } - appendStringBuf(pkg->fileList, buf); + resultAttr->PdirmodeString = strdup(resultAttr->PdirmodeString); } - fclose(f); } - - /* Init the file list structure */ - - fl.buildRoot = spec->buildRoot ? spec->buildRoot : ""; - if (headerGetEntry(pkg->header, RPMTAG_DEFAULTPREFIX, - NULL, (void *)&fl.prefix, NULL)) { - fl.prefix = strdup(fl.prefix); + if (!strcmp(resultAttr->Uname, "-")) { + resultAttr->Uname = NULL; } else { - fl.prefix = NULL; + resultAttr->Uname = strdup(resultAttr->Uname); + } + if (!strcmp(resultAttr->Gname, "-")) { + resultAttr->Gname = NULL; + } else { + resultAttr->Gname = strdup(resultAttr->Gname); } - - fl.fileCount = 0; - fl.totalFileSize = 0; - fl.processingFailed = 0; - - fl.passedSpecialDoc = 0; - fl.current.PmodeString = NULL; - fl.current.PdirmodeString = NULL; - fl.current.Uname = NULL; - fl.current.Gname = NULL; - fl.def.PmodeString = NULL; - fl.def.PdirmodeString = NULL; - fl.def.Uname = NULL; - fl.def.Gname = NULL; - fl.def.Pmode = 0; - fl.def.Pdirmode = 0; - fl.currentLang = NULL; + /* Set everything we just parsed to blank spaces */ + while (start <= end) { + *start++ = ' '; + } - fl.defVerifyFlags = RPMVERIFY_ALL; + return 0; +} - fl.docDirCount = 0; - fl.docDirs[fl.docDirCount++] = strdup("/usr/doc"); - fl.docDirs[fl.docDirCount++] = strdup("/usr/man"); - fl.docDirs[fl.docDirCount++] = strdup("/usr/info"); - fl.docDirs[fl.docDirCount++] = strdup("/usr/X11R6/man"); - fl.docDirs[fl.docDirCount++] = strdup(spec->docDir); - - fl.fileList = NULL; - fl.fileListRecsAlloced = 0; - fl.fileListRecsUsed = 0; +static int parseForConfig(char *buf, struct FileList *fl) +{ + char *p, *start, *end; + char ourbuf[1024]; - s = getStringBuf(pkg->fileList); - files = splitString(s, strlen(s), '\n'); - fp = files; + if (!(p = start = strstr(buf, "%config"))) { + return 0; + } + fl->currentFlags = RPMFILE_CONFIG; - while (*fp) { - s = *fp; - SKIPSPACE(s); - if (! *s) { - fp++; continue; - } - fileName = NULL; - strcpy(buf, s); - - /* Reset for a new line in %files */ - fl.isDir = 0; - fl.inFtw = 0; - fl.currentFlags = 0; - fl.currentVerifyFlags = fl.defVerifyFlags; - fl.current.Pmode = fl.def.Pmode; - fl.current.Pdirmode = fl.def.Pdirmode; - fl.isSpecialDoc = 0; - FREE(fl.current.PmodeString); - FREE(fl.current.PdirmodeString); - FREE(fl.current.Uname); - FREE(fl.current.Gname); - FREE(fl.currentLang); - if (fl.def.PmodeString) { - fl.current.PmodeString = strdup(fl.def.PmodeString); - } - if (fl.def.PdirmodeString) { - fl.current.PdirmodeString = strdup(fl.def.PdirmodeString); - } - if (fl.def.Uname) { - fl.current.Uname = strdup(fl.def.Uname); - } - if (fl.def.Gname) { - fl.current.Gname = strdup(fl.def.Gname); - } + p += 7; + SKIPSPACE(p); - if (parseForVerify(buf, &fl)) { - fp++; continue; - } - if (parseForAttr(buf, &fl)) { - fp++; continue; + if (*p != '(') { + while (start < p) { + *start++ = ' '; } - if (parseForConfig(buf, &fl)) { - fp++; continue; + return 0; + } + p++; + + end = p; + while (*end && *end != ')') { + end++; + } + + if (! *end) { + rpmError(RPMERR_BADSPEC, "Bad %%config() syntax: %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + + strncpy(ourbuf, p, end-p); + ourbuf[end-p] = '\0'; + while (start <= end) { + *start++ = ' '; + } + + p = strtok(ourbuf, ", \n\t"); + while (p) { + if (!strcmp(p, "missingok")) { + fl->currentFlags |= RPMFILE_MISSINGOK; + } else if (!strcmp(p, "noreplace")) { + fl->currentFlags |= RPMFILE_NOREPLACE; + } else { + rpmError(RPMERR_BADSPEC, "Invalid %%config token: %s", p); + fl->processingFailed = 1; + return RPMERR_BADSPEC; } - if (parseForLang(buf, &fl)) { - fp++; continue; + p = strtok(NULL, ", \n\t"); + } + + return 0; +} + +static int parseForLang(char *buf, struct FileList *fl) +{ + char *p, *start, *end; + char ourbuf[1024]; + + if (!(p = start = strstr(buf, "%lang"))) { + return 0; + } + + p += 5; + SKIPSPACE(p); + + if (*p != '(') { + rpmError(RPMERR_BADSPEC, "Bad %%lang() syntax: %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + p++; + + end = p; + while (*end && *end != ')') { + end++; + } + + if (! *end) { + rpmError(RPMERR_BADSPEC, "Bad %%lang() syntax: %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + + strncpy(ourbuf, p, end-p); + ourbuf[end-p] = '\0'; + while (start <= end) { + *start++ = ' '; + } + + p = strtok(ourbuf, ", \n\t"); + if (!p) { + rpmError(RPMERR_BADSPEC, "Bad %%lang() syntax: %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + if (strlen(p) != 2) { + rpmError(RPMERR_BADSPEC, "%%lang() entries are 2 characters: %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + if (strtok(NULL, ", \n\t")) { + rpmError(RPMERR_BADSPEC, "Only one entry in %%lang(): %s", buf); + fl->processingFailed = 1; + return RPMERR_BADSPEC; + } + fl->currentLang = strdup(p); + + return 0; +} + +static int parseForRegexLang(char *fileName, char **lang) +{ + static int initialized = 0; + static int hasRegex = 0; + static regex_t compiledPatt; + static char buf[BUFSIZ]; + int x; + regmatch_t matches[2]; + char *patt, *s; + + if (! initialized) { + initialized = 1; + patt = rpmGetVar(RPMVAR_LANGPATT); + if (! patt) { + return 1; } - if (parseForSimple(spec, pkg, buf, &fl, &fileName)) { - fp++; continue; + if (regcomp(&compiledPatt, patt, REG_EXTENDED)) { + return -1; } - if (! fileName) { - fp++; continue; + hasRegex = 1; + } + + if (! hasRegex) { + return 1; + } + + if (! regexec(&compiledPatt, fileName, 2, matches, REG_NOTEOL)) { + /* Got match */ + s = fileName + matches[1].rm_eo - 1; + x = matches[1].rm_eo - matches[1].rm_so; + buf[x] = '\0'; + while (x) { + buf[--x] = *s--; } + *lang = buf; + return 0; + } - if (fl.isSpecialDoc) { - /* Save this stuff for last */ - specialDoc = strdup(fileName); - specialDocAttrRec = fl.current; - if (specialDocAttrRec.PmodeString) { - specialDocAttrRec.PmodeString = - strdup(specialDocAttrRec.PmodeString); + return 1; +} + +static int parseForSimple(Spec spec, Package pkg, char *buf, + struct FileList *fl, char **fileName) +{ + char *s; + int res, specialDoc = 0; + char *name, *version; + char specialDocBuf[BUFSIZ]; + + specialDocBuf[0] = '\0'; + *fileName = NULL; + res = 0; + s = strtokWithQuotes(buf, " \t\n"); + while (s) { + if (!strcmp(s, "%docdir")) { + s = strtokWithQuotes(NULL, " \t\n"); + if (fl->docDirCount == MAXDOCDIR) { + rpmError(RPMERR_INTERNAL, "Hit limit for %%docdir"); + fl->processingFailed = 1; + res = 1; } - if (specialDocAttrRec.PdirmodeString) { - specialDocAttrRec.PdirmodeString = - strdup(specialDocAttrRec.PdirmodeString); + fl->docDirs[fl->docDirCount++] = strdup(s); + if (strtokWithQuotes(NULL, " \t\n")) { + rpmError(RPMERR_INTERNAL, "Only one arg for %%docdir"); + fl->processingFailed = 1; + res = 1; } - if (specialDocAttrRec.Uname) { - specialDocAttrRec.Uname = strdup(specialDocAttrRec.Uname); + break; + } else if (!strcmp(s, "%doc")) { + fl->currentFlags |= RPMFILE_DOC; + } else if (!strcmp(s, "%ghost")) { + fl->currentFlags |= RPMFILE_GHOST; + } else if (!strcmp(s, "%dir")) { + fl->isDir = 1; + } else { + if (*fileName) { + /* We already got a file -- error */ + rpmError(RPMERR_BADSPEC, + "Two files on one line: %s", *fileName); + fl->processingFailed = 1; + res = 1; } - if (specialDocAttrRec.Gname) { - specialDocAttrRec.Gname = strdup(specialDocAttrRec.Gname); + if (*s != '/') { + if (fl->currentFlags & RPMFILE_DOC) { + specialDoc = 1; + strcat(specialDocBuf, " "); + strcat(specialDocBuf, s); + } else { + /* not in %doc, does not begin with / -- error */ + rpmError(RPMERR_BADSPEC, + "File must begin with \"/\": %s", s); + fl->processingFailed = 1; + res = 1; + } + } else { + *fileName = s; } - } else { - processBinaryFile(pkg, &fl, fileName); } - - fp++; + s = strtokWithQuotes(NULL, " \t\n"); } - /* Now process special doc, if there is one */ if (specialDoc) { - if (installSpecialDoc) { - doScript(spec, RPMBUILD_STRINGBUF, "%doc", pkg->specialDoc, test); - } + if (*fileName || (fl->currentFlags & ~(RPMFILE_DOC))) { + rpmError(RPMERR_BADSPEC, + "Can't mix special %%doc with other forms: %s", + *fileName); + fl->processingFailed = 1; + res = 1; + } else { + headerGetEntry(pkg->header, RPMTAG_NAME, NULL, + (void *) &name, NULL); + headerGetEntry(pkg->header, RPMTAG_VERSION, NULL, + (void *) &version, NULL); + sprintf(buf, "%s/%s-%s", spec->docDir, name, version); - /* fl.current now takes on "ownership" of the specialDocAttrRec */ - /* allocated string data. */ - fl.current = specialDocAttrRec; - fl.isDir = 0; - fl.inFtw = 0; - fl.currentFlags = 0; - fl.currentVerifyFlags = 0; - processBinaryFile(pkg, &fl, specialDoc); - FREE(specialDoc); - } - - freeSplitString(files); + if (! fl->passedSpecialDoc) { + pkg->specialDoc = newStringBuf(); + appendStringBuf(pkg->specialDoc, "DOCDIR=$RPM_BUILD_ROOT"); + appendLineStringBuf(pkg->specialDoc, buf); + appendLineStringBuf(pkg->specialDoc, "export DOCDIR"); + appendLineStringBuf(pkg->specialDoc, "rm -rf $DOCDIR"); + appendLineStringBuf(pkg->specialDoc, MKDIR_P " $DOCDIR"); - if (! fl.processingFailed) { - genCpioListAndHeader(&fl, &(pkg->cpioList), &(pkg->cpioCount), - pkg->header, 0); + *fileName = buf; + fl->passedSpecialDoc = 1; + fl->isSpecialDoc = 1; + } - if (spec->timeCheck) { - timeCheck(spec->timeCheck, pkg->header); + appendStringBuf(pkg->specialDoc, "cp -pr "); + appendStringBuf(pkg->specialDoc, specialDocBuf); + appendLineStringBuf(pkg->specialDoc, " $DOCDIR"); } } - - /* Clean up */ - FREE(fl.prefix); - FREE(fl.current.PmodeString); - FREE(fl.current.PdirmodeString); - FREE(fl.current.Uname); - FREE(fl.current.Gname); - FREE(fl.def.PmodeString); - FREE(fl.def.PdirmodeString); - FREE(fl.def.Uname); - FREE(fl.def.Gname); - FREE(fl.currentLang); - freeFileList(fl.fileList, fl.fileListRecsUsed); - while (fl.docDirCount--) { - FREE(fl.docDirs[fl.docDirCount]); - } - return fl.processingFailed; + + return res; } -static void timeCheck(int tc, Header h) +static int compareFileListRecs(const void *ap, const void *bp) { - int *mtime; - char **file; - int count, x, currentTime; + char *a, *b; - headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &file, &count); - headerGetEntry(h, RPMTAG_FILEMTIMES, NULL, (void **) &mtime, NULL); + a = ((struct FileListRec *)ap)->fileName; + b = ((struct FileListRec *)bp)->fileName; - currentTime = time(NULL); - - x = 0; - while (x < count) { - if (currentTime - mtime[x] > tc) { - rpmMessage(RPMMESS_WARNING, "TIMECHECK failure: %s\n", file[x]); - } - x++; + return strcmp(a, b); +} + +static int isDoc(struct FileList *fl, char *fileName) +{ + int x = fl->docDirCount; + + while (x--) { + if (strstr(fileName, fl->docDirs[x]) == fileName) { + return 1; + } } + return 0; } static void genCpioListAndHeader(struct FileList *fl, @@ -674,85 +837,6 @@ static void freeFileList(struct FileListRec *fileList, int count) FREE(fileList); } -void freeCpioList(struct cpioFileMapping *cpioList, int cpioCount) -{ - struct cpioFileMapping *p = cpioList; - - while (cpioCount--) { - rpmMessage(RPMMESS_DEBUG, "archive = %s, fs = %s\n", - p->archivePath, p->fsPath); - FREE(p->archivePath); - FREE(p->fsPath); - p++; - } - FREE(cpioList); -} - -static int compareFileListRecs(const void *ap, const void *bp) -{ - char *a, *b; - - a = ((struct FileListRec *)ap)->fileName; - b = ((struct FileListRec *)bp)->fileName; - - return strcmp(a, b); -} - -static int isDoc(struct FileList *fl, char *fileName) -{ - int x = fl->docDirCount; - - while (x--) { - if (strstr(fileName, fl->docDirs[x]) == fileName) { - return 1; - } - } - return 0; -} - -static int processBinaryFile(Package pkg, struct FileList *fl, char *fileName) -{ - char fullname[BUFSIZ]; - glob_t glob_result; - int x, offset, rc = 0; - - /* check that file starts with leading "/" */ - if (*fileName != '/') { - rpmError(RPMERR_BADSPEC, "File needs leading \"/\": %s", *fileName); - fl->processingFailed = 1; - return 1; - } - - if (myGlobPatternP(fileName)) { - if (fl->buildRoot) { - sprintf(fullname, "%s%s", fl->buildRoot, fileName); - offset = strlen(fl->buildRoot); - } else { - strcpy(fullname, fileName); - offset = 0; - } - - if (glob(fullname, 0, glob_error, &glob_result) || - (glob_result.gl_pathc < 1)) { - rpmError(RPMERR_BADSPEC, "File not found: %s", fullname); - fl->processingFailed = 1; - globfree(&glob_result); - return 1; - } - - x = 0; - while (x < glob_result.gl_pathc) { - rc = addFile(fl, &(glob_result.gl_pathv[x][offset]), NULL); - x++; - } - globfree(&glob_result); - } else { - rc = addFile(fl, fileName, NULL); - } - - return rc; -} - static int addFile(struct FileList *fl, char *name, struct stat *statp) { char fileName[BUFSIZ]; @@ -893,548 +977,705 @@ static int addFile(struct FileList *fl, char *name, struct stat *statp) return 0; } -static int parseForSimple(Spec spec, Package pkg, char *buf, - struct FileList *fl, char **fileName) +static int processBinaryFile(Package pkg, struct FileList *fl, char *fileName) { - char *s; - int res, specialDoc = 0; - char *name, *version; - char specialDocBuf[BUFSIZ]; - - specialDocBuf[0] = '\0'; - *fileName = NULL; - res = 0; - s = strtokWithQuotes(buf, " \t\n"); - while (s) { - if (!strcmp(s, "%docdir")) { - s = strtokWithQuotes(NULL, " \t\n"); - if (fl->docDirCount == MAXDOCDIR) { - rpmError(RPMERR_INTERNAL, "Hit limit for %%docdir"); - fl->processingFailed = 1; - res = 1; - } - fl->docDirs[fl->docDirCount++] = strdup(s); - if (strtokWithQuotes(NULL, " \t\n")) { - rpmError(RPMERR_INTERNAL, "Only one arg for %%docdir"); - fl->processingFailed = 1; - res = 1; - } - break; - } else if (!strcmp(s, "%doc")) { - fl->currentFlags |= RPMFILE_DOC; - } else if (!strcmp(s, "%ghost")) { - fl->currentFlags |= RPMFILE_GHOST; - } else if (!strcmp(s, "%dir")) { - fl->isDir = 1; + char fullname[BUFSIZ]; + glob_t glob_result; + int x, offset, rc = 0; + + /* check that file starts with leading "/" */ + if (*fileName != '/') { + rpmError(RPMERR_BADSPEC, "File needs leading \"/\": %s", *fileName); + fl->processingFailed = 1; + return 1; + } + + if (myGlobPatternP(fileName)) { + if (fl->buildRoot) { + sprintf(fullname, "%s%s", fl->buildRoot, fileName); + offset = strlen(fl->buildRoot); } else { - if (*fileName) { - /* We already got a file -- error */ - rpmError(RPMERR_BADSPEC, - "Two files on one line: %s", *fileName); - fl->processingFailed = 1; - res = 1; - } - if (*s != '/') { - if (fl->currentFlags & RPMFILE_DOC) { - specialDoc = 1; - strcat(specialDocBuf, " "); - strcat(specialDocBuf, s); - } else { - /* not in %doc, does not begin with / -- error */ - rpmError(RPMERR_BADSPEC, - "File must begin with \"/\": %s", s); - fl->processingFailed = 1; - res = 1; - } - } else { - *fileName = s; - } + strcpy(fullname, fileName); + offset = 0; } - s = strtokWithQuotes(NULL, " \t\n"); - } - - if (specialDoc) { - if (*fileName || (fl->currentFlags & ~(RPMFILE_DOC))) { - rpmError(RPMERR_BADSPEC, - "Can't mix special %%doc with other forms: %s", - *fileName); + + if (glob(fullname, 0, glob_error, &glob_result) || + (glob_result.gl_pathc < 1)) { + rpmError(RPMERR_BADSPEC, "File not found: %s", fullname); fl->processingFailed = 1; - res = 1; - } else { - headerGetEntry(pkg->header, RPMTAG_NAME, NULL, - (void *) &name, NULL); - headerGetEntry(pkg->header, RPMTAG_VERSION, NULL, - (void *) &version, NULL); - sprintf(buf, "%s/%s-%s", spec->docDir, name, version); - - if (! fl->passedSpecialDoc) { - pkg->specialDoc = newStringBuf(); - appendStringBuf(pkg->specialDoc, "DOCDIR=$RPM_BUILD_ROOT"); - appendLineStringBuf(pkg->specialDoc, buf); - appendLineStringBuf(pkg->specialDoc, "export DOCDIR"); - appendLineStringBuf(pkg->specialDoc, "rm -rf $DOCDIR"); - appendLineStringBuf(pkg->specialDoc, MKDIR_P " $DOCDIR"); - - *fileName = buf; - fl->passedSpecialDoc = 1; - fl->isSpecialDoc = 1; - } - - appendStringBuf(pkg->specialDoc, "cp -pr "); - appendStringBuf(pkg->specialDoc, specialDocBuf); - appendLineStringBuf(pkg->specialDoc, " $DOCDIR"); + globfree(&glob_result); + return 1; + } + + x = 0; + while (x < glob_result.gl_pathc) { + rc = addFile(fl, &(glob_result.gl_pathv[x][offset]), NULL); + x++; } + globfree(&glob_result); + } else { + rc = addFile(fl, fileName, NULL); } - return res; + return rc; } -static int parseForVerify(char *buf, struct FileList *fl) +static int processPackageFiles(Spec spec, Package pkg, + int installSpecialDoc, int test) { - char *p, *start, *end, *name; - char ourbuf[BUFSIZ]; - int not, verifyFlags; - int *resultVerify; + struct FileList fl; + char *s, **files, **fp, *fileName; + char buf[BUFSIZ]; + FILE *f; - if (!(p = start = strstr(buf, "%verify"))) { - if (!(p = start = strstr(buf, "%defverify"))) { - return 0; + struct AttrRec specialDocAttrRec; + char *specialDoc = NULL; + + pkg->cpioList = NULL; + pkg->cpioCount = 0; + + if (pkg->fileFile) { + if (spec->buildSubdir) { + sprintf(buf, "%s/%s/%s", rpmGetVar(RPMVAR_BUILDDIR), + spec->buildSubdir, pkg->fileFile); + } else { + sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_BUILDDIR), pkg->fileFile); } - name = "%defverify"; - resultVerify = &(fl->defVerifyFlags); - p += 10; + if ((f = fopen(buf, "r")) == NULL) { + rpmError(RPMERR_BADFILENAME, + "Could not open %%files file: %s", pkg->fileFile); + return RPMERR_BADFILENAME; + } + while (fgets(buf, sizeof(buf), f)) { + handleComments(buf); + if (expandMacros(spec, &spec->macros, buf, sizeof(buf))) { + rpmError(RPMERR_BADSPEC, "line: %s", buf); + return RPMERR_BADSPEC; + } + appendStringBuf(pkg->fileList, buf); + } + fclose(f); + } + + /* Init the file list structure */ + + fl.buildRoot = spec->buildRoot ? spec->buildRoot : ""; + if (headerGetEntry(pkg->header, RPMTAG_DEFAULTPREFIX, + NULL, (void *)&fl.prefix, NULL)) { + fl.prefix = strdup(fl.prefix); } else { - name = "%verify"; - resultVerify = &(fl->currentVerifyFlags); - p += 7; + fl.prefix = NULL; } - SKIPSPACE(p); + fl.fileCount = 0; + fl.totalFileSize = 0; + fl.processingFailed = 0; - if (*p != '(') { - rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } - p++; + fl.passedSpecialDoc = 0; + + fl.current.PmodeString = NULL; + fl.current.PdirmodeString = NULL; + fl.current.Uname = NULL; + fl.current.Gname = NULL; + fl.def.PmodeString = NULL; + fl.def.PdirmodeString = NULL; + fl.def.Uname = NULL; + fl.def.Gname = NULL; + fl.def.Pmode = 0; + fl.def.Pdirmode = 0; + fl.currentLang = NULL; - end = p; - while (*end && *end != ')') { - end++; - } + fl.defVerifyFlags = RPMVERIFY_ALL; - if (! *end) { - rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } + fl.docDirCount = 0; + fl.docDirs[fl.docDirCount++] = strdup("/usr/doc"); + fl.docDirs[fl.docDirCount++] = strdup("/usr/man"); + fl.docDirs[fl.docDirCount++] = strdup("/usr/info"); + fl.docDirs[fl.docDirCount++] = strdup("/usr/X11R6/man"); + fl.docDirs[fl.docDirCount++] = strdup(spec->docDir); + + fl.fileList = NULL; + fl.fileListRecsAlloced = 0; + fl.fileListRecsUsed = 0; - strncpy(ourbuf, p, end-p); - ourbuf[end-p] = '\0'; - while (start <= end) { - *start++ = ' '; - } + s = getStringBuf(pkg->fileList); + files = splitString(s, strlen(s), '\n'); + fp = files; - p = strtok(ourbuf, ", \n\t"); - not = 0; - verifyFlags = RPMVERIFY_NONE; - while (p) { - if (!strcmp(p, "not")) { - not = 1; - } else if (!strcmp(p, "md5")) { - verifyFlags |= RPMVERIFY_MD5; - } else if (!strcmp(p, "size")) { - verifyFlags |= RPMVERIFY_FILESIZE; - } else if (!strcmp(p, "link")) { - verifyFlags |= RPMVERIFY_LINKTO; - } else if (!strcmp(p, "user")) { - verifyFlags |= RPMVERIFY_USER; - } else if (!strcmp(p, "group")) { - verifyFlags |= RPMVERIFY_GROUP; - } else if (!strcmp(p, "mtime")) { - verifyFlags |= RPMVERIFY_MTIME; - } else if (!strcmp(p, "mode")) { - verifyFlags |= RPMVERIFY_MODE; - } else if (!strcmp(p, "rdev")) { - verifyFlags |= RPMVERIFY_RDEV; + while (*fp) { + s = *fp; + SKIPSPACE(s); + if (! *s) { + fp++; continue; + } + fileName = NULL; + strcpy(buf, s); + + /* Reset for a new line in %files */ + fl.isDir = 0; + fl.inFtw = 0; + fl.currentFlags = 0; + fl.currentVerifyFlags = fl.defVerifyFlags; + fl.current.Pmode = fl.def.Pmode; + fl.current.Pdirmode = fl.def.Pdirmode; + fl.isSpecialDoc = 0; + FREE(fl.current.PmodeString); + FREE(fl.current.PdirmodeString); + FREE(fl.current.Uname); + FREE(fl.current.Gname); + FREE(fl.currentLang); + if (fl.def.PmodeString) { + fl.current.PmodeString = strdup(fl.def.PmodeString); + } + if (fl.def.PdirmodeString) { + fl.current.PdirmodeString = strdup(fl.def.PdirmodeString); + } + if (fl.def.Uname) { + fl.current.Uname = strdup(fl.def.Uname); + } + if (fl.def.Gname) { + fl.current.Gname = strdup(fl.def.Gname); + } + + if (parseForVerify(buf, &fl)) { + fp++; continue; + } + if (parseForAttr(buf, &fl)) { + fp++; continue; + } + if (parseForConfig(buf, &fl)) { + fp++; continue; + } + if (parseForLang(buf, &fl)) { + fp++; continue; + } + if (parseForSimple(spec, pkg, buf, &fl, &fileName)) { + fp++; continue; + } + if (! fileName) { + fp++; continue; + } + + if (fl.isSpecialDoc) { + /* Save this stuff for last */ + specialDoc = strdup(fileName); + specialDocAttrRec = fl.current; + if (specialDocAttrRec.PmodeString) { + specialDocAttrRec.PmodeString = + strdup(specialDocAttrRec.PmodeString); + } + if (specialDocAttrRec.PdirmodeString) { + specialDocAttrRec.PdirmodeString = + strdup(specialDocAttrRec.PdirmodeString); + } + if (specialDocAttrRec.Uname) { + specialDocAttrRec.Uname = strdup(specialDocAttrRec.Uname); + } + if (specialDocAttrRec.Gname) { + specialDocAttrRec.Gname = strdup(specialDocAttrRec.Gname); + } } else { - rpmError(RPMERR_BADSPEC, "Invalid %s token: %s", name, p); - fl->processingFailed = 1; - return RPMERR_BADSPEC; + processBinaryFile(pkg, &fl, fileName); } - p = strtok(NULL, ", \n\t"); + + fp++; } - *resultVerify = not ? ~(verifyFlags) : verifyFlags; + /* Now process special doc, if there is one */ + if (specialDoc) { + if (installSpecialDoc) { + doScript(spec, RPMBUILD_STRINGBUF, "%doc", pkg->specialDoc, test); + } - return 0; -} + /* fl.current now takes on "ownership" of the specialDocAttrRec */ + /* allocated string data. */ + fl.current = specialDocAttrRec; + fl.isDir = 0; + fl.inFtw = 0; + fl.currentFlags = 0; + fl.currentVerifyFlags = 0; + processBinaryFile(pkg, &fl, specialDoc); + FREE(specialDoc); + } + + freeSplitString(files); -static int parseForRegexLang(char *fileName, char **lang) -{ - static int initialized = 0; - static int hasRegex = 0; - static regex_t compiledPatt; - static char buf[BUFSIZ]; - int x; - regmatch_t matches[2]; - char *patt, *s; + if (! fl.processingFailed) { + genCpioListAndHeader(&fl, &(pkg->cpioList), &(pkg->cpioCount), + pkg->header, 0); - if (! initialized) { - initialized = 1; - patt = rpmGetVar(RPMVAR_LANGPATT); - if (! patt) { - return 1; - } - if (regcomp(&compiledPatt, patt, REG_EXTENDED)) { - return -1; + if (spec->timeCheck) { + timeCheck(spec->timeCheck, pkg->header); } - hasRegex = 1; } - if (! hasRegex) { - return 1; - } - - if (! regexec(&compiledPatt, fileName, 2, matches, REG_NOTEOL)) { - /* Got match */ - s = fileName + matches[1].rm_eo - 1; - x = matches[1].rm_eo - matches[1].rm_so; - buf[x] = '\0'; - while (x) { - buf[--x] = *s--; - } - *lang = buf; - return 0; + /* Clean up */ + FREE(fl.prefix); + FREE(fl.current.PmodeString); + FREE(fl.current.PdirmodeString); + FREE(fl.current.Uname); + FREE(fl.current.Gname); + FREE(fl.def.PmodeString); + FREE(fl.def.PdirmodeString); + FREE(fl.def.Uname); + FREE(fl.def.Gname); + FREE(fl.currentLang); + freeFileList(fl.fileList, fl.fileListRecsUsed); + while (fl.docDirCount--) { + FREE(fl.docDirs[fl.docDirCount]); } - - return 1; + return fl.processingFailed; } -static int parseForLang(char *buf, struct FileList *fl) +void freeCpioList(struct cpioFileMapping *cpioList, int cpioCount) { - char *p, *start, *end; - char ourbuf[1024]; - - if (!(p = start = strstr(buf, "%lang"))) { - return 0; - } - - p += 5; - SKIPSPACE(p); + struct cpioFileMapping *p = cpioList; - if (*p != '(') { - rpmError(RPMERR_BADSPEC, "Bad %%lang() syntax: %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; + while (cpioCount--) { + rpmMessage(RPMMESS_DEBUG, "archive = %s, fs = %s\n", + p->archivePath, p->fsPath); + FREE(p->archivePath); + FREE(p->fsPath); + p++; } - p++; + FREE(cpioList); +} - end = p; - while (*end && *end != ')') { - end++; - } +int processSourceFiles(Spec spec) +{ + struct Source *srcPtr; + char buf[BUFSIZ]; + StringBuf sourceFiles; + int x, isSpec = 1; + struct FileList fl; + char *s, **files, **fp, *fn; + struct stat sb; + HeaderIterator hi; + int tag, type, count; + Package pkg; + void * ptr; - if (! *end) { - rpmError(RPMERR_BADSPEC, "Bad %%lang() syntax: %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } + sourceFiles = newStringBuf(); + spec->sourceHeader = headerNew(); - strncpy(ourbuf, p, end-p); - ourbuf[end-p] = '\0'; - while (start <= end) { - *start++ = ' '; + /* Only specific tags are added to the source package header */ + hi = headerInitIterator(spec->packages->header); + while (headerNextIterator(hi, &tag, &type, &ptr, &count)) { + switch (tag) { + case RPMTAG_NAME: + case RPMTAG_VERSION: + case RPMTAG_RELEASE: + case RPMTAG_SERIAL: + case RPMTAG_SUMMARY: + case RPMTAG_DESCRIPTION: + case RPMTAG_PACKAGER: + case RPMTAG_DISTRIBUTION: + case RPMTAG_VENDOR: + case RPMTAG_COPYRIGHT: + case RPMTAG_GROUP: + case RPMTAG_OS: + case RPMTAG_ARCH: + case RPMTAG_CHANGELOGTIME: + case RPMTAG_CHANGELOGNAME: + case RPMTAG_CHANGELOGTEXT: + case RPMTAG_URL: + case HEADER_I18NTABLE: + headerAddEntry(spec->sourceHeader, tag, type, ptr, count); + break; + default: + /* do not copy */ + break; + } + if (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE) { + FREE(ptr); + } } + headerFreeIterator(hi); - p = strtok(ourbuf, ", \n\t"); - if (!p) { - rpmError(RPMERR_BADSPEC, "Bad %%lang() syntax: %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } - if (strlen(p) != 2) { - rpmError(RPMERR_BADSPEC, "%%lang() entries are 2 characters: %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } - if (strtok(NULL, ", \n\t")) { - rpmError(RPMERR_BADSPEC, "Only one entry in %%lang(): %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; + /* Construct the file list and source entries */ + appendLineStringBuf(sourceFiles, spec->specFile); + srcPtr = spec->sources; + while (srcPtr) { + if (srcPtr->flags & RPMBUILD_ISSOURCE) { + headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_SOURCE, + RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1); + if (srcPtr->flags & RPMBUILD_ISNO) { + headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOSOURCE, + RPM_INT32_TYPE, &srcPtr->num, 1); + } + } + if (srcPtr->flags & RPMBUILD_ISPATCH) { + headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_PATCH, + RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1); + if (srcPtr->flags & RPMBUILD_ISNO) { + headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOPATCH, + RPM_INT32_TYPE, &srcPtr->num, 1); + } + } + sprintf(buf, "%s%s/%s", + srcPtr->flags & RPMBUILD_ISNO ? "!" : "", + rpmGetVar(RPMVAR_SOURCEDIR), srcPtr->source); + appendLineStringBuf(sourceFiles, buf); + srcPtr = srcPtr->next; } - fl->currentLang = strdup(p); - - return 0; -} - -static int parseForAttr(char *buf, struct FileList *fl) -{ - char *p, *s, *start, *end, *name; - char ourbuf[1024]; - int x, defattr = 0; - struct AttrRec *resultAttr; - if (!(p = start = strstr(buf, "%attr"))) { - if (!(p = start = strstr(buf, "%defattr"))) { - return 0; + pkg = spec->packages; + while (pkg) { + srcPtr = pkg->icon; + while (srcPtr) { + sprintf(buf, "%s%s/%s", + srcPtr->flags & RPMBUILD_ISNO ? "!" : "", + rpmGetVar(RPMVAR_SOURCEDIR), srcPtr->source); + appendLineStringBuf(sourceFiles, buf); + srcPtr = srcPtr->next; } - defattr = 1; - name = "%defattr"; - resultAttr = &(fl->def); - p += 8; - } else { - name = "%attr"; - resultAttr = &(fl->current); - p += 5; + pkg = pkg->next; } - resultAttr->PmodeString = resultAttr->Uname = resultAttr->Gname = NULL; + spec->sourceCpioList = NULL; + spec->sourceCpioCount = 0; - SKIPSPACE(p); + fl.fileList = malloc((spec->numSources + 1) * sizeof(struct FileListRec)); + fl.processingFailed = 0; + fl.fileListRecsUsed = 0; + fl.totalFileSize = 0; + fl.prefix = NULL; - if (*p != '(') { - rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } - p++; + s = getStringBuf(sourceFiles); + files = splitString(s, strlen(s), '\n'); + fp = files; - end = p; - while (*end && *end != ')') { - end++; - } + /* The first source file is the spec file */ + x = 0; + while (*fp) { + s = *fp; + SKIPSPACE(s); + if (! *s) { + fp++; continue; + } - if (! *end) { - rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; + fl.fileList[x].flags = isSpec ? RPMFILE_SPECFILE : 0; + /* files with leading ! are no source files */ + if (*s == '!') { + fl.fileList[x].flags |= RPMFILE_GHOST; + s++; + } + fl.fileList[x].diskName = strdup(s); + fn = strrchr(s, '/'); + if (fn) { + fn++; + } else { + fn = s; + } + fl.fileList[x].fileName = strdup(fn); + fl.fileList[x].verifyFlags = RPMVERIFY_ALL; + stat(s, &sb); + fl.fileList[x].mode = sb.st_mode; + fl.fileList[x].uid = sb.st_uid; + fl.fileList[x].gid = sb.st_gid; + fl.fileList[x].uname = getUname(sb.st_uid); + fl.fileList[x].gname = getGname(sb.st_gid); + fl.fileList[x].size = sb.st_size; + fl.fileList[x].mtime = sb.st_mtime; + fl.fileList[x].rdev = sb.st_rdev; + fl.fileList[x].device = sb.st_dev; + fl.fileList[x].inode = sb.st_ino; + fl.fileList[x].lang = strdup(""); + + fl.totalFileSize += sb.st_size; + + if (! (fl.fileList[x].uname && fl.fileList[x].gname)) { + rpmError(RPMERR_BADSPEC, "Bad owner/group: %s", s); + fl.processingFailed = 1; + } + + isSpec = 0; + fp++; + x++; } + fl.fileListRecsUsed = x; + freeSplitString(files); - if (defattr) { - s = end; - s++; - SKIPSPACE(s); - if (*s) { - rpmError(RPMERR_BADSPEC, - "No files after %%defattr(): %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } + if (! fl.processingFailed) { + genCpioListAndHeader(&fl, &(spec->sourceCpioList), + &(spec->sourceCpioCount), spec->sourceHeader, 1); } - strncpy(ourbuf, p, end-p); - ourbuf[end-p] = '\0'; + freeStringBuf(sourceFiles); + freeFileList(fl.fileList, fl.fileListRecsUsed); + return fl.processingFailed; +} - resultAttr->PmodeString = strtok(ourbuf, ", \n\t"); - resultAttr->Uname = strtok(NULL, ", \n\t"); - resultAttr->Gname = strtok(NULL, ", \n\t"); - resultAttr->PdirmodeString = strtok(NULL, ", \n\t"); +static StringBuf getOutputFrom(char *dir, char *argv[], + char *writePtr, int writeBytesLeft, + int failNonZero) +{ + int progPID; + int progDead; + int toProg[2]; + int fromProg[2]; + int status; + void *oldhandler; + int bytesWritten; + StringBuf readBuff; + int bytes; + unsigned char buf[8193]; + + oldhandler = signal(SIGPIPE, SIG_IGN); + + pipe(toProg); + pipe(fromProg); + + if (!(progPID = fork())) { + close(toProg[1]); + close(fromProg[0]); + + dup2(toProg[0], 0); /* Make stdin the in pipe */ + dup2(fromProg[1], 1); /* Make stdout the out pipe */ - if (! (resultAttr->PmodeString && - resultAttr->Uname && resultAttr->Gname)) { - rpmError(RPMERR_BADSPEC, "Bad %s() syntax: %s", name, buf); - resultAttr->PmodeString = resultAttr->Uname = resultAttr->Gname = NULL; - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } + close(toProg[0]); + close(fromProg[1]); - /* Do a quick test on the mode argument and adjust for "-" */ - if (!strcmp(resultAttr->PmodeString, "-")) { - resultAttr->PmodeString = NULL; - } else { - x = sscanf(resultAttr->PmodeString, "%o", &(resultAttr->Pmode)); - if ((x == 0) || (resultAttr->Pmode >> 12)) { - rpmError(RPMERR_BADSPEC, "Bad %s() mode spec: %s", name, buf); - resultAttr->PmodeString = resultAttr->Uname = - resultAttr->Gname = NULL; - fl->processingFailed = 1; - return RPMERR_BADSPEC; + if (dir) { + chdir(dir); } - resultAttr->PmodeString = strdup(resultAttr->PmodeString); + + execvp(argv[0], argv); + rpmError(RPMERR_EXEC, "Couldn't exec %s", argv[0]); + _exit(RPMERR_EXEC); } - if (resultAttr->PdirmodeString) { - /* The processing here is slightly different to maintain */ - /* compatibility with old spec files. */ - if (!strcmp(resultAttr->PdirmodeString, "-")) { - resultAttr->PdirmodeString = strdup(resultAttr->PdirmodeString); - } else { - x = sscanf(resultAttr->PdirmodeString, "%o", - &(resultAttr->Pdirmode)); - if ((x == 0) || (resultAttr->Pdirmode >> 12)) { - rpmError(RPMERR_BADSPEC, - "Bad %s() dirmode spec: %s", name, buf); - resultAttr->PmodeString = resultAttr->Uname = - resultAttr->Gname = resultAttr->PdirmodeString = NULL; - fl->processingFailed = 1; - return RPMERR_BADSPEC; + if (progPID < 0) { + rpmError(RPMERR_FORK, "Couldn't fork %s", argv[0]); + return NULL; + } + + close(toProg[0]); + close(fromProg[1]); + + /* Do not block reading or writing from/to prog. */ + fcntl(fromProg[0], F_SETFL, O_NONBLOCK); + fcntl(toProg[1], F_SETFL, O_NONBLOCK); + + readBuff = newStringBuf(); + + progDead = 0; + do { + if (waitpid(progPID, &status, WNOHANG)) { + progDead = 1; + } + + /* Write some stuff to the process if possible */ + if (writeBytesLeft) { + if ((bytesWritten = + write(toProg[1], writePtr, + (1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) { + if (errno != EAGAIN) { + perror("getOutputFrom()"); + exit(1); + } + bytesWritten = 0; } - resultAttr->PdirmodeString = strdup(resultAttr->PdirmodeString); + writeBytesLeft -= bytesWritten; + writePtr += bytesWritten; + } else { + close(toProg[1]); } + + /* Read any data from prog */ + bytes = read(fromProg[0], buf, sizeof(buf)-1); + while (bytes > 0) { + buf[bytes] = '\0'; + appendStringBuf(readBuff, buf); + bytes = read(fromProg[0], buf, sizeof(buf)-1); + } + + /* terminate when prog dies */ + } while (!progDead); + + close(toProg[1]); + close(fromProg[0]); + signal(SIGPIPE, oldhandler); + + if (writeBytesLeft) { + rpmError(RPMERR_EXEC, "failed to write all data to %s", argv[0]); + return NULL; } - if (!strcmp(resultAttr->Uname, "-")) { - resultAttr->Uname = NULL; - } else { - resultAttr->Uname = strdup(resultAttr->Uname); - } - if (!strcmp(resultAttr->Gname, "-")) { - resultAttr->Gname = NULL; - } else { - resultAttr->Gname = strdup(resultAttr->Gname); - } - - /* Set everything we just parsed to blank spaces */ - while (start <= end) { - *start++ = ' '; + waitpid(progPID, &status, 0); + if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) { + rpmError(RPMERR_EXEC, "%s failed", argv[0]); + return NULL; } - return 0; + return readBuff; } -static int parseForConfig(char *buf, struct FileList *fl) +static int generateAutoReqProv(Spec spec, Package pkg, + struct cpioFileMapping *cpioList, int cpioCount) { - char *p, *start, *end; - char ourbuf[1024]; + StringBuf writeBuf; + int writeBytes; + StringBuf readBuf; + char *argv[2]; + char **f, **fsave; - if (!(p = start = strstr(buf, "%config"))) { + if (!cpioCount) { return 0; } - fl->currentFlags = RPMFILE_CONFIG; - p += 7; - SKIPSPACE(p); - - if (*p != '(') { - while (start < p) { - *start++ = ' '; - } + if (! (spec->autoReq || spec->autoProv)) { return 0; } - p++; - - end = p; - while (*end && *end != ')') { - end++; + + writeBuf = newStringBuf(); + writeBytes = 0; + while (cpioCount--) { + writeBytes += strlen(cpioList->fsPath) + 1; + appendLineStringBuf(writeBuf, cpioList->fsPath); + cpioList++; } - if (! *end) { - rpmError(RPMERR_BADSPEC, "Bad %%config() syntax: %s", buf); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } + /*** Do Provides ***/ - strncpy(ourbuf, p, end-p); - ourbuf[end-p] = '\0'; - while (start <= end) { - *start++ = ' '; - } - - p = strtok(ourbuf, ", \n\t"); - while (p) { - if (!strcmp(p, "missingok")) { - fl->currentFlags |= RPMFILE_MISSINGOK; - } else if (!strcmp(p, "noreplace")) { - fl->currentFlags |= RPMFILE_NOREPLACE; - } else { - rpmError(RPMERR_BADSPEC, "Invalid %%config token: %s", p); - fl->processingFailed = 1; - return RPMERR_BADSPEC; + if (spec->autoProv) { + rpmMessage(RPMMESS_NORMAL, "Finding provides...\n"); + + argv[0] = FINDPROVIDES; + argv[1] = NULL; + readBuf = getOutputFrom(NULL, argv, + getStringBuf(writeBuf), writeBytes, 1); + if (!readBuf) { + rpmError(RPMERR_EXEC, "Failed to find provides"); + freeStringBuf(writeBuf); + return RPMERR_EXEC; } - p = strtok(NULL, ", \n\t"); + + f = fsave = splitString(getStringBuf(readBuf), + strlen(getStringBuf(readBuf)), '\n'); + freeStringBuf(readBuf); + while (*f) { + if (**f) { + addReqProv(spec, pkg, RPMSENSE_PROVIDES, *f, NULL, 0); + } + f++; + } + freeSplitString(fsave); } - return 0; -} - -/* glob_pattern_p() taken from bash - * Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc. - * - * Return nonzero if PATTERN has any special globbing chars in it. - */ -static int myGlobPatternP (char *pattern) -{ - register char *p = pattern; - register char c; - int open = 0; - - while ((c = *p++) != '\0') - switch (c) { - case '?': - case '*': - return (1); - case '[': /* Only accept an open brace if there is a close */ - open++; /* brace to match it. Bracket expressions must be */ - continue; /* complete, according to Posix.2 */ - case ']': - if (open) - return (1); - continue; - case '\\': - if (*p++ == '\0') - return (0); - } + /*** Do Requires ***/ - return (0); -} + if (spec->autoReq) { + rpmMessage(RPMMESS_NORMAL, "Finding requires...\n"); -static int glob_error(const char *foo, int bar) -{ - return 1; -} + argv[0] = FINDREQUIRES; + argv[1] = NULL; + readBuf = getOutputFrom(NULL, argv, + getStringBuf(writeBuf), writeBytes, 0); + if (!readBuf) { + rpmError(RPMERR_EXEC, "Failed to find requires"); + freeStringBuf(writeBuf); + return RPMERR_EXEC; + } -/* strtokWithQuotes() modified from glibc strtok() */ -/* Copyright (C) 1991, 1996 Free Software Foundation, Inc. - This file is part of the GNU C Library. + f = fsave = splitString(getStringBuf(readBuf), + strlen(getStringBuf(readBuf)), '\n'); + freeStringBuf(readBuf); + while (*f) { + if (**f) { + addReqProv(spec, pkg, RPMSENSE_ANY, *f, NULL, 0); + } + f++; + } + freeSplitString(fsave); + } - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + /*** Clean Up ***/ - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + freeStringBuf(writeBuf); - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + return 0; +} -static char *strtokWithQuotes(char *s, char *delim) +static void printReqs(Spec spec, Package pkg) { - static char *olds = NULL; - char *token; + int startedPreReq = 0; + int startedReq = 0; - if (s == NULL) { - s = olds; - } + char **names; + int x, count; + int *flags; - /* Skip leading delimiters */ - s += strspn(s, delim); - if (*s == '\0') { - return NULL; + if (headerGetEntry(pkg->header, RPMTAG_PROVIDES, + NULL, (void **) &names, &count)) { + rpmMessage(RPMMESS_NORMAL, "Provides:"); + x = 0; + while (x < count) { + rpmMessage(RPMMESS_NORMAL, " %s", names[x]); + x++; + } + rpmMessage(RPMMESS_NORMAL, "\n"); + FREE(names); } - /* Find the end of the token. */ - token = s; - if (*token == '"') { - token++; - /* Find next " char */ - s = strchr(token, '"'); - } else { - s = strpbrk(token, delim); + if (headerGetEntry(pkg->header, RPMTAG_REQUIRENAME, + NULL, (void **) &names, &count)) { + headerGetEntry(pkg->header, RPMTAG_REQUIREFLAGS, + NULL, (void **) &flags, NULL); + x = 0; + while (x < count) { + if (flags[x] & RPMSENSE_PREREQ) { + if (! startedPreReq) { + rpmMessage(RPMMESS_NORMAL, "Prereqs:"); + startedPreReq = 1; + } + rpmMessage(RPMMESS_NORMAL, " %s", names[x]); + } + x++; + } + if (startedPreReq) { + rpmMessage(RPMMESS_NORMAL, "\n"); + } + x = 0; + while (x < count) { + if (! (flags[x] & RPMSENSE_PREREQ)) { + if (! startedReq) { + rpmMessage(RPMMESS_NORMAL, "Requires:"); + startedReq = 1; + } + rpmMessage(RPMMESS_NORMAL, " %s", names[x]); + } + x++; + } + rpmMessage(RPMMESS_NORMAL, "\n"); + FREE(names); } +} - /* Terminate it */ - if (s == NULL) { - /* This token finishes the string */ - olds = strchr(token, '\0'); - } else { - /* Terminate the token and make olds point past it */ - *s = '\0'; - olds = s+1; +int processBinaryFiles(Spec spec, int installSpecialDoc, int test) +{ + Package pkg; + int res, rc; + char *name; + + pkg = spec->packages; + res = 0; + while (pkg) { + if (!pkg->fileList) { + pkg = pkg->next; + continue; + } + + headerGetEntry(pkg->header, RPMTAG_NAME, NULL, (void **)&name, NULL); + rpmMessage(RPMMESS_NORMAL, "Processing files: %s\n", name); + + if ((rc = processPackageFiles(spec, pkg, installSpecialDoc, test))) { + res = rc; + } + + generateAutoReqProv(spec, pkg, pkg->cpioList, pkg->cpioCount); + printReqs(spec, pkg); + + pkg = pkg->next; } - return token; + return res; } diff --git a/build/macro.c b/build/macro.c index 46682bd7c..5639457a8 100644 --- a/build/macro.c +++ b/build/macro.c @@ -1,9 +1,6 @@ +#include "system.h" + #include <assert.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> #define isblank(_c) ((_c) == ' ' || (_c) == '\t') #define STREQ(_t, _f, _fn) ((_fn) == (sizeof(_t)-1) && !strncmp((_t), (_f), (_fn))) @@ -73,7 +70,6 @@ compareMacroName(const void *ap, const void *bp) static void expandMacroTable(MacroContext *mc) { - int i; if (mc->macroTable == NULL) { mc->macrosAllocated = MACRO_CHUNK_SIZE; mc->macroTable = (MacroEntry **)malloc(sizeof(*(mc->macroTable)) * @@ -493,9 +489,9 @@ dumpME(const char *msg, MacroEntry *me) { if (msg) fprintf(stderr, "%s", msg); - fprintf(stderr, "\tme %x", me); + fprintf(stderr, "\tme %p", me); if (me) - fprintf(stderr,"\tname %x(%s) prev %x", + fprintf(stderr,"\tname %p(%s) prev %p", me->name, me->name, me->prev); fprintf(stderr, "\n"); } @@ -585,7 +581,7 @@ grabArgs(MacroBuf *mb, const MacroEntry *me, const char *se) /* Copy args into buf until newline */ *be++ = ' '; b = be; /* Save beginning of args */ - while (c = *se) { + while ((c = *se) != 0) { char *a; se++; if (c == '\n') @@ -1038,7 +1034,6 @@ expandMacros(Spec spec, MacroContext *mc, char *s, size_t slen) { MacroBuf macrobuf, *mb = ¯obuf; char *tbuf; - int c; int rc; if (s == NULL || slen <= 0) diff --git a/build/misc.c b/build/misc.c index 4b74ec64d..e74bc1eb3 100644 --- a/build/misc.c +++ b/build/misc.c @@ -1,16 +1,4 @@ -#include "config.h" - -#if HAVE_STRING_H -# include <string.h> -#endif - -#include <stdlib.h> -#include <ctype.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/wait.h> -#include <errno.h> -#include <sys/types.h> +#include "system.h" #include "misc.h" #include "spec.h" @@ -18,77 +6,6 @@ #include "header.h" #include "popt/popt.h" -void addOrAppendListEntry(Header h, int_32 tag, char *line) -{ - int argc; - char **argv; - - poptParseArgvString(line, &argc, &argv); - if (argc) { - headerAddOrAppendEntry(h, tag, RPM_STRING_ARRAY_TYPE, argv, argc); - } - FREE(argv); -} - -/* Parse a simple part line that only take -n <pkg> or <pkg> */ -/* <pkg> is return in name as a pointer into a static buffer */ - -int parseSimplePart(char *line, char **name, int *flag) -{ - char *tok; - char linebuf[BUFSIZ]; - static char buf[BUFSIZ]; - - strcpy(linebuf, line); - - /* Throw away the first token (the %xxxx) */ - strtok(linebuf, " \t\n"); - - if (!(tok = strtok(NULL, " \t\n"))) { - *name = NULL; - return 0; - } - - if (!strcmp(tok, "-n")) { - if (!(tok = strtok(NULL, " \t\n"))) { - return 1; - } - *flag = PART_NAME; - } else { - *flag = PART_SUBNAME; - } - strcpy(buf, tok); - *name = buf; - - return (strtok(NULL, " \t\n")) ? 1 : 0; -} - -int parseYesNo(char *s) -{ - if (!s || (s[0] == 'n' || s[0] == 'N') || - !strcasecmp(s, "false") || - !strcasecmp(s, "off") || - !strcmp(s, "0")) { - return 0; - } - - return 1; -} - -char *findLastChar(char *s) -{ - char *res = s; - - while (*s) { - if (! isspace(*s)) { - res = s; - } - s++; - } - - return res; -} - int parseNum(char *line, int *res) { char *s1; @@ -102,109 +19,6 @@ int parseNum(char *line, int *res) return 0; } -StringBuf getOutputFrom(char *dir, char *argv[], - char *writePtr, int writeBytesLeft, - int failNonZero) -{ - int progPID; - int progDead; - int toProg[2]; - int fromProg[2]; - int status; - void *oldhandler; - int bytesWritten; - StringBuf readBuff; - int bytes; - unsigned char buf[8193]; - - oldhandler = signal(SIGPIPE, SIG_IGN); - - pipe(toProg); - pipe(fromProg); - - if (!(progPID = fork())) { - close(toProg[1]); - close(fromProg[0]); - - dup2(toProg[0], 0); /* Make stdin the in pipe */ - dup2(fromProg[1], 1); /* Make stdout the out pipe */ - - close(toProg[0]); - close(fromProg[1]); - - if (dir) { - chdir(dir); - } - - execvp(argv[0], argv); - rpmError(RPMERR_EXEC, "Couldn't exec %s", argv[0]); - _exit(RPMERR_EXEC); - } - if (progPID < 0) { - rpmError(RPMERR_FORK, "Couldn't fork %s", argv[0]); - return NULL; - } - - close(toProg[0]); - close(fromProg[1]); - - /* Do not block reading or writing from/to prog. */ - fcntl(fromProg[0], F_SETFL, O_NONBLOCK); - fcntl(toProg[1], F_SETFL, O_NONBLOCK); - - readBuff = newStringBuf(); - - progDead = 0; - do { - if (waitpid(progPID, &status, WNOHANG)) { - progDead = 1; - } - - /* Write some stuff to the process if possible */ - if (writeBytesLeft) { - if ((bytesWritten = - write(toProg[1], writePtr, - (1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) { - if (errno != EAGAIN) { - perror("getOutputFrom()"); - exit(1); - } - bytesWritten = 0; - } - writeBytesLeft -= bytesWritten; - writePtr += bytesWritten; - } else { - close(toProg[1]); - } - - /* Read any data from prog */ - bytes = read(fromProg[0], buf, sizeof(buf)-1); - while (bytes > 0) { - buf[bytes] = '\0'; - appendStringBuf(readBuff, buf); - bytes = read(fromProg[0], buf, sizeof(buf)-1); - } - - /* terminate when prog dies */ - } while (!progDead); - - close(toProg[1]); - close(fromProg[0]); - signal(SIGPIPE, oldhandler); - - if (writeBytesLeft) { - rpmError(RPMERR_EXEC, "failed to write all data to %s", argv[0]); - return NULL; - } - waitpid(progPID, &status, 0); - if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) { - rpmError(RPMERR_EXEC, "%s failed", argv[0]); - return NULL; - } - - return readBuff; -} - char *cleanFileName(char *name) { static char res[BUFSIZ]; diff --git a/build/misc.h b/build/misc.h index 534bcc708..b88c5c80f 100644 --- a/build/misc.h +++ b/build/misc.h @@ -19,14 +19,17 @@ extern "C" { #endif +#ifdef DYING void addOrAppendListEntry(Header h, int_32 tag, char *line); int parseSimplePart(char *line, char **name, int *flag); char *findLastChar(char *s); int parseYesNo(char *s); -int parseNum(char *line, int *res); StringBuf getOutputFrom(char *dir, char *argv[], char *writePtr, int writeBytesLeft, int failNonZero); +#endif /* DYING */ + +int parseNum(char *line, int *res); char *cleanFileName(char *name); #ifdef __cplusplus diff --git a/build/myftw.c b/build/myftw.c index 0c8a910fc..16656554f 100644 --- a/build/myftw.c +++ b/build/myftw.c @@ -19,20 +19,7 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "config.h" - -#if HAVE_ALLOCA_H -# include <alloca.h> -#endif - -#include <sys/types.h> -#include <errno.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <stdio.h> -#include <sys/stat.h> +#include "system.h" #ifndef NAMLEN #define NAMLEN(a) strlen((a)->d_name) diff --git a/build/names.c b/build/names.c index c619c692c..6850ec100 100644 --- a/build/names.c +++ b/build/names.c @@ -1,14 +1,11 @@ /* names.c -- user/group name/id cache (plus hostname and buildtime) */ -#include <stdio.h> -#include <sys/types.h> +#include "system.h" + #include <pwd.h> #include <grp.h> -#include <string.h> #include <time.h> -#include <unistd.h> #include <netdb.h> -#include <errno.h> #include "names.h" #include "rpmlib.h" diff --git a/build/pack.c b/build/pack.c index 81b34b521..9fc2ee8f2 100644 --- a/build/pack.c +++ b/build/pack.c @@ -1,13 +1,7 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <malloc.h> -#include <string.h> -#include <errno.h> +#include "system.h" + #include <signal.h> #include <time.h> -#include <stdlib.h> #include "spec.h" #include "header.h" @@ -348,7 +342,6 @@ static int cpio_copy(int fdo, CSA_t *csa) { static StringBuf addFileToTagAux(Spec spec, char *file, StringBuf sb) { - char *s; char buf[BUFSIZ]; FILE *f; diff --git a/build/package.c b/build/package.c index df4446c45..fb20934c4 100644 --- a/build/package.c +++ b/build/package.c @@ -1,11 +1,11 @@ +#include "system.h" + #include "spec.h" #include "package.h" #include "misc.h" #include "rpmlib.h" #include "files.h" -#include <stdlib.h> - static void freeTriggerFiles(struct TriggerFileEntry *p); int lookupPackage(Spec spec, char *name, int flag, Package *pkg) diff --git a/build/parseBuildInstallClean.c b/build/parseBuildInstallClean.c index 18643e8f1..76ef92c67 100644 --- a/build/parseBuildInstallClean.c +++ b/build/parseBuildInstallClean.c @@ -1,3 +1,5 @@ +#include "system.h" + #include "read.h" #include "part.h" #include "rpmlib.h" diff --git a/build/parseChangelog.c b/build/parseChangelog.c index a1265979b..6703b8c12 100644 --- a/build/parseChangelog.c +++ b/build/parseChangelog.c @@ -1,14 +1,6 @@ -#include "config.h" +#include "system.h" -#include <stdlib.h> #include <time.h> -#include <string.h> -#include <sys/types.h> - -#ifdef HAVE_ALLOCA_H -# include <alloca.h> -#endif - #include "read.h" #include "part.h" diff --git a/build/parseDescription.c b/build/parseDescription.c index e1bd48687..30c4c8051 100644 --- a/build/parseDescription.c +++ b/build/parseDescription.c @@ -1,4 +1,4 @@ -#include <stdlib.h> +#include "system.h" #include "spec.h" #include "header.h" diff --git a/build/parseFiles.c b/build/parseFiles.c index f7938c24a..f3a1e6621 100644 --- a/build/parseFiles.c +++ b/build/parseFiles.c @@ -1,5 +1,4 @@ -#include <stdlib.h> -#include <string.h> +#include "system.h" #include "header.h" #include "read.h" diff --git a/build/parsePreamble.c b/build/parsePreamble.c index 9a8ab96d6..6fbf4881f 100644 --- a/build/parsePreamble.c +++ b/build/parsePreamble.c @@ -1,9 +1,4 @@ -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <fcntl.h> +#include "system.h" #include "read.h" #include "part.h" @@ -44,6 +39,7 @@ static int requiredTags[] = { 0 }; +#ifdef DYING static int handlePreambleTag(Spec spec, Package pkg, int tag, char *macro, char *lang); static void initPreambleList(void); @@ -56,107 +52,77 @@ static char *tagName(int tag); static int checkForValidArchitectures(Spec spec); static int isMemberInEntry(Header header, char *name, int tag); static int readIcon(Header h, char *file); +#endif /* DYING */ -int parsePreamble(Spec spec, int initialPackage) +static void addOrAppendListEntry(Header h, int_32 tag, char *line) { - int nextPart; - int tag, rc; - char *name, *mainName, *linep, *macro; - int flag; - Package pkg; - char fullName[BUFSIZ]; - char lang[BUFSIZ]; - - strcpy(fullName, "(main package)"); + int argc; + char **argv; - pkg = newPackage(spec); - - if (! initialPackage) { - /* There is one option to %package: <pkg> or -n <pkg> */ - if (parseSimplePart(spec->line, &name, &flag)) { - rpmError(RPMERR_BADSPEC, "Bad package specification: %s", - spec->line); - return RPMERR_BADSPEC; - } - - if (!lookupPackage(spec, name, flag, NULL)) { - rpmError(RPMERR_BADSPEC, "Package already exists: %s", spec->line); - return RPMERR_BADSPEC; - } - - /* Construct the package */ - if (flag == PART_SUBNAME) { - headerGetEntry(spec->packages->header, RPMTAG_NAME, - NULL, (void *) &mainName, NULL); - sprintf(fullName, "%s-%s", mainName, name); - } else { - strcpy(fullName, name); - } - headerAddEntry(pkg->header, RPMTAG_NAME, RPM_STRING_TYPE, fullName, 1); + poptParseArgvString(line, &argc, &argv); + if (argc) { + headerAddOrAppendEntry(h, tag, RPM_STRING_ARRAY_TYPE, argv, argc); } + FREE(argv); +} - if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { - nextPart = PART_NONE; - } else { - if (rc) { - return rc; - } - while (! (nextPart = isPart(spec->line))) { - /* Skip blank lines */ - linep = spec->line; - SKIPSPACE(linep); - if (*linep) { - if (findPreambleTag(spec, &tag, ¯o, lang)) { - rpmError(RPMERR_BADSPEC, "line %d: Unknown tag: %s", - spec->lineNum, spec->line); - return RPMERR_BADSPEC; - } - if (handlePreambleTag(spec, pkg, tag, macro, lang)) { - return RPMERR_BADSPEC; - } - if (spec->buildArchitectures && !spec->inBuildArchitectures) { - return PART_BUILDARCHITECTURES; - } - } - if ((rc = - readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { - nextPart = PART_NONE; - break; - } - if (rc) { - return rc; - } - } - } +/* Parse a simple part line that only take -n <pkg> or <pkg> */ +/* <pkg> is return in name as a pointer into a static buffer */ - /* Do some final processing on the header */ +static int parseSimplePart(char *line, char **name, int *flag) +{ + char *tok; + char linebuf[BUFSIZ]; + static char buf[BUFSIZ]; + + strcpy(linebuf, line); + + /* Throw away the first token (the %xxxx) */ + strtok(linebuf, " \t\n"); - if (!spec->gotBuildRoot && spec->buildRoot) { - rpmError(RPMERR_BADSPEC, "Spec file can't use BuildRoot"); - return RPMERR_BADSPEC; + if (!(tok = strtok(NULL, " \t\n"))) { + *name = NULL; + return 0; } - - if (checkForValidArchitectures(spec)) { - return RPMERR_BADSPEC; + + if (!strcmp(tok, "-n")) { + if (!(tok = strtok(NULL, " \t\n"))) { + return 1; + } + *flag = PART_NAME; + } else { + *flag = PART_SUBNAME; } + strcpy(buf, tok); + *name = buf; - if (pkg == spec->packages) { - fillOutMainPackage(pkg->header); - } + return (strtok(NULL, " \t\n")) ? 1 : 0; +} - if (checkForDuplicates(pkg->header, fullName)) { - return RPMERR_BADSPEC; +static int parseYesNo(char *s) +{ + if (!s || (s[0] == 'n' || s[0] == 'N') || + !strcasecmp(s, "false") || + !strcasecmp(s, "off") || + !strcmp(s, "0")) { + return 0; } - if (pkg != spec->packages) { - copyFromMain(spec, pkg); - } + return 1; +} - if (checkForRequired(pkg->header, fullName)) { - return RPMERR_BADSPEC; +static char *findLastChar(char *s) +{ + char *res = s; + + while (*s) { + if (! isspace(*s)) { + res = s; + } + s++; } - return nextPart; + return res; } static int isMemberInEntry(Header header, char *name, int tag) @@ -209,6 +175,28 @@ static int checkForValidArchitectures(Spec spec) return 0; } +static char *tagName(int tag) +{ + int i = 0; + static char nameBuf[1024]; + char *s; + + strcpy(nameBuf, "(unknown)"); + while (i < rpmTagTableSize) { + if (tag == rpmTagTable[i].val) { + strcpy(nameBuf, rpmTagTable[i].name + 7); + s = nameBuf+1; + while (*s) { + *s = tolower(*s); + s++; + } + } + i++; + } + + return nameBuf; +} + static int checkForRequired(Header h, char *name) { int res = 0; @@ -293,6 +281,39 @@ static void fillOutMainPackage(Header h) } } +static int readIcon(Header h, char *file) +{ + char buf[BUFSIZ], *icon; + struct stat statbuf; + int fd; + + sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), file); + if (stat(buf, &statbuf)) { + rpmError(RPMERR_BADSPEC, "Unable to read icon: %s", file); + return RPMERR_BADSPEC; + } + icon = malloc(statbuf.st_size); + fd = open(buf, O_RDONLY); + if (read(fd, icon, statbuf.st_size) != statbuf.st_size) { + close(fd); + rpmError(RPMERR_BADSPEC, "Unable to read icon: %s", file); + return RPMERR_BADSPEC; + } + close(fd); + + if (! strncmp(icon, "GIF", 3)) { + headerAddEntry(h, RPMTAG_GIF, RPM_BIN_TYPE, icon, statbuf.st_size); + } else if (! strncmp(icon, "/* XPM", 6)) { + headerAddEntry(h, RPMTAG_XPM, RPM_BIN_TYPE, icon, statbuf.st_size); + } else { + rpmError(RPMERR_BADSPEC, "Unknown icon type: %s", file); + return RPMERR_BADSPEC; + } + free(icon); + + return 0; +} + #define SINGLE_TOKEN_ONLY \ if (multiToken) { \ rpmError(RPMERR_BADSPEC, "line %d: Tag takes single token only: %s", \ @@ -609,57 +630,104 @@ static int findPreambleTag(Spec spec, int *tag, char **macro, char *lang) return 0; } -static char *tagName(int tag) +int parsePreamble(Spec spec, int initialPackage) { - int i = 0; - static char nameBuf[1024]; - char *s; + int nextPart; + int tag, rc; + char *name, *mainName, *linep, *macro; + int flag; + Package pkg; + char fullName[BUFSIZ]; + char lang[BUFSIZ]; - strcpy(nameBuf, "(unknown)"); - while (i < rpmTagTableSize) { - if (tag == rpmTagTable[i].val) { - strcpy(nameBuf, rpmTagTable[i].name + 7); - s = nameBuf+1; - while (*s) { - *s = tolower(*s); - s++; - } + strcpy(fullName, "(main package)"); + + pkg = newPackage(spec); + + if (! initialPackage) { + /* There is one option to %package: <pkg> or -n <pkg> */ + if (parseSimplePart(spec->line, &name, &flag)) { + rpmError(RPMERR_BADSPEC, "Bad package specification: %s", + spec->line); + return RPMERR_BADSPEC; } - i++; + + if (!lookupPackage(spec, name, flag, NULL)) { + rpmError(RPMERR_BADSPEC, "Package already exists: %s", spec->line); + return RPMERR_BADSPEC; + } + + /* Construct the package */ + if (flag == PART_SUBNAME) { + headerGetEntry(spec->packages->header, RPMTAG_NAME, + NULL, (void *) &mainName, NULL); + sprintf(fullName, "%s-%s", mainName, name); + } else { + strcpy(fullName, name); + } + headerAddEntry(pkg->header, RPMTAG_NAME, RPM_STRING_TYPE, fullName, 1); } - return nameBuf; -} + if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { + nextPart = PART_NONE; + } else { + if (rc) { + return rc; + } + while (! (nextPart = isPart(spec->line))) { + /* Skip blank lines */ + linep = spec->line; + SKIPSPACE(linep); + if (*linep) { + if (findPreambleTag(spec, &tag, ¯o, lang)) { + rpmError(RPMERR_BADSPEC, "line %d: Unknown tag: %s", + spec->lineNum, spec->line); + return RPMERR_BADSPEC; + } + if (handlePreambleTag(spec, pkg, tag, macro, lang)) { + return RPMERR_BADSPEC; + } + if (spec->buildArchitectures && !spec->inBuildArchitectures) { + return PART_BUILDARCHITECTURES; + } + } + if ((rc = + readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { + nextPart = PART_NONE; + break; + } + if (rc) { + return rc; + } + } + } -static int readIcon(Header h, char *file) -{ - char buf[BUFSIZ], *icon; - struct stat statbuf; - int fd; + /* Do some final processing on the header */ + + if (!spec->gotBuildRoot && spec->buildRoot) { + rpmError(RPMERR_BADSPEC, "Spec file can't use BuildRoot"); + return RPMERR_BADSPEC; + } - sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), file); - if (stat(buf, &statbuf)) { - rpmError(RPMERR_BADSPEC, "Unable to read icon: %s", file); + if (checkForValidArchitectures(spec)) { return RPMERR_BADSPEC; } - icon = malloc(statbuf.st_size); - fd = open(buf, O_RDONLY); - if (read(fd, icon, statbuf.st_size) != statbuf.st_size) { - close(fd); - rpmError(RPMERR_BADSPEC, "Unable to read icon: %s", file); + + if (pkg == spec->packages) { + fillOutMainPackage(pkg->header); + } + + if (checkForDuplicates(pkg->header, fullName)) { return RPMERR_BADSPEC; } - close(fd); - if (! strncmp(icon, "GIF", 3)) { - headerAddEntry(h, RPMTAG_GIF, RPM_BIN_TYPE, icon, statbuf.st_size); - } else if (! strncmp(icon, "/* XPM", 6)) { - headerAddEntry(h, RPMTAG_XPM, RPM_BIN_TYPE, icon, statbuf.st_size); - } else { - rpmError(RPMERR_BADSPEC, "Unknown icon type: %s", file); + if (pkg != spec->packages) { + copyFromMain(spec, pkg); + } + + if (checkForRequired(pkg->header, fullName)) { return RPMERR_BADSPEC; } - free(icon); - - return 0; + + return nextPart; } diff --git a/build/parsePrep.c b/build/parsePrep.c index 92ee392e6..a2d73b062 100644 --- a/build/parsePrep.c +++ b/build/parsePrep.c @@ -1,9 +1,4 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> +#include "system.h" #include "spec.h" #include "read.h" diff --git a/build/parseReqs.c b/build/parseReqs.c index 3008c37e7..59eb02e64 100644 --- a/build/parseReqs.c +++ b/build/parseReqs.c @@ -1,4 +1,4 @@ -#include <string.h> +#include "system.h" #include "spec.h" #include "rpmlib.h" diff --git a/build/parseScript.c b/build/parseScript.c index 048ad3ed2..3214c482b 100644 --- a/build/parseScript.c +++ b/build/parseScript.c @@ -1,5 +1,4 @@ -#include <malloc.h> -#include <string.h> +#include "system.h" #include "header.h" #include "read.h" @@ -9,6 +8,7 @@ #include "popt/popt.h" #include "reqprov.h" #include "package.h" +#include "parse.h" static int addTriggerIndex(Package pkg, char *file, char *script, char *prog); diff --git a/build/parseSpec.c b/build/parseSpec.c index 569c7e0b1..4f394b72b 100644 --- a/build/parseSpec.c +++ b/build/parseSpec.c @@ -1,8 +1,4 @@ -#include <ctype.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <sys/stat.h> +#include "system.h" #include "header.h" #include "rpmlib.h" diff --git a/build/part.c b/build/part.c index a36f1f505..2fb84e365 100644 --- a/build/part.c +++ b/build/part.c @@ -1,4 +1,4 @@ -#include <string.h> +#include "system.h" #include "part.h" diff --git a/build/read.c b/build/read.c index 20bc65c3c..f006374a7 100644 --- a/build/read.c +++ b/build/read.c @@ -1,6 +1,4 @@ -#include <stdlib.h> -#include <ctype.h> -#include <string.h> +#include "system.h" #include "spec.h" #include "rpmlib.h" @@ -9,11 +7,24 @@ #include "misc.h" #include "read.h" +#ifdef DYING static int matchTok(char *token, char *line); +#endif -/* returns 0 - success */ -/* 1 - EOF */ -/* <0 - error */ +static int matchTok(char *token, char *line) +{ + char buf[BUFSIZ], *tok; + + strcpy(buf, line); + strtok(buf, " \n\t"); + while ((tok = strtok(NULL, " \n\t"))) { + if (! strcmp(tok, token)) { + return 1; + } + } + + return 0; +} void handleComments(char *s) { @@ -23,9 +34,13 @@ void handleComments(char *s) } } +/* returns 0 - success */ +/* 1 - EOF */ +/* <0 - error */ + int readLine(Spec spec, int strip) { - char *from, *to, *first, *last, *s, *arch, *os; + char *from, *to, *last, *s, *arch, *os; int match; char ch; struct ReadLevelEntry *rl; @@ -132,21 +147,6 @@ int readLine(Spec spec, int strip) return 0; } -static int matchTok(char *token, char *line) -{ - char buf[BUFSIZ], *tok; - - strcpy(buf, line); - strtok(buf, " \n\t"); - while ((tok = strtok(NULL, " \n\t"))) { - if (! strcmp(tok, token)) { - return 1; - } - } - - return 0; -} - void closeSpec(Spec spec) { if (spec->file) { diff --git a/build/reqprov.c b/build/reqprov.c index 30ff53dbc..b80d2263a 100644 --- a/build/reqprov.c +++ b/build/reqprov.c @@ -1,7 +1,6 @@ /* reqprov.c -- require/provide handling */ -#include <stdlib.h> -#include <string.h> +#include "system.h" #include "spec.h" #include "reqprov.h" @@ -97,145 +96,3 @@ int addReqProv(Spec spec, Package pkg, return 0; } - -int generateAutoReqProv(Spec spec, Package pkg, - struct cpioFileMapping *cpioList, int cpioCount) -{ - StringBuf writeBuf; - int writeBytes; - StringBuf readBuf; - char *argv[2]; - char **f, **fsave; - - if (!cpioCount) { - return 0; - } - - if (! (spec->autoReq || spec->autoProv)) { - return 0; - } - - writeBuf = newStringBuf(); - writeBytes = 0; - while (cpioCount--) { - writeBytes += strlen(cpioList->fsPath) + 1; - appendLineStringBuf(writeBuf, cpioList->fsPath); - cpioList++; - } - - /*** Do Provides ***/ - - if (spec->autoProv) { - rpmMessage(RPMMESS_NORMAL, "Finding provides...\n"); - - argv[0] = FINDPROVIDES; - argv[1] = NULL; - readBuf = getOutputFrom(NULL, argv, - getStringBuf(writeBuf), writeBytes, 1); - if (!readBuf) { - rpmError(RPMERR_EXEC, "Failed to find provides"); - freeStringBuf(writeBuf); - return RPMERR_EXEC; - } - - f = fsave = splitString(getStringBuf(readBuf), - strlen(getStringBuf(readBuf)), '\n'); - freeStringBuf(readBuf); - while (*f) { - if (**f) { - addReqProv(spec, pkg, RPMSENSE_PROVIDES, *f, NULL, 0); - } - f++; - } - freeSplitString(fsave); - } - - /*** Do Requires ***/ - - if (spec->autoReq) { - rpmMessage(RPMMESS_NORMAL, "Finding requires...\n"); - - argv[0] = FINDREQUIRES; - argv[1] = NULL; - readBuf = getOutputFrom(NULL, argv, - getStringBuf(writeBuf), writeBytes, 0); - if (!readBuf) { - rpmError(RPMERR_EXEC, "Failed to find requires"); - freeStringBuf(writeBuf); - return RPMERR_EXEC; - } - - f = fsave = splitString(getStringBuf(readBuf), - strlen(getStringBuf(readBuf)), '\n'); - freeStringBuf(readBuf); - while (*f) { - if (**f) { - addReqProv(spec, pkg, RPMSENSE_ANY, *f, NULL, 0); - } - f++; - } - freeSplitString(fsave); - } - - /*** Clean Up ***/ - - freeStringBuf(writeBuf); - - return 0; -} - -void printReqs(Spec spec, Package pkg) -{ - int startedPreReq = 0; - int startedReq = 0; - - char **names; - int x, count; - int *flags; - - if (headerGetEntry(pkg->header, RPMTAG_PROVIDES, - NULL, (void **) &names, &count)) { - rpmMessage(RPMMESS_NORMAL, "Provides:"); - x = 0; - while (x < count) { - rpmMessage(RPMMESS_NORMAL, " %s", names[x]); - x++; - } - rpmMessage(RPMMESS_NORMAL, "\n"); - FREE(names); - } - - if (headerGetEntry(pkg->header, RPMTAG_REQUIRENAME, - NULL, (void **) &names, &count)) { - headerGetEntry(pkg->header, RPMTAG_REQUIREFLAGS, - NULL, (void **) &flags, NULL); - x = 0; - while (x < count) { - if (flags[x] & RPMSENSE_PREREQ) { - if (! startedPreReq) { - rpmMessage(RPMMESS_NORMAL, "Prereqs:"); - startedPreReq = 1; - } - rpmMessage(RPMMESS_NORMAL, " %s", names[x]); - } - x++; - } - if (startedPreReq) { - rpmMessage(RPMMESS_NORMAL, "\n"); - } - x = 0; - while (x < count) { - if (! (flags[x] & RPMSENSE_PREREQ)) { - if (! startedReq) { - rpmMessage(RPMMESS_NORMAL, "Requires:"); - startedReq = 1; - } - rpmMessage(RPMMESS_NORMAL, " %s", names[x]); - } - x++; - } - rpmMessage(RPMMESS_NORMAL, "\n"); - FREE(names); - } - -} diff --git a/build/reqprov.h b/build/reqprov.h index 990139aae..14cbc379d 100644 --- a/build/reqprov.h +++ b/build/reqprov.h @@ -11,9 +11,12 @@ extern "C" { int addReqProv(Spec spec, Package pkg, int flag, char *name, char *version, int index); + +#ifdef DYING int generateAutoReqProv(Spec spec, Package pkg, struct cpioFileMapping *cpioList, int cpioCount); void printReqs(Spec spec, Package pkg); +#endif #ifdef __cplusplus } diff --git a/build/spec.c b/build/spec.c index f73dc7621..22dbb54b5 100644 --- a/build/spec.c +++ b/build/spec.c @@ -1,6 +1,4 @@ -#include <stdlib.h> -#include <malloc.h> -#include <string.h> +#include "system.h" #include "spec.h" #include "misc.h" @@ -10,114 +8,82 @@ #include "files.h" #include "macro.h" +#ifdef DYING static char *getSourceAux(Spec spec, int num, int flag, int full); static struct Source *findSource(Spec spec, int num, int flag); +#endif -Spec newSpec(void) +static struct Source *findSource(Spec spec, int num, int flag) { - Spec spec; - - spec = (Spec)malloc(sizeof *spec); - - spec->specFile = NULL; - spec->sourceRpmName = NULL; - - spec->file = NULL; - spec->readBuf[0] = '\0'; - spec->readPtr = NULL; - spec->line[0] = '\0'; - spec->readStack = malloc(sizeof(struct ReadLevelEntry)); - spec->readStack->next = NULL; - spec->readStack->reading = 1; - - spec->prep = NULL; - spec->build = NULL; - spec->install = NULL; - spec->clean = NULL; - - spec->sources = NULL; - spec->packages = NULL; - spec->noSource = 0; - spec->numSources = 0; - - spec->sourceHeader = NULL; + struct Source *p = spec->sources; - spec->sourceCpioCount = 0; - spec->sourceCpioList = NULL; - - spec->gotBuildRoot = 0; - spec->buildRoot = NULL; - - spec->buildSubdir = NULL; + while (p) { + if ((num == p->num) && (p->flags & flag)) { + return p; + } + p = p->next; + } - spec->docDir = NULL; + return NULL; +} - spec->passPhrase = NULL; - spec->timeCheck = 0; - spec->cookie = NULL; +#ifdef UNUSED +static char *getSourceAux(Spec spec, int num, int flag, int full) +{ + struct Source *p = spec->sources; - spec->buildRestrictions = headerNew(); - spec->buildArchitectures = NULL; - spec->buildArchitectureCount = 0; - spec->inBuildArchitectures = 0; - spec->buildArchitectureSpecs = NULL; + p = findSource(spec, num, flag); - initMacros(&spec->macros, MACROFILE); - - spec->autoReq = 1; - spec->autoProv = 1; + return (p) ? (full ? p->fullSource : p->source) : NULL; +} - return spec; +static char *getSource(Spec spec, int num, int flag) +{ + return getSourceAux(spec, num, flag, 0); } -void freeSpec(Spec spec) +static char *getFullSource(Spec spec, int num, int flag) { - struct ReadLevelEntry *rl; - - freeStringBuf(spec->prep); - freeStringBuf(spec->build); - freeStringBuf(spec->install); - freeStringBuf(spec->clean); + return getSourceAux(spec, num, flag, 1); +} +#endif /* UNUSED */ - FREE(spec->buildRoot); - FREE(spec->buildSubdir); - FREE(spec->specFile); - FREE(spec->sourceRpmName); - FREE(spec->docDir); +int parseNoSource(Spec spec, char *field, int tag) +{ + char buf[BUFSIZ]; + char *s, *name; + int num, flag; + struct Source *p; - while (spec->readStack) { - rl = spec->readStack; - spec->readStack = spec->readStack->next; - free(rl); - } - - if (spec->sourceHeader) { - headerFree(spec->sourceHeader); + if (tag == RPMTAG_NOSOURCE) { + flag = RPMBUILD_ISSOURCE; + name = "source"; + } else { + flag = RPMBUILD_ISPATCH; + name = "patch"; } - - freeCpioList(spec->sourceCpioList, spec->sourceCpioCount); - headerFree(spec->buildRestrictions); - FREE(spec->buildArchitectures); + strcpy(buf, field); + field = buf; + while ((s = strtok(field, ", \t"))) { + if (parseNum(s, &num)) { + rpmError(RPMERR_BADSPEC, "line %d: Bad number: %s", + spec->lineNum, spec->line); + return RPMERR_BADSPEC; + } - if (!spec->inBuildArchitectures) { - while (spec->buildArchitectureCount--) { - freeSpec( - spec->buildArchitectureSpecs[spec->buildArchitectureCount]); + if (! (p = findSource(spec, num, flag))) { + rpmError(RPMERR_BADSPEC, "line %d: Bad no%s number: %d", + spec->lineNum, name, num); + return RPMERR_BADSPEC; } - } - FREE(spec->buildArchitectures); - FREE(spec->passPhrase); - FREE(spec->cookie); + p->flags |= RPMBUILD_ISNO; - freeMacros(&spec->macros); - - freeSources(spec); - freePackages(spec); - closeSpec(spec); - - free(spec); + field = NULL; + } + + return 0; } int addSource(Spec spec, Package pkg, char *field, int tag) @@ -207,40 +173,64 @@ int addSource(Spec spec, Package pkg, char *field, int tag) return 0; } -char *getSource(Spec spec, int num, int flag) +Spec newSpec(void) { - return getSourceAux(spec, num, flag, 0); -} + Spec spec; -char *getFullSource(Spec spec, int num, int flag) -{ - return getSourceAux(spec, num, flag, 1); -} + spec = (Spec)malloc(sizeof *spec); + + spec->specFile = NULL; + spec->sourceRpmName = NULL; -static char *getSourceAux(Spec spec, int num, int flag, int full) -{ - struct Source *p = spec->sources; + spec->file = NULL; + spec->readBuf[0] = '\0'; + spec->readPtr = NULL; + spec->line[0] = '\0'; + spec->readStack = malloc(sizeof(struct ReadLevelEntry)); + spec->readStack->next = NULL; + spec->readStack->reading = 1; - p = findSource(spec, num, flag); + spec->prep = NULL; + spec->build = NULL; + spec->install = NULL; + spec->clean = NULL; - return (p) ? (full ? p->fullSource : p->source) : NULL; -} + spec->sources = NULL; + spec->packages = NULL; + spec->noSource = 0; + spec->numSources = 0; -static struct Source *findSource(Spec spec, int num, int flag) -{ - struct Source *p = spec->sources; + spec->sourceHeader = NULL; - while (p) { - if ((num == p->num) && (p->flags & flag)) { - return p; - } - p = p->next; - } + spec->sourceCpioCount = 0; + spec->sourceCpioList = NULL; + + spec->gotBuildRoot = 0; + spec->buildRoot = NULL; + + spec->buildSubdir = NULL; - return NULL; + spec->docDir = NULL; + + spec->passPhrase = NULL; + spec->timeCheck = 0; + spec->cookie = NULL; + + spec->buildRestrictions = headerNew(); + spec->buildArchitectures = NULL; + spec->buildArchitectureCount = 0; + spec->inBuildArchitectures = 0; + spec->buildArchitectureSpecs = NULL; + + initMacros(&spec->macros, MACROFILE); + + spec->autoReq = 1; + spec->autoProv = 1; + + return spec; } -void freeSources(Spec spec) +static void freeSources(Spec spec) { struct Source *p1, *p2; @@ -253,40 +243,52 @@ void freeSources(Spec spec) } } -int parseNoSource(Spec spec, char *field, int tag) +void freeSpec(Spec spec) { - char buf[BUFSIZ]; - char *s, *name; - int num, flag; - struct Source *p; + struct ReadLevelEntry *rl; + + freeStringBuf(spec->prep); + freeStringBuf(spec->build); + freeStringBuf(spec->install); + freeStringBuf(spec->clean); - if (tag == RPMTAG_NOSOURCE) { - flag = RPMBUILD_ISSOURCE; - name = "source"; - } else { - flag = RPMBUILD_ISPATCH; - name = "patch"; + FREE(spec->buildRoot); + FREE(spec->buildSubdir); + FREE(spec->specFile); + FREE(spec->sourceRpmName); + FREE(spec->docDir); + + while (spec->readStack) { + rl = spec->readStack; + spec->readStack = spec->readStack->next; + free(rl); } - strcpy(buf, field); - field = buf; - while ((s = strtok(field, ", \t"))) { - if (parseNum(s, &num)) { - rpmError(RPMERR_BADSPEC, "line %d: Bad number: %s", - spec->lineNum, spec->line); - return RPMERR_BADSPEC; - } - - if (! (p = findSource(spec, num, flag))) { - rpmError(RPMERR_BADSPEC, "line %d: Bad no%s number: %d", - spec->lineNum, name, num); - return RPMERR_BADSPEC; - } + if (spec->sourceHeader) { + headerFree(spec->sourceHeader); + } - p->flags |= RPMBUILD_ISNO; + freeCpioList(spec->sourceCpioList, spec->sourceCpioCount); + + headerFree(spec->buildRestrictions); + FREE(spec->buildArchitectures); - field = NULL; + if (!spec->inBuildArchitectures) { + while (spec->buildArchitectureCount--) { + freeSpec( + spec->buildArchitectureSpecs[spec->buildArchitectureCount]); + } } + FREE(spec->buildArchitectures); - return 0; + FREE(spec->passPhrase); + FREE(spec->cookie); + + freeMacros(&spec->macros); + + freeSources(spec); + freePackages(spec); + closeSpec(spec); + + free(spec); } diff --git a/build/spec.h b/build/spec.h index 796fa36e2..6579e7599 100644 --- a/build/spec.h +++ b/build/spec.h @@ -131,13 +131,16 @@ typedef struct PackageStruct *Package; extern "C" { #endif +#ifdef DYING +char *getSource(Spec spec, int num, int flag); +char *getFullSource(Spec spec, int num, int flag); +void freeSources(Spec spec); +#endif + Spec newSpec(void); void freeSpec(Spec spec); int addSource(Spec spec, Package pkg, char *field, int tag); -char *getSource(Spec spec, int num, int flag); -char *getFullSource(Spec spec, int num, int flag); -void freeSources(Spec spec); int parseNoSource(Spec spec, char *field, int tag); #ifdef __cplusplus |