struct yum_context {
struct razor_importer *importer;
struct import_property_context *current_property_context;
- char *name;
+ char name[256], buffer[512], *p;
int state;
};
if (strcmp(name, "name") == 0) {
ctx->state = YUM_STATE_PACKAGE_NAME;
+ ctx->p = ctx->name;
} else if (strcmp(name, "version") == 0) {
version = NULL;
for (i = 0; atts[i]; i += 2) {
}
} else if (strcmp(name, "file") == 0) {
ctx->state = YUM_STATE_FILE;
+ ctx->p = ctx->buffer;
}
}
struct yum_context *ctx = data;
ctx->state = YUM_STATE_BEGIN;
- if (strcmp(name, "package") == 0) {
- free(ctx->name);
+ if (strcmp(name, "package") == 0)
razor_importer_finish_package(ctx->importer);
- }
+ else if (strcmp(name, "file") == 0)
+ razor_importer_add_file(ctx->importer, ctx->buffer);
}
static void
yum_character_data (void *data, const XML_Char *s, int len)
{
struct yum_context *ctx = data;
- char filename[PATH_MAX];
- if (ctx->state == YUM_STATE_PACKAGE_NAME)
- ctx->name = strndup(s, len);
- else if (ctx->state == YUM_STATE_FILE) {
- snprintf(filename, sizeof filename, "%.*s", len, s);
- razor_importer_add_file(ctx->importer, filename);
+ switch (ctx->state) {
+ case YUM_STATE_PACKAGE_NAME:
+ case YUM_STATE_FILE:
+ memcpy(ctx->p, s, len);
+ ctx->p += len;
+ *ctx->p = '\0';
+ break;
}
}
}
static int
+command_list_files(int argc, const char *argv[])
+{
+ struct razor_set *set;
+
+ set = razor_set_open(repo_filename);
+ if (set == NULL)
+ return 1;
+ razor_set_list_files(set);
+ razor_set_destroy(set);
+
+ return 0;
+}
+
+static int
command_what_requires(int argc, const char *argv[])
{
struct razor_set *set;
{ "list", "list all packages", command_list },
{ "list-requires", "list all requires or requires for the given package", command_list_requires },
{ "list-provides", "list all provides or provides for the give package", command_list_provides },
+ { "list-files", "list files for package set", command_list_files },
{ "what-requires", "list the packages that have the given requires", command_what_requires },
{ "what-provides", "list the packages that have the given provides", command_what_provides },
{ "import-yum", "import yum filelist.xml on stdin", command_import_yum },
#define RAZOR_PACKAGE_POOL 4
#define RAZOR_REQUIRES_POOL 5
#define RAZOR_PROVIDES_POOL 6
+#define RAZOR_FILE_TREE 7
struct razor_package {
unsigned long name;
unsigned long packages;
};
+struct razor_entry {
+ unsigned long name;
+ unsigned long count;
+ unsigned long start;
+};
+
struct razor_set {
struct array string_pool;
struct array packages;
struct array provides;
struct array requires_pool;
struct array provides_pool;
+ struct array file_tree;
struct razor_set_header *header;
};
struct import_property_context requires;
struct import_property_context provides;
struct razor_package *package;
+ struct array files;
};
static void
{ RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
{ RAZOR_REQUIRES_POOL, offsetof(struct razor_set, requires_pool) },
{ RAZOR_PROVIDES_POOL, offsetof(struct razor_set, provides_pool) },
+ { RAZOR_FILE_TREE, offsetof(struct razor_set, file_tree) },
};
struct razor_set *
void
razor_importer_add_file(struct razor_importer *importer, const char *name)
{
+ char **p;
+
+ p = array_add(&importer->files, sizeof *p);
+ *p = strdup(name);
}
struct razor_importer *
*p = map[*p];
}
+static int
+compare_filenames(const void *p1, const void *p2, void *data)
+{
+ char *f1 = *(char **) p1;
+ char *f2 = *(char **) p2;
+
+ return strcmp(f1, f2);
+}
+
+struct directory {
+ unsigned long name, count;
+ struct array files;
+ struct directory *last;
+};
+
+static void
+count_entries(struct directory *d)
+{
+ struct directory *p, *end;
+
+ p = d->files.data;
+ end = d->files.data + d->files.size;
+ d->count = 0;
+ while (p < end) {
+ count_entries(p);
+ d->count += p->count + 1;
+ p++;
+ }
+}
+
+static void
+serialize_files(struct directory *d, struct array *array)
+{
+ struct directory *p, *end;
+ struct razor_entry *e;
+ unsigned long s;
+
+ p = d->files.data;
+ end = d->files.data + d->files.size;
+ s = array->size / sizeof *e + d->files.size / sizeof *p;
+ while (p < end) {
+ e = array_add(array, sizeof *e);
+ e->name = p->name;
+ e->count = p->files.size / sizeof *p;
+ e->start = s;
+ s += p->count;
+ p++;
+ }
+
+ p = d->files.data;
+ end = d->files.data + d->files.size;
+ while (p < end) {
+ serialize_files(p, array);
+ p++;
+ }
+}
+
+static void
+build_file_tree(struct razor_importer *importer)
+{
+ int count, i, length;
+ char **filenames, *f, *end;
+ unsigned long name;
+ char dirname[256];
+ struct directory *d, root;
+ struct razor_entry *e;
+
+ count = importer->files.size / sizeof (char *);
+ qsort_with_data(importer->files.data,
+ count,
+ sizeof (char *),
+ compare_filenames,
+ NULL);
+
+ root.name = razor_importer_tokenize(importer, "");
+ array_init(&root.files);
+ root.last = NULL;
+
+ filenames = importer->files.data;
+ for (i = 0; i < count; i++) {
+ f = filenames[i];
+ if (*f != '/')
+ continue;
+
+ d = &root;
+ while (*f) {
+ end = strchr(f + 1, '/');
+ if (end == NULL)
+ end = f + strlen(f);
+ length = end - (f + 1);
+ memcpy(dirname, f + 1, length);
+ dirname[length] ='\0';
+ name = razor_importer_tokenize(importer, dirname);
+ if (d->last == NULL || d->last->name != name) {
+ d->last = array_add(&d->files, sizeof *d);
+ d->last->name = name;
+ d->last->last = NULL;
+ array_init(&d->last->files);
+ }
+ d = d->last;
+ f = end;
+ }
+
+ free(filenames[i]);
+ }
+
+ count_entries(&root);
+ array_init(&importer->set->file_tree);
+
+ e = array_add(&importer->set->file_tree, sizeof *e);
+ e->name = root.name;
+ e->count = root.files.size / sizeof *d;
+ e->start = 1;
+
+ serialize_files(&root, &importer->set->file_tree);
+
+ array_release(&importer->files);
+}
+
+static void
+list_dir(struct razor_set *set, struct razor_entry *e, int indent)
+{
+ struct razor_entry *c;
+ char *pool = set->string_pool.data;
+ int i;
+
+ for (i = 0; i < indent; i++)
+ putchar(' ');
+ printf("%s\n", pool + e->name);
+ for (i = 0; i < e->count; i++) {
+ c = (struct razor_entry *) set->file_tree.data + e->start + i;
+ list_dir(set, c, indent + 2);
+ }
+}
+
+void
+razor_set_list_files(struct razor_set *set)
+{
+ list_dir(set, set->file_tree.data, 2);
+}
+
struct razor_set *
razor_importer_finish(struct razor_importer *importer)
{
free(map);
free(rmap);
+ build_file_tree(importer);
+
set = importer->set;
array_release(&importer->buckets);
free(importer);