1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/import.c Tue Sep 18 15:02:04 2007 -0400
1.3 @@ -0,0 +1,259 @@
1.4 +#define _GNU_SOURCE
1.5 +
1.6 +#include <string.h>
1.7 +#include <stdio.h>
1.8 +#include <sys/stat.h>
1.9 +#include <sys/mman.h>
1.10 +#include <unistd.h>
1.11 +#include <fcntl.h>
1.12 +#include <errno.h>
1.13 +
1.14 +#include <expat.h>
1.15 +#include "sha1.h"
1.16 +#include "razor.h"
1.17 +
1.18 +static void
1.19 +parse_package(struct import_context *ctx, const char **atts, void *data)
1.20 +{
1.21 + const char *name = NULL, *version = NULL;
1.22 + int i;
1.23 +
1.24 + for (i = 0; atts[i]; i += 2) {
1.25 + if (strcmp(atts[i], "name") == 0)
1.26 + name = atts[i + 1];
1.27 + else if (strcmp(atts[i], "version") == 0)
1.28 + version = atts[i + 1];
1.29 + }
1.30 +
1.31 + if (name == NULL || version == NULL) {
1.32 + fprintf(stderr, "invalid package tag, "
1.33 + "missing name or version attributes\n");
1.34 + return;
1.35 + }
1.36 +
1.37 + import_context_add_package(ctx, name, version);
1.38 +}
1.39 +
1.40 +static void
1.41 +parse_property(struct import_context *ctx, const char **atts, void *data)
1.42 +{
1.43 + const char *name = NULL, *version = NULL;
1.44 + int i;
1.45 +
1.46 + for (i = 0; atts[i]; i += 2) {
1.47 + if (strcmp(atts[i], "name") == 0)
1.48 + name = atts[i + 1];
1.49 + if (strcmp(atts[i], "version") == 0)
1.50 + version = atts[i + 1];
1.51 + }
1.52 +
1.53 + if (name == NULL) {
1.54 + fprintf(stderr, "invalid tag, missing name attribute\n");
1.55 + return;
1.56 + }
1.57 +
1.58 + import_context_add_property(ctx, data, name, version);
1.59 +}
1.60 +
1.61 +static void
1.62 +start_element(void *data, const char *name, const char **atts)
1.63 +{
1.64 + struct import_context *ctx = data;
1.65 +
1.66 + if (strcmp(name, "package") == 0)
1.67 + parse_package(ctx, atts, NULL);
1.68 + else if (strcmp(name, "requires") == 0)
1.69 + parse_property(ctx, atts, &ctx->requires);
1.70 + else if (strcmp(name, "provides") == 0)
1.71 + parse_property(ctx, atts, &ctx->provides);
1.72 +}
1.73 +
1.74 +static void
1.75 +end_element (void *data, const char *name)
1.76 +{
1.77 + struct import_context *ctx = data;
1.78 +
1.79 + if (strcmp(name, "package") == 0)
1.80 + import_context_finish_package(ctx);
1.81 +}
1.82 +
1.83 +static int
1.84 +import_rzr_file(struct import_context *ctx, const char *filename)
1.85 +{
1.86 + SHA_CTX sha1;
1.87 + XML_Parser parser;
1.88 + int fd;
1.89 + void *p;
1.90 + struct stat stat;
1.91 + unsigned char hash[20];
1.92 +
1.93 + fd = open(filename, O_RDONLY);
1.94 + if (fstat(fd, &stat) < 0)
1.95 + return -1;
1.96 + p = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1.97 + if (p == MAP_FAILED)
1.98 + return -1;
1.99 +
1.100 + parser = XML_ParserCreate(NULL);
1.101 + XML_SetUserData(parser, ctx);
1.102 + XML_SetElementHandler(parser, start_element, end_element);
1.103 + if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) {
1.104 + fprintf(stderr,
1.105 + "%s at line %d, %s\n",
1.106 + XML_ErrorString(XML_GetErrorCode(parser)),
1.107 + XML_GetCurrentLineNumber(parser),
1.108 + filename);
1.109 + return 1;
1.110 + }
1.111 +
1.112 + XML_ParserFree(parser);
1.113 +
1.114 + SHA1_Init(&sha1);
1.115 + SHA1_Update(&sha1, p, stat.st_size);
1.116 + SHA1_Final(hash, &sha1);
1.117 +
1.118 + close(fd);
1.119 +
1.120 + munmap(p, stat.st_size);
1.121 +
1.122 + return 0;
1.123 +}
1.124 +
1.125 +struct razor_set *
1.126 +razor_import_rzr_files(int count, const char *files[])
1.127 +{
1.128 + struct import_context ctx;
1.129 + int i;
1.130 +
1.131 + razor_prepare_import(&ctx);
1.132 +
1.133 + for (i = 0; i < count; i++) {
1.134 + if (import_rzr_file(&ctx, files[i]) < 0) {
1.135 + fprintf(stderr, "failed to import %s\n", files[i]);
1.136 + exit(-1);
1.137 + }
1.138 + }
1.139 +
1.140 + return razor_finish_import(&ctx);
1.141 +}
1.142 +
1.143 +/* Import a yum filelist as a razor package set. */
1.144 +
1.145 +enum {
1.146 + YUM_STATE_BEGIN,
1.147 + YUM_STATE_PACKAGE_NAME
1.148 +};
1.149 +
1.150 +struct yum_context {
1.151 + struct import_context ctx;
1.152 + struct import_property_context *current_property_context;
1.153 + char *name;
1.154 + int state;
1.155 +};
1.156 +
1.157 +static void
1.158 +yum_start_element(void *data, const char *name, const char **atts)
1.159 +{
1.160 + struct yum_context *ctx = data;
1.161 + const char *n, *version;
1.162 + int i;
1.163 +
1.164 + if (strcmp(name, "name") == 0) {
1.165 + ctx->state = YUM_STATE_PACKAGE_NAME;
1.166 + } else if (strcmp(name, "version") == 0) {
1.167 + version = NULL;
1.168 + for (i = 0; atts[i]; i += 2) {
1.169 + if (strcmp(atts[i], "ver") == 0)
1.170 + version = atts[i + 1];
1.171 + }
1.172 + import_context_add_package(&ctx->ctx, ctx->name, version);
1.173 + } else if (strcmp(name, "rpm:requires") == 0) {
1.174 + ctx->current_property_context = &ctx->ctx.requires;
1.175 + } else if (strcmp(name, "rpm:provides") == 0) {
1.176 + ctx->current_property_context = &ctx->ctx.provides;
1.177 + } else if (strcmp(name, "rpm:entry") == 0 &&
1.178 + ctx->current_property_context != NULL) {
1.179 + n = NULL;
1.180 + version = NULL;
1.181 + for (i = 0; atts[i]; i += 2) {
1.182 + if (strcmp(atts[i], "name") == 0)
1.183 + n = atts[i + 1];
1.184 + else if (strcmp(atts[i], "ver") == 0)
1.185 + version = atts[i + 1];
1.186 + }
1.187 +
1.188 + if (n == NULL) {
1.189 + fprintf(stderr, "invalid rpm:entry, "
1.190 + "missing name or version attributes\n");
1.191 + return;
1.192 + }
1.193 +
1.194 + import_context_add_property(&ctx->ctx,
1.195 + ctx->current_property_context,
1.196 + n, version);
1.197 + }
1.198 +}
1.199 +
1.200 +static void
1.201 +yum_end_element (void *data, const char *name)
1.202 +{
1.203 + struct yum_context *ctx = data;
1.204 +
1.205 + if (strcmp(name, "package") == 0) {
1.206 + free(ctx->name);
1.207 + import_context_finish_package(&ctx->ctx);
1.208 + } else if (strcmp(name, "name") == 0) {
1.209 + ctx->state = 0;
1.210 + } else if (strcmp(name, "rpm:requires") == 0) {
1.211 + ctx->current_property_context = NULL;
1.212 + } else if (strcmp(name, "rpm:provides") == 0) {
1.213 + ctx->current_property_context = NULL;
1.214 + }
1.215 +}
1.216 +
1.217 +static void
1.218 +yum_character_data (void *data, const XML_Char *s, int len)
1.219 +{
1.220 + struct yum_context *ctx = data;
1.221 +
1.222 + if (ctx->state == YUM_STATE_PACKAGE_NAME)
1.223 + ctx->name = strndup(s, len);
1.224 +}
1.225 +
1.226 +struct razor_set *
1.227 +razor_set_create_from_yum_filelist(int fd)
1.228 +{
1.229 + struct yum_context ctx;
1.230 + XML_Parser parser;
1.231 + char buf[4096];
1.232 + int len;
1.233 +
1.234 + razor_prepare_import(&ctx.ctx);
1.235 +
1.236 + parser = XML_ParserCreate(NULL);
1.237 + XML_SetUserData(parser, &ctx);
1.238 + XML_SetElementHandler(parser, yum_start_element, yum_end_element);
1.239 + XML_SetCharacterDataHandler(parser, yum_character_data);
1.240 +
1.241 + while (1) {
1.242 + len = read(fd, buf, sizeof buf);
1.243 + if (len < 0) {
1.244 + fprintf(stderr,
1.245 + "couldn't read input: %s\n", strerror(errno));
1.246 + return NULL;
1.247 + } else if (len == 0)
1.248 + break;
1.249 +
1.250 + if (XML_Parse(parser, buf, len, 0) == XML_STATUS_ERROR) {
1.251 + fprintf(stderr,
1.252 + "%s at line %d\n",
1.253 + XML_ErrorString(XML_GetErrorCode(parser)),
1.254 + XML_GetCurrentLineNumber(parser));
1.255 + return NULL;
1.256 + }
1.257 + }
1.258 +
1.259 + XML_ParserFree(parser);
1.260 +
1.261 + return razor_finish_import(&ctx.ctx);
1.262 +}