#include "signature.h"
#include "misc.h"
#include "pack.h"
+#include "build.h"
#include "messages.h"
#include "md5.h"
static int add_file(struct file_entry **festack, const char *name,
int isdoc, int isconf, int isdir, int verify_flags);
static int compare_fe(const void *ap, const void *bp);
-static int process_filelist(Header header, StringBuf sb, int *size,
- char *name, char *version, char *release,
- int type);
+static int process_filelist(Header header, struct PackageRec *pr, StringBuf sb,
+ int *size, char *name, char *version,
+ char *release, int type);
static char *buildHost(void);
static int add_file_aux(const char *file, struct stat *sb, int flag);
static char *getUname(uid_t uid);
return 1;
}
-static int process_filelist(Header header, StringBuf sb, int *size,
- char *name, char *version, char *release, int type)
+static int process_filelist(Header header, struct PackageRec *pr,
+ StringBuf sb, int *size, char *name,
+ char *version, char *release, int type)
{
char buf[1024];
char **files, **fp;
glob_t glob_result;
int special_doc;
int passed_special_doc = 0;
+ FILE *file;
fes = NULL;
*size = 0;
resetDocdir();
+
+ if (type == RPMLEAD_BINARY && pr->fileFile) {
+ sprintf(buf, "%s/%s/%s", getVar(RPMVAR_BUILDDIR),
+ build_subdir, pr->fileFile);
+ message(MESS_DEBUG, "Reading file names from: %sXX\n", buf);
+ if ((file = fopen(buf, "r")) == NULL) {
+ perror("open fileFile");
+ exit(1);
+ }
+ while (fgets(buf, sizeof(buf), file)) {
+ appendStringBuf(sb, buf);
+ }
+ fclose(file);
+ }
str = getStringBuf(sb);
files = splitString(str, strlen(str), '\n');
/**** Process the file list ****/
- if (process_filelist(outHeader, pr->filelist, &size, nametmp,
+ if (process_filelist(outHeader, pr, pr->filelist, &size, nametmp,
packageVersion, packageRelease, RPMLEAD_BINARY)) {
return 1;
}
+
+ /* Add any require/provide entries */
+ addReqProvHeaderEntry(outHeader, pr);
+
/* And add the final Header entry */
addEntry(outHeader, RPMTAG_SIZE, INT32_TYPE, &size, 1);
}
/* Process the file list */
- if (process_filelist(outHeader, filelist, &size,
+ if (process_filelist(outHeader, NULL, filelist, &size,
s->name, version, release, RPMLEAD_SOURCE)) {
return 1;
}
#include <string.h>
#include <regex.h>
#include <limits.h>
+#include <ctype.h>
#include "header.h"
#include "spec.h"
static int lookup_package(Spec s, struct PackageRec **pr,
char *name, int flags);
static void dumpPackage(struct PackageRec *p, FILE *f);
-static char *chop_line(char *s);
static void parseForDocFiles(struct PackageRec *package, char *line);
+static int parseProvides(struct PackageRec *p, char *line);
+static int parseRequires(struct PackageRec *p, char *line);
+void free_reqprov(struct ReqProv *p);
+
/**********************************************************************/
/* */
/* Source and patch structure creation/deletion/lookup */
/**********************************************************************/
/* */
+/* Provide/Require handling */
+/* */
+/**********************************************************************/
+
+int addReqProv(struct PackageRec *p, int flags,
+ char *name, char *version)
+{
+ struct ReqProv *rd;
+
+ rd = (struct ReqProv *)malloc(sizeof(*rd));
+ rd->flags = flags;
+ rd->name = strdup(name);
+ rd->version = version ? strdup(version) : NULL;
+ rd->next = p->reqprov;
+ p->reqprov = rd;
+
+ if (flags & REQUIRE_PROVIDES) {
+ message(MESS_DEBUG, "Adding provide: %s\n", name);
+ p->numProv++;
+ } else {
+ message(MESS_DEBUG, "Adding require: %s\n", name);
+ p->numReq++;
+ }
+
+ return 0;
+}
+
+static int parseProvides(struct PackageRec *p, char *line)
+{
+ char *prov;
+ int flags = REQUIRE_PROVIDES;
+
+ while ((prov = strtok(line, " ,\t\n"))) {
+ addReqProv(p, flags, prov, NULL);
+ line = NULL;
+ }
+ return 0;
+}
+
+struct ReqComp {
+ char *token;
+ int flags;
+} ReqComparisons[] = {
+ { "<=", REQUIRE_LESS | REQUIRE_EQUAL},
+ { "<=S", REQUIRE_LESS | REQUIRE_EQUAL | REQUIRE_SERIAL},
+ { "=<", REQUIRE_LESS | REQUIRE_EQUAL},
+ { "=<S", REQUIRE_LESS | REQUIRE_EQUAL | REQUIRE_SERIAL},
+ { "<", REQUIRE_LESS},
+ { "<S", REQUIRE_LESS | REQUIRE_SERIAL},
+
+ { "=", REQUIRE_EQUAL},
+ { "=S", REQUIRE_EQUAL | REQUIRE_SERIAL},
+
+ { ">=", REQUIRE_GREATER | REQUIRE_EQUAL},
+ { ">=S", REQUIRE_GREATER | REQUIRE_EQUAL | REQUIRE_SERIAL},
+ { "=>", REQUIRE_GREATER | REQUIRE_EQUAL},
+ { "=>S", REQUIRE_GREATER | REQUIRE_EQUAL | REQUIRE_SERIAL},
+ { ">", REQUIRE_GREATER},
+ { ">S", REQUIRE_GREATER | REQUIRE_SERIAL},
+ { NULL, 0 },
+};
+
+static int parseRequires(struct PackageRec *p, char *line)
+{
+ char *req = NULL;
+ char *version = NULL;
+ int flags;
+ struct ReqComp *rc;
+
+ while (req || (req = strtok(line, " ,\t\n"))) {
+ flags = 0;
+ if ((version = strtok(NULL, " ,\t\n"))) {
+ rc = ReqComparisons;
+ while (rc->token && strcmp(version, rc->token)) {
+ rc++;
+ }
+ if (rc->token) {
+ /* read a version */
+ flags = rc->flags;
+ version = strtok(NULL, " ,\t\n");
+ }
+ }
+ if (flags && !version) {
+ error(RPMERR_BADSPEC, "Version required in dependency");
+ return RPMERR_BADSPEC;
+ }
+
+ addReqProv(p, flags, req, version);
+
+ req = NULL;
+ if (! flags) {
+ /* No version -- we just read a name */
+ req = version;
+ }
+ line = NULL;
+ }
+
+ return 0;
+}
+
+void free_reqprov(struct ReqProv *p)
+{
+ struct ReqProv *s;
+
+ while (p) {
+ s = p;
+ p = p->next;
+ FREE(s->name);
+ FREE(s->version);
+ free(s);
+ }
+}
+
+int addReqProvHeaderEntry(Header h, struct PackageRec *p)
+{
+ message(MESS_DEBUG, "provides: %d\nrequires: %d\n", p->numProv, p->numReq);
+ return 0;
+}
+
+/**********************************************************************/
+/* */
/* Spec and package structure creation/deletion/lookup */
/* */
/**********************************************************************/
p->header = newHeader();
p->filelist = newStringBuf();
p->files = -1; /* -1 means no %files, thus no package */
+ p->fileFile = NULL;
p->doc = newStringBuf();
+ p->reqprov = NULL;
+ p->numReq = 0;
+ p->numProv = 0;
p->next = NULL;
return p;
FREE(p->subname);
FREE(p->newname);
FREE(p->icon);
+ FREE(p->fileFile);
+ free_reqprov(p->reqprov);
if (p->next) {
free_packagerec(p->next);
}
{RPMTAG_EXCLUDE, 0, "exclude"},
{RPMTAG_EXCLUSIVE, 0, "exclusive"},
{RPMTAG_ICON, 0, "icon"},
- {RPMTAG_ICON, 0, "provides"},
- {RPMTAG_ICON, 0, "requires"},
+ {RPMTAG_PROVIDES, 0, "provides"},
+ {RPMTAG_REQUIREFLAGS, 0, "requires"},
{0, 0, 0}
};
return p->part;
}
+#if 0
static char *chop_line(char *s)
{
char *p, *e;
}
return p;
}
+#endif
static void parseForDocFiles(struct PackageRec *package, char *line)
{
{
char buf[LINE_BUF_SIZE]; /* read buffer */
char buf2[LINE_BUF_SIZE];
+ char fileFile[LINE_BUF_SIZE];
char *line; /* "parsed" read buffer */
int x, serial, tag, cur_part, t1;
int lookupopts;
StringBuf sb;
char *s = NULL;
- char *s1;
+ char *s1, *s2;
struct PackageRec *cur_package = NULL;
Spec spec = (struct SpecRec *) malloc(sizeof(struct SpecRec));
}
}
+ /* Rip through s for -f in %files */
+ fileFile[0] = '\0';
+ s1 = NULL;
+ if (s &&
+ ((s1 = strstr(s, " -f ")) ||
+ (!strncmp(s, "-f ", 3)))) {
+ if (s1) {
+ s1[0] = ' ';
+ s1++;
+ } else {
+ s1 = s;
+ }
+ s1[0] = ' '; s1[1] = ' '; s1[2] = ' ';
+ s1 += 3;
+
+ while (isspace(*s1)) {
+ s1++;
+ }
+ s2 = fileFile;
+ while (*s1 && !isspace(*s1)) {
+ *s2 = *s1;
+ *s1 = ' ';
+ s1++;
+ s2++;
+ }
+ *s2 = '\0';
+ while (isspace(*s)) {
+ s++;
+ }
+ if (! *s) {
+ s = NULL;
+ }
+ }
+
+ message(MESS_DEBUG, "fileFile = %s\n", fileFile);
+
/* Handle -n in part tags */
lookupopts = 0;
if (s) {
s1++;
*s1 = '\0';
}
-
+
switch (tag) {
case PREP_PART:
case BUILD_PART:
if (cur_part == FILES_PART) {
/* set files to 0 (current -1 means no %files, no package */
cur_package->files = 0;
+ if (fileFile[0]) {
+ cur_package->fileFile = strdup(fileFile);
+ }
}
continue;
}
break;
case RPMTAG_PROVIDES:
- if (parseProvides(line)) {
+ if (parseProvides(cur_package, s)) {
+ return NULL;
+ }
+ break;
+ case RPMTAG_REQUIREFLAGS:
+ if (parseRequires(cur_package, s)) {
+ return NULL;
}
break;
default: