diff options
author | root <devnull@localhost> | 1995-11-27 22:31:21 +0000 |
---|---|---|
committer | root <devnull@localhost> | 1995-11-27 22:31:21 +0000 |
commit | 7153c160969d70a083f791bf75f9b4d09d2f2a45 (patch) | |
tree | 8548631eab9ea9afa933aba9ef1ec7d48a5bb5d4 /lib/header.c | |
download | rpm-7153c160969d70a083f791bf75f9b4d09d2f2a45.tar.gz rpm-7153c160969d70a083f791bf75f9b4d09d2f2a45.tar.bz2 rpm-7153c160969d70a083f791bf75f9b4d09d2f2a45.zip |
Initial revision
CVS patchset: 1
CVS date: 1995/11/27 22:31:21
Diffstat (limited to 'lib/header.c')
-rw-r--r-- | lib/header.c | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/lib/header.c b/lib/header.c new file mode 100644 index 000000000..116496527 --- /dev/null +++ b/lib/header.c @@ -0,0 +1,464 @@ +/* RPM - Copyright (C) 1995 Red Hat Software + * + * header.c - routines for managing rpm headers + */ + +#include <asm/byteorder.h> +#include <sys/mman.h> +#include <ctype.h> +#include <string.h> +#include <malloc.h> +#include "header.h" + +#define INDEX_MALLOC_SIZE 8 +#define DATA_MALLOC_SIZE 1024 + +struct headerToken { + struct indexEntry *index; + int entries_malloced; + int entries_used; + + char *data; + int data_malloced; + int data_used; + + caddr_t mmapped_address; + + int mutable; +}; + +/* All this is in network byte order! */ +struct indexEntry { + int_32 tag; + int_32 type; + int_32 offset; /* Offset from beginning of data segment */ + int_32 count; +}; + +/********************************************************************/ + +void writeHeader(FILE *f, Header h) +{ + int_32 l; + + /* First write out the length of the index (count of index entries) */ + l = htonl(h->entries_used); + fwrite(&l, sizeof(l), 1, f); + + /* And the length of the data (number of bytes) */ + l = htonl(h->data_used); + fwrite(&l, sizeof(l), 1, f); + + /* Now write the index */ + fwrite(h->index, sizeof(struct indexEntry), h->entries_used, f); + + /* Finally write the data */ + fwrite(h->data, h->data_used, 1, f); +} + +Header mmapHeader(int fd, long offset) +{ + struct headerToken * h = malloc(sizeof(struct headerToken)); + int_32 * p1, il, dl; + caddr_t p; + size_t bytes = 2 * sizeof(int_32); + + p = mmap(0, bytes, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, offset); + if (!p) + return NULL; + + p1 = (int_32 *) p; + + il = ntohl(*p1++); + dl = ntohl(*p1++); + if (munmap((caddr_t) p, 0)) { + return NULL; + } + + bytes += il * sizeof(struct indexEntry) + dl; + p = mmap(0, bytes, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); + h->index = (void *) (p + 2 * sizeof(int_32)); + h->data = (void *) (p + 2 * sizeof(int_32) + il * sizeof(struct indexEntry)); + + h->entries_malloced = il; + h->entries_used = il; + h->data_malloced = dl; + h->data_used = dl; + h->mutable = 0; + h->mmapped_address = p; + + return h; +} + +Header readHeader(FILE *f) +{ + int_32 il, dl; + + struct headerToken *h = (struct headerToken *) + malloc(sizeof(struct headerToken)); + + /* First read the index length (count of index entries) */ + fread(&il, sizeof(il), 1, f); + il = ntohl(il); + + /* Then read the data length (number of bytes) */ + fread(&dl, sizeof(dl), 1, f); + dl = ntohl(dl); + + /* Next read the index */ + h->index = malloc(il * sizeof(struct indexEntry)); + h->entries_malloced = il; + h->entries_used = il; + fread(h->index, sizeof(struct indexEntry), il, f); + + /* Finally, read the data */ + h->data = malloc(dl); + h->data_malloced = dl; + h->data_used = dl; + fread(h->data, dl, 1, f); + + h->mutable = 0; + + return h; +} + +Header loadHeader(void *pv) +{ + int_32 il, dl; + char * p = pv; + struct headerToken *h = malloc(sizeof(struct headerToken)); + + il = ntohl( *((int_32 *)p) ); + p += sizeof(int_32); + dl = ntohl( *((int_32 *)p) ); + p += sizeof(int_32); + + h->entries_malloced = il; + h->entries_used = il; + h->index = (struct indexEntry *) p; + p += il * sizeof(struct indexEntry); + + h->data_malloced = dl; + h->data_used = dl; + h->data = p; + + h->mutable = 0; + + return h; +} + +void *unloadHeader(Header h) +{ + void *p; + int_32 *pi; + + pi = p = malloc(2 * sizeof(int_32) + + h->entries_used * sizeof(struct indexEntry) + + h->data_used); + + *pi++ = h->entries_used; + *pi++ = h->data_used; + memcpy(pi, h->index, h->entries_used * sizeof(struct indexEntry)); + pi += h->entries_used * sizeof(struct indexEntry); + memcpy(pi, h->data, h->data_used); + + return p; +} + +void dumpHeader(Header h, FILE *f, int flags) +{ + int i, c, ct; + struct indexEntry *p; + char *dp; + char ch; + + /* First write out the length of the index (count of index entries) */ + fprintf(f, "Entry count: %d\n", h->entries_used); + + /* And the length of the data (number of bytes) */ + fprintf(f, "Data count : %d\n", h->data_used); + + /* Now write the index */ + p = h->index; + /* Entry : 00 0x00000000 0x00000000 0x00000000 0x00000000 */ + fprintf(f, "\n CT TAG TYPE OFFSET COUNT\n"); + for (i = 0; i < h->entries_used; i++) { + fprintf(f, "Entry : %.3d 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", i, + (uint_32) ntohl(p->tag), (uint_32) ntohl(p->type), + (uint_32) ntohl(p->offset), (uint_32) ntohl(p->count)); + + if (flags & DUMP_INLINE) { + /* Print the data inline */ + dp = h->data + ntohl(p->offset); + c = ntohl(p->count); + ct = 0; + switch (ntohl(p->type)) { + case INT32_TYPE: + while (c--) { + fprintf(f, " Data: %.3d 0x%.8x (%d)\n", ct++, + (uint_32) ntohl(*((int_32 *)dp)), + (uint_32) ntohl(*((int_32 *)dp))); + dp += sizeof(int_32); + } + break; + + case INT16_TYPE: + while (c--) { + fprintf(f, " Data: %.3d 0x%.4x (%d)\n", ct++, + (short int) ntohs(*((int_16 *)dp)), + (short int) ntohs(*((int_16 *)dp))); + dp += sizeof(int_16); + } + break; + case INT8_TYPE: + while (c--) { + fprintf(f, " Data: %.3d 0x%.2x (%d)\n", ct++, + (char) *((int_8 *)dp), + (char) *((int_8 *)dp)); + dp += sizeof(int_8); + } + break; + case CHAR_TYPE: + while (c--) { + ch = (char) *((char *)dp); + fprintf(f, " Data: %.3d 0x%2x %c (%d)\n", ct++, + ch, + (isprint(ch) ? ch : ' '), + (char) *((char *)dp)); + dp += sizeof(char); + } + break; + case STRING_TYPE: + while (c--) { + fprintf(f, " Data: %.3d %s\n", ct++, (char *)dp); + dp = strchr(dp, 0); + dp++; + } + break; + default: + fprintf(stderr, "Data type %d not supprted\n", (int)ntohl(p->type)); + exit(1); + } + } + p++; + } +} + +void freeHeader(Header h) +{ + if (h->mutable) { + free(h->index); + free(h->data); + } + if (h->mmapped_address) { + munmap(h->mmapped_address, 0); + } + free(h); +} + +int getEntry(Header h, int_32 tag, int_32 *type, void **p, int_32 *c) +{ + struct indexEntry *index = h->index; + int x = h->entries_used; + char **spp; + char *sp; + + /* First find the tag */ + tag = htonl(tag); + while (x && (tag != index->tag)) { + index++; + x--; + } + if (x == 0) { + return 0; + } + + *type = ntohl(index->type); + *c = ntohl(index->count); + + /* Now look it up */ + switch (*type) { + case INT64_TYPE: + case INT32_TYPE: + case INT16_TYPE: + case INT8_TYPE: + case CHAR_TYPE: + *p = h->data + ntohl(index->offset); + break; + case STRING_TYPE: + if (*c == 1) { + /* Special case -- just return a pointer to the string */ + *p = h->data + ntohl(index->offset); + } else { + /* Otherwise, build up an array of char* to return */ + x = index->count; + p = malloc(x * sizeof(char *)); + spp = (char **)p; + sp = h->data + ntohl(index->offset); + while(x--) { + *spp++ = sp; + sp = strchr(sp, 0); + sp++; + } + } + break; + default: + fprintf(stderr, "Data type %d not supprted\n", (int) *type); + exit(1); + } + + return 1; +} + +/********************************************************************/ + +/* + * The following routines are used to build up a header. + */ + +Header newHeader() +{ + struct headerToken *h = (struct headerToken *) + malloc(sizeof(struct headerToken)); + + h->data = malloc(DATA_MALLOC_SIZE); + h->data_malloced = DATA_MALLOC_SIZE; + h->data_used = 0; + + h->index = malloc(INDEX_MALLOC_SIZE * sizeof(struct indexEntry)); + h->entries_malloced = INDEX_MALLOC_SIZE; + h->entries_used = 0; + + h->mutable = 1; + h->mmapped_address = (caddr_t) 0; + + return (Header) h; +} + +int addEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c) +{ + struct indexEntry *entry; + void *ptr; + char **spp; + char *sp; + int_32 *i32p; + int_16 *i16p; + int i, length; + + if (c <= 0) { + fprintf(stderr, "Bad count for addEntry(): %d\n", (int)c); + exit(1); + } + + if (h->mutable == 0) { + fprintf(stderr, "Attempted addEntry() to immutable header.\n"); + exit(1); + } + + /* Allocate more index space if necessary */ + if (h->entries_used == h->entries_malloced) { + h->entries_malloced += INDEX_MALLOC_SIZE; + h->index = realloc(h->index, + h->entries_malloced * sizeof(struct indexEntry)); + } + + /* Fill in the index */ + i = h->entries_used++; + entry = &((h->index)[i]); + entry->tag = htonl(tag); + entry->type = htonl(type); + entry->count = htonl(c); + entry->offset = htonl(h->data_used); + + /* Compute length of data to add */ + switch (type) { + case INT64_TYPE: + length = sizeof(int_64) * c; + break; + case INT32_TYPE: + length = sizeof(int_32) * c; + break; + case INT16_TYPE: + length = sizeof(int_16) * c; + break; + case INT8_TYPE: + length = sizeof(int_8) * c; + break; + case CHAR_TYPE: + length = sizeof(char) * c; + break; + case STRING_TYPE: + if (c == 1) { + /* Special case -- p is just the string */ + length = strlen(p) + 1; + } else { + /* Compute sum of length of all strings, including null terminators */ + i = c; + spp = p; + length = 0; + while (i--) { + /* add one for null termination */ + length += strlen(*spp++) + 1; + } + } + break; + default: + fprintf(stderr, "Data type %d not supprted\n", (int)type); + exit(1); + } + + /* Allocate more data space if necessary */ + if ((length + h->data_used) > h->data_malloced) { + h->data_malloced += DATA_MALLOC_SIZE; + h->data = realloc(h->data, h->data_malloced); + } + + /* Fill in the data */ + ptr = h->data + h->data_used; + switch (type) { + case INT32_TYPE: + memcpy(ptr, p, length); + i = c; + i32p = (int_32 *)ptr; + while (i--) { + *i32p = htonl(*i32p); + i32p++; + } + break; + case INT16_TYPE: + memcpy(ptr, p, length); + i = c; + i16p = (int_16 *)ptr; + while (i--) { + *i16p = htons(*i16p); + i16p++; + } + break; + case INT8_TYPE: + case CHAR_TYPE: + memcpy(ptr, p, length); + break; + case STRING_TYPE: + if (c == 1) { + /* Special case -- p is just the string */ + strcpy(ptr, p); + } else { + /* Otherwise, p is char** */ + i = c; + spp = p; + sp = (char *)ptr; + while (i--) { + strcpy(sp, *spp); + sp += strlen(*spp++) + 1; + } + } + break; + default: + fprintf(stderr, "Data type %d not supprted\n", (int)type); + exit(1); + } + + h->data_used += length; + + return 1; +} |