Use the cpio headers instead of the rpm headers when unpacking.
The files in the cpio payload doesn't actually follow the file order
in the rpm headers, so we need to decode the cpio header and use the
information there.
7 array_init(struct array *array)
9 memset(array, 0, sizeof *array);
13 array_release(struct array *array)
19 array_add(struct array *array, int size)
29 while (alloc < array->size + size)
32 if (array->alloc < alloc) {
33 data = realloc(array->data, alloc);
40 p = array->data + array->size;
46 /* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
47 #define RAZOR_ENTRY_LAST 0x80
48 #define RAZOR_IMMEDIATE 0x80
49 #define RAZOR_EMPTY_LIST 0xff
52 list_set_empty(struct list_head *head)
55 head->flags = RAZOR_EMPTY_LIST;
59 list_set_ptr(struct list_head *head, uint32_t ptr)
66 list_set_array(struct list_head *head, struct array *pool,
67 struct array *items, int force_indirect)
71 if (!force_indirect) {
72 if (items->size == 0) {
75 } else if (items->size == sizeof (uint32_t)) {
76 head->list_ptr = *(uint32_t *) items->data;
77 head->flags = RAZOR_IMMEDIATE;
82 p = array_add(pool, items->size);
83 memcpy(p, items->data, items->size);
84 p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
85 list_set_ptr(head, p - (struct list *) pool->data);
89 list_first(struct list_head *head, struct array *pool)
91 if (head->flags == RAZOR_EMPTY_LIST)
93 else if (head->flags == RAZOR_IMMEDIATE)
94 return (struct list *) head;
96 return (struct list *) pool->data + head->list_ptr;
100 list_next(struct list *list)
108 list_remap_pool(struct array *pool, uint32_t *map)
110 struct list *p, *end;
112 end = pool->data + pool->size;
113 for (p = pool->data; p < end; p++)
114 p->data = map[p->data];
118 list_remap_head(struct list_head *head, uint32_t *map)
120 if (head->flags == RAZOR_IMMEDIATE)
121 head->list_ptr = map[head->list_ptr];
126 hashtable_init(struct hashtable *table, struct array *pool)
128 array_init(&table->buckets);
133 hashtable_release(struct hashtable *table)
135 array_release(&table->buckets);
139 hash_string(const char *key)
142 unsigned int hash = 0;
144 for (p = key; *p; p++)
145 hash = (hash * 617) ^ *p;
151 hashtable_lookup(struct hashtable *table, const char *key)
153 unsigned int mask, start, i;
157 pool = table->pool->data;
158 mask = table->buckets.alloc - 1;
159 start = hash_string(key) * sizeof(uint32_t);
161 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
162 b = table->buckets.data + ((start + i) & mask);
167 if (strcmp(key, &pool[*b]) == 0)
175 do_insert(struct hashtable *table, uint32_t value)
177 unsigned int mask, start, i;
181 key = (char *) table->pool->data + value;
182 mask = table->buckets.alloc - 1;
183 start = hash_string(key) * sizeof(uint32_t);
185 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
186 b = table->buckets.data + ((start + i) & mask);
195 add_to_string_pool(struct hashtable *table, const char *key)
200 len = strlen(key) + 1;
201 p = array_add(table->pool, len);
204 return p - (char *) table->pool->data;
208 hashtable_insert(struct hashtable *table, const char *key)
210 uint32_t value, *buckets, *b, *end;
213 alloc = table->buckets.alloc;
214 array_add(&table->buckets, 4 * sizeof *buckets);
215 if (alloc != table->buckets.alloc) {
216 end = table->buckets.data + alloc;
217 memset(end, 0, table->buckets.alloc - alloc);
218 for (b = table->buckets.data; b < end; b++) {
222 do_insert(table, value);
227 value = add_to_string_pool(table, key);
228 do_insert (table, value);
234 hashtable_tokenize(struct hashtable *table, const char *string)
241 token = hashtable_lookup(table, string);
245 return hashtable_insert(table, string);
250 bitarray_init(struct bitarray *bitarray, int size, int initial_value)
252 int bytes = ((size + 31) / 32) * 4;
254 bitarray->bits = malloc(bytes);
255 memset(bitarray->bits, initial_value ? 0xff : 0x00, bytes);
259 bitarray_release(struct bitarray *bitarray)
261 free(bitarray->bits);
265 bitarray_set(struct bitarray *bitarray, int bit, int value)
268 bitarray->bits[bit >> 5] |= 1 << (bit & 31);
270 bitarray->bits[bit >> 5] &= ~(1 << (bit & 31));
274 bitarray_get(struct bitarray *bitarray, int bit)
276 return (bitarray->bits[bit >> 5] & (1 << (bit & 31))) != 0;