From: Kristian Høgsberg Date: Tue, 18 Sep 2007 19:02:04 +0000 (-0400) Subject: Split importers to import.c. X-Git-Tag: 0.1~333 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=9aa27578d2a23f5fc2e8405f3f9d4c36ae672872;p=razor.git Split importers to import.c. --- diff --git a/Makefile b/Makefile index 05ecfce..43b5620 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CFLAGS = -Wall -g -O2 LDLIBS = -lexpat -g -razor : razor.o sha1.o +razor : razor.o import.o sha1.o import : razor primary.xml.gz zcat primary.xml.gz | ./razor eat-yum diff --git a/import.c b/import.c new file mode 100644 index 0000000..a5ccc98 --- /dev/null +++ b/import.c @@ -0,0 +1,259 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "sha1.h" +#include "razor.h" + +static void +parse_package(struct import_context *ctx, const char **atts, void *data) +{ + const char *name = NULL, *version = NULL; + int i; + + for (i = 0; atts[i]; i += 2) { + if (strcmp(atts[i], "name") == 0) + name = atts[i + 1]; + else if (strcmp(atts[i], "version") == 0) + version = atts[i + 1]; + } + + if (name == NULL || version == NULL) { + fprintf(stderr, "invalid package tag, " + "missing name or version attributes\n"); + return; + } + + import_context_add_package(ctx, name, version); +} + +static void +parse_property(struct import_context *ctx, const char **atts, void *data) +{ + const char *name = NULL, *version = NULL; + int i; + + for (i = 0; atts[i]; i += 2) { + if (strcmp(atts[i], "name") == 0) + name = atts[i + 1]; + if (strcmp(atts[i], "version") == 0) + version = atts[i + 1]; + } + + if (name == NULL) { + fprintf(stderr, "invalid tag, missing name attribute\n"); + return; + } + + import_context_add_property(ctx, data, name, version); +} + +static void +start_element(void *data, const char *name, const char **atts) +{ + struct import_context *ctx = data; + + if (strcmp(name, "package") == 0) + parse_package(ctx, atts, NULL); + else if (strcmp(name, "requires") == 0) + parse_property(ctx, atts, &ctx->requires); + else if (strcmp(name, "provides") == 0) + parse_property(ctx, atts, &ctx->provides); +} + +static void +end_element (void *data, const char *name) +{ + struct import_context *ctx = data; + + if (strcmp(name, "package") == 0) + import_context_finish_package(ctx); +} + +static int +import_rzr_file(struct import_context *ctx, const char *filename) +{ + SHA_CTX sha1; + XML_Parser parser; + int fd; + void *p; + struct stat stat; + unsigned char hash[20]; + + fd = open(filename, O_RDONLY); + if (fstat(fd, &stat) < 0) + return -1; + p = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (p == MAP_FAILED) + return -1; + + parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, ctx); + XML_SetElementHandler(parser, start_element, end_element); + if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) { + fprintf(stderr, + "%s at line %d, %s\n", + XML_ErrorString(XML_GetErrorCode(parser)), + XML_GetCurrentLineNumber(parser), + filename); + return 1; + } + + XML_ParserFree(parser); + + SHA1_Init(&sha1); + SHA1_Update(&sha1, p, stat.st_size); + SHA1_Final(hash, &sha1); + + close(fd); + + munmap(p, stat.st_size); + + return 0; +} + +struct razor_set * +razor_import_rzr_files(int count, const char *files[]) +{ + struct import_context ctx; + int i; + + razor_prepare_import(&ctx); + + for (i = 0; i < count; i++) { + if (import_rzr_file(&ctx, files[i]) < 0) { + fprintf(stderr, "failed to import %s\n", files[i]); + exit(-1); + } + } + + return razor_finish_import(&ctx); +} + +/* Import a yum filelist as a razor package set. */ + +enum { + YUM_STATE_BEGIN, + YUM_STATE_PACKAGE_NAME +}; + +struct yum_context { + struct import_context ctx; + struct import_property_context *current_property_context; + char *name; + int state; +}; + +static void +yum_start_element(void *data, const char *name, const char **atts) +{ + struct yum_context *ctx = data; + const char *n, *version; + int i; + + if (strcmp(name, "name") == 0) { + ctx->state = YUM_STATE_PACKAGE_NAME; + } else if (strcmp(name, "version") == 0) { + version = NULL; + for (i = 0; atts[i]; i += 2) { + if (strcmp(atts[i], "ver") == 0) + version = atts[i + 1]; + } + import_context_add_package(&ctx->ctx, ctx->name, version); + } else if (strcmp(name, "rpm:requires") == 0) { + ctx->current_property_context = &ctx->ctx.requires; + } else if (strcmp(name, "rpm:provides") == 0) { + ctx->current_property_context = &ctx->ctx.provides; + } else if (strcmp(name, "rpm:entry") == 0 && + ctx->current_property_context != NULL) { + n = NULL; + version = NULL; + for (i = 0; atts[i]; i += 2) { + if (strcmp(atts[i], "name") == 0) + n = atts[i + 1]; + else if (strcmp(atts[i], "ver") == 0) + version = atts[i + 1]; + } + + if (n == NULL) { + fprintf(stderr, "invalid rpm:entry, " + "missing name or version attributes\n"); + return; + } + + import_context_add_property(&ctx->ctx, + ctx->current_property_context, + n, version); + } +} + +static void +yum_end_element (void *data, const char *name) +{ + struct yum_context *ctx = data; + + if (strcmp(name, "package") == 0) { + free(ctx->name); + import_context_finish_package(&ctx->ctx); + } else if (strcmp(name, "name") == 0) { + ctx->state = 0; + } else if (strcmp(name, "rpm:requires") == 0) { + ctx->current_property_context = NULL; + } else if (strcmp(name, "rpm:provides") == 0) { + ctx->current_property_context = NULL; + } +} + +static void +yum_character_data (void *data, const XML_Char *s, int len) +{ + struct yum_context *ctx = data; + + if (ctx->state == YUM_STATE_PACKAGE_NAME) + ctx->name = strndup(s, len); +} + +struct razor_set * +razor_set_create_from_yum_filelist(int fd) +{ + struct yum_context ctx; + XML_Parser parser; + char buf[4096]; + int len; + + razor_prepare_import(&ctx.ctx); + + parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, &ctx); + XML_SetElementHandler(parser, yum_start_element, yum_end_element); + XML_SetCharacterDataHandler(parser, yum_character_data); + + while (1) { + len = read(fd, buf, sizeof buf); + if (len < 0) { + fprintf(stderr, + "couldn't read input: %s\n", strerror(errno)); + return NULL; + } else if (len == 0) + break; + + if (XML_Parse(parser, buf, len, 0) == XML_STATUS_ERROR) { + fprintf(stderr, + "%s at line %d\n", + XML_ErrorString(XML_GetErrorCode(parser)), + XML_GetCurrentLineNumber(parser)); + return NULL; + } + } + + XML_ParserFree(parser); + + return razor_finish_import(&ctx.ctx); +} diff --git a/razor.c b/razor.c index 290dd31..541d0c1 100644 --- a/razor.c +++ b/razor.c @@ -11,15 +11,7 @@ #include #include -#include -#include "sha1.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -struct array { - void *data; - int size, alloc; -}; +#include "razor.h" static void array_init(struct array *array) @@ -77,20 +69,6 @@ write_to_fd(int fd, void *p, size_t size) return 0; } -static int -write_to_file(const char *filename, void *p, size_t size) -{ - int fd, err; - - fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); - if (fd < 0) - return -1; - err = write_to_fd(fd, p, size); - close(fd); - - return err; -} - static void * zalloc(size_t size) { @@ -102,50 +80,6 @@ zalloc(size_t size) return p; } -struct razor_set_section { - unsigned int type; - unsigned int offset; - unsigned int size; -}; - -struct razor_set_header { - unsigned int magic; - unsigned int version; - struct razor_set_section sections[0]; -}; - -#define RAZOR_MAGIC 0x7a7a7a7a -#define RAZOR_VERSION 1 - -#define RAZOR_PACKAGES 0 -#define RAZOR_REQUIRES 1 -#define RAZOR_PROVIDES 2 -#define RAZOR_STRING_POOL 3 -#define RAZOR_PROPERTY_POOL 4 - -struct razor_package { - unsigned long name; - unsigned long version; - unsigned long requires; - unsigned long provides; -}; - -struct razor_property { - unsigned long name; - unsigned long version; - unsigned long packages; -}; - -struct razor_set { - struct array buckets; - struct array string_pool; - struct array property_pool; - struct array packages; - struct array requires; - struct array provides; - struct razor_set_header *header; -}; - struct razor_set_section razor_sections[] = { { RAZOR_PACKAGES, offsetof(struct razor_set, packages) }, { RAZOR_REQUIRES, offsetof(struct razor_set, requires) }, @@ -386,21 +320,7 @@ razor_set_tokenize(struct razor_set *set, const char *string) return razor_set_insert(set, string); } -struct import_property_context { - struct array *all; - struct array package; -}; - -struct import_context { - struct razor_set *set; - struct import_property_context requires; - struct import_property_context provides; - struct razor_package *package; - unsigned long *requires_map; - unsigned long *provides_map; -}; - -static void +void import_context_add_package(struct import_context *ctx, const char *name, const char *version) { @@ -428,7 +348,7 @@ import_context_finish_package(struct import_context *ctx) array_release(&ctx->provides.package); } -static void +void import_context_add_property(struct import_context *ctx, struct import_property_context *pctx, const char *name, const char *version) @@ -446,91 +366,7 @@ import_context_add_property(struct import_context *ctx, *r = p - (struct razor_property *) pctx->all->data; } -static void -parse_package(struct import_context *ctx, const char **atts, void *data) -{ - const char *name = NULL, *version = NULL; - int i; - - for (i = 0; atts[i]; i += 2) { - if (strcmp(atts[i], "name") == 0) - name = atts[i + 1]; - else if (strcmp(atts[i], "version") == 0) - version = atts[i + 1]; - } - - if (name == NULL || version == NULL) { - fprintf(stderr, "invalid package tag, " - "missing name or version attributes\n"); - return; - } - - import_context_add_package(ctx, name, version); -} - -static void -parse_property(struct import_context *ctx, const char **atts, void *data) -{ - const char *name = NULL, *version = NULL; - int i; - - for (i = 0; atts[i]; i += 2) { - if (strcmp(atts[i], "name") == 0) - name = atts[i + 1]; - if (strcmp(atts[i], "version") == 0) - version = atts[i + 1]; - } - - if (name == NULL) { - fprintf(stderr, "invalid tag, missing name attribute\n"); - return; - } - - import_context_add_property(ctx, data, name, version); -} - -static void -start_element(void *data, const char *name, const char **atts) -{ - struct import_context *ctx = data; - - if (strcmp(name, "package") == 0) - parse_package(ctx, atts, NULL); - else if (strcmp(name, "requires") == 0) - parse_property(ctx, atts, &ctx->requires); - else if (strcmp(name, "provides") == 0) - parse_property(ctx, atts, &ctx->provides); -} - -static void -end_element (void *data, const char *name) -{ - struct import_context *ctx = data; - - if (strcmp(name, "package") == 0) - import_context_finish_package(ctx); -} - -static char * -sha1_to_hex(const unsigned char *sha1) -{ - static int bufno; - static char hexbuffer[4][50]; - static const char hex[] = "0123456789abcdef"; - char *buffer = hexbuffer[3 & ++bufno], *buf = buffer; - int i; - - for (i = 0; i < 20; i++) { - unsigned int val = *sha1++; - *buf++ = hex[val >> 4]; - *buf++ = hex[val & 0xf]; - } - *buf = '\0'; - - return buffer; -} - -static void +void razor_prepare_import(struct import_context *ctx) { memset(ctx, 0, sizeof *ctx); @@ -539,52 +375,6 @@ razor_prepare_import(struct import_context *ctx) ctx->provides.all = &ctx->set->provides; } -static int -razor_import(struct import_context *ctx, const char *filename) -{ - SHA_CTX sha1; - XML_Parser parser; - int fd; - void *p; - struct stat stat; - char buf[128]; - unsigned char hash[20]; - - fd = open(filename, O_RDONLY); - if (fstat(fd, &stat) < 0) - return -1; - p = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (p == MAP_FAILED) - return -1; - - parser = XML_ParserCreate(NULL); - XML_SetUserData(parser, ctx); - XML_SetElementHandler(parser, start_element, end_element); - if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) { - fprintf(stderr, - "%s at line %d, %s\n", - XML_ErrorString(XML_GetErrorCode(parser)), - XML_GetCurrentLineNumber(parser), - filename); - return 1; - } - - XML_ParserFree(parser); - - SHA1_Init(&sha1); - SHA1_Update(&sha1, p, stat.st_size); - SHA1_Final(hash, &sha1); - - close(fd); - - snprintf(buf, sizeof buf, "set/%s", sha1_to_hex(hash)); - if (write_to_file(buf, p, stat.st_size) < 0) - return -1; - munmap(p, stat.st_size); - - return 0; -} - typedef int (*compare_with_data_func_t)(const void *p1, const void *p, void *data); @@ -800,7 +590,7 @@ remap_property_links(struct import_context *ctx, unsigned long *map) free(rmap); } -static struct razor_set * +struct razor_set * razor_finish_import(struct import_context *ctx) { unsigned long *map; @@ -824,127 +614,6 @@ razor_finish_import(struct import_context *ctx) return ctx->set; } -/* Import a yum filelist as a razor package set. */ - -enum { - YUM_STATE_BEGIN, - YUM_STATE_PACKAGE_NAME -}; - -struct yum_context { - struct import_context ctx; - struct import_property_context *current_property_context; - char *name; - int state; -}; - -static void -yum_start_element(void *data, const char *name, const char **atts) -{ - struct yum_context *ctx = data; - const char *n, *version; - int i; - - if (strcmp(name, "name") == 0) { - ctx->state = YUM_STATE_PACKAGE_NAME; - } else if (strcmp(name, "version") == 0) { - version = NULL; - for (i = 0; atts[i]; i += 2) { - if (strcmp(atts[i], "ver") == 0) - version = atts[i + 1]; - } - import_context_add_package(&ctx->ctx, ctx->name, version); - } else if (strcmp(name, "rpm:requires") == 0) { - ctx->current_property_context = &ctx->ctx.requires; - } else if (strcmp(name, "rpm:provides") == 0) { - ctx->current_property_context = &ctx->ctx.provides; - } else if (strcmp(name, "rpm:entry") == 0 && - ctx->current_property_context != NULL) { - n = NULL; - version = NULL; - for (i = 0; atts[i]; i += 2) { - if (strcmp(atts[i], "name") == 0) - n = atts[i + 1]; - else if (strcmp(atts[i], "ver") == 0) - version = atts[i + 1]; - } - - if (n == NULL) { - fprintf(stderr, "invalid rpm:entry, " - "missing name or version attributes\n"); - return; - } - - import_context_add_property(&ctx->ctx, - ctx->current_property_context, - n, version); - } -} - -static void -yum_end_element (void *data, const char *name) -{ - struct yum_context *ctx = data; - - if (strcmp(name, "package") == 0) { - free(ctx->name); - import_context_finish_package(&ctx->ctx); - } else if (strcmp(name, "name") == 0) { - ctx->state = 0; - } else if (strcmp(name, "rpm:requires") == 0) { - ctx->current_property_context = NULL; - } else if (strcmp(name, "rpm:provides") == 0) { - ctx->current_property_context = NULL; - } -} - -static void -yum_character_data (void *data, const XML_Char *s, int len) -{ - struct yum_context *ctx = data; - - if (ctx->state == YUM_STATE_PACKAGE_NAME) - ctx->name = strndup(s, len); -} - -static struct razor_set * -razor_set_create_from_yum_filelist(int fd) -{ - struct yum_context ctx; - XML_Parser parser; - char buf[4096]; - int len; - - razor_prepare_import(&ctx.ctx); - - parser = XML_ParserCreate(NULL); - XML_SetUserData(parser, &ctx); - XML_SetElementHandler(parser, yum_start_element, yum_end_element); - XML_SetCharacterDataHandler(parser, yum_character_data); - - while (1) { - len = read(fd, buf, sizeof buf); - if (len < 0) { - fprintf(stderr, - "couldn't read input: %s\n", strerror(errno)); - return NULL; - } else if (len == 0) - break; - - if (XML_Parse(parser, buf, len, 0) == XML_STATUS_ERROR) { - fprintf(stderr, - "%s at line %d\n", - XML_ErrorString(XML_GetErrorCode(parser)), - XML_GetCurrentLineNumber(parser)); - return NULL; - } - } - - XML_ParserFree(parser); - - return razor_finish_import(&ctx.ctx); -} - void razor_set_list(struct razor_set *set) { @@ -1188,12 +857,10 @@ static const char *repo_filename = "system.repo"; static const char rawhide_repo_filename[] = "rawhide.repo"; int -main(int argc, char *argv[]) +main(int argc, const char *argv[]) { - int i; struct razor_set *set; struct stat statbuf; - struct import_context ctx; char *repo; repo = getenv("RAZOR_REPO"); @@ -1208,17 +875,7 @@ main(int argc, char *argv[]) exit(-1); } - razor_prepare_import(&ctx); - - for (i = 2; i < argc; i++) { - if (razor_import(&ctx, argv[i]) < 0) { - fprintf(stderr, "failed to import %s\n", - argv[i]); - exit(-1); - } - } - - set = razor_finish_import(&ctx); + set = razor_import_rzr_files(argc - 2, argv + 2); printf("bucket allocation: %d\n", set->buckets.alloc); printf("pool size: %d\n", set->string_pool.size); diff --git a/razor.h b/razor.h new file mode 100644 index 0000000..8912ad6 --- /dev/null +++ b/razor.h @@ -0,0 +1,83 @@ +#ifndef _RAZOR_H_ +#define _RAZOR_H_ + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +struct array { + void *data; + int size, alloc; +}; + +struct razor_set_section { + unsigned int type; + unsigned int offset; + unsigned int size; +}; + +struct razor_set_header { + unsigned int magic; + unsigned int version; + struct razor_set_section sections[0]; +}; + +#define RAZOR_MAGIC 0x7a7a7a7a +#define RAZOR_VERSION 1 + +#define RAZOR_PACKAGES 0 +#define RAZOR_REQUIRES 1 +#define RAZOR_PROVIDES 2 +#define RAZOR_STRING_POOL 3 +#define RAZOR_PROPERTY_POOL 4 + +struct razor_package { + unsigned long name; + unsigned long version; + unsigned long requires; + unsigned long provides; +}; + +struct razor_property { + unsigned long name; + unsigned long version; + unsigned long packages; +}; + +struct razor_set { + struct array buckets; + struct array string_pool; + struct array property_pool; + struct array packages; + struct array requires; + struct array provides; + struct razor_set_header *header; +}; + +struct import_property_context { + struct array *all; + struct array package; +}; + +struct import_context { + struct razor_set *set; + struct import_property_context requires; + struct import_property_context provides; + struct razor_package *package; + unsigned long *requires_map; + unsigned long *provides_map; +}; + +void import_context_add_package(struct import_context *ctx, + const char *name, const char *version); +void import_context_add_property(struct import_context *ctx, + struct import_property_context *pctx, + const char *name, const char *version); +void import_context_finish_package(struct import_context *ctx); + +unsigned long razor_set_tokenize(struct razor_set *set, const char *string); +void razor_prepare_import(struct import_context *ctx); +struct razor_set *razor_finish_import(struct import_context *ctx); + +struct razor_set *razor_import_rzr_files(int count, const char **files); +struct razor_set *razor_set_create_from_yum_filelist(int fd); + +#endif /* _RAZOR_H_ */