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 | |
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')
-rw-r--r-- | lib/Makefile.in | 31 | ||||
-rw-r--r-- | lib/header.c | 464 | ||||
-rw-r--r-- | lib/header.h | 85 | ||||
-rw-r--r-- | lib/messages.c | 49 | ||||
-rw-r--r-- | lib/messages.h | 17 | ||||
-rw-r--r-- | lib/misc.c | 42 | ||||
-rw-r--r-- | lib/misc.h | 7 | ||||
-rw-r--r-- | lib/oldrpmdb.h | 70 | ||||
-rw-r--r-- | lib/rpm_malloc.h | 8 | ||||
-rw-r--r-- | lib/rpmerr.c | 8 | ||||
-rw-r--r-- | lib/test.c | 32 |
11 files changed, 813 insertions, 0 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 000000000..e62a0416e --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,31 @@ +LIBS = -lefence + +LIBOBJECTS = header.o oldrpmdb.o misc.o messages.o +LIBRPM = librpm.a + +WARNINGS = -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes +DEBUG = -g +OPTS = -O2 + +all: test dump + +# ----------------------------------------------------------------------- + +AR = ar r +RANLIB = ranlib + +CFLAGS = $(WARNINGS) $(DEBUG) $(OPTS) +LDFLAGS = $(DEBUG) $(LIBS) + +test: librpm.a + $(CC) -o $@ test.c librpm.a $(LIBS) + +dump: librpm.a + $(CC) -o $@ dump.c librpm.a $(LIBS) + +$(LIBRPM): $(LIBOBJECTS) + $(AR) $@ $(LIBOBJECTS) + $(RANLIB) $@ + +clean: + rm -f *.a *.o *~ test dump test.out 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; +} diff --git a/lib/header.h b/lib/header.h new file mode 100644 index 000000000..517663ecd --- /dev/null +++ b/lib/header.h @@ -0,0 +1,85 @@ +/* RPM - Copyright (C) 1995 Red Hat Software + * + * header.h - routines for managing rpm tagged structures + */ + +#ifndef _header_h +#define _header_h +#include <stdio.h> + +#if defined(__alpha__) +typedef long int int_64; +typedef int int_32; +typedef short int int_16; +typedef char int_8; + +typedef unsigned int uint_32; + +#else + +typedef long long int int_64; +typedef long int int_32; +typedef short int int_16; +typedef char int_8; + +typedef unsigned int uint_32; +#endif + +typedef struct headerToken *Header; + +/* read and write a header from a file */ +Header readHeader(FILE *f); +Header mmapHeader(int fd, long offset); +void writeHeader(FILE *f, Header h); + +/* load and unload a header from a chunk of memory */ +Header loadHeader(void *p); +void *unloadHeader(Header h); + +Header newHeader(void); +void freeHeader(Header h); + +/* dump a header to a file, in human readable format */ +void dumpHeader(Header h, FILE *f, int flags); + +#define DUMP_INLINE 1 +#define DUMP_SYMBOLIC 2 + +int getEntry(Header h, int_32 tag, int_32 *type, void **p, int_32 *c); +int addEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c); + +/* Entry Types */ + +#define NULL_TYPE 0 +#define CHAR_TYPE 1 +#define INT8_TYPE 2 +#define INT16_TYPE 3 +#define INT32_TYPE 4 +#define INT64_TYPE 5 +#define STRING_TYPE 6 + +/* Entries */ + +#define NAME 1 +#define VERSION 2 +#define RELEASE 3 +#define SHORT_DESCRIPTION 4 +#define LONG_DESCRIPTION 5 +#define COPYRIGHT 6 +#define DISTRIBUTION 7 +#define VENDOR 8 +#define PACKAGER 9 +#define BUILD_DATE 10 +#define BUILD_HOST 11 +#define INSTALL_DATE 12 +#define GROUP 13 +#define SIZE 14 +#define URL 15 +#define OS 16 +#define ARCH 17 +#define CHANGELOG 18 +#define ICON 19 +#define SOURCE 20 +#define PATCH 21 + +#endif _header_h diff --git a/lib/messages.c b/lib/messages.c new file mode 100644 index 000000000..81ba0196b --- /dev/null +++ b/lib/messages.c @@ -0,0 +1,49 @@ +#include <stdarg.h> +#include <stdio.h> + +#include "messages.h" + +static minLevel = MESS_NORMAL; + +void increaseVerbosity(void) { + minLevel--; +} + +void setVerbosity(int level) { + minLevel = level; +} + +void message(int level, char * format, ...) { + va_list args; + + va_start(args, format); + if (level >= minLevel) { + switch (level) { + case MESS_VERBOSE: + case MESS_NORMAL: + vfprintf(stdout, format, args); + break; + + case MESS_DEBUG: + fprintf(stdout, "D: "); + vfprintf(stdout, format, args); + break; + + case MESS_WARNING: + fprintf(stderr, "warning: "); + vfprintf(stderr, format, args); + break; + + case MESS_ERROR: + fprintf(stderr, "error: "); + vfprintf(stderr, format, args); + break; + + case MESS_FATALERROR: + fprintf(stderr, "fatal error: "); + vfprintf(stderr, format, args); + exit(1); + break; + } + } +} diff --git a/lib/messages.h b/lib/messages.h new file mode 100644 index 000000000..4de2cd8be --- /dev/null +++ b/lib/messages.h @@ -0,0 +1,17 @@ +#ifndef H_MESSAGES +#define H_MESSAGES + +#define MESS_DEBUG 1 +#define MESS_VERBOSE 2 +#define MESS_NORMAL 3 +#define MESS_WARNING 4 +#define MESS_ERROR 5 +#define MESS_FATALERROR 6 + +#define MESS_QUIET (MESS_NORMAL + 1) + +void increaseVerbosity(void); +void setVerbosity(int level); +void message(int level, char * format, ...); + +#endif diff --git a/lib/misc.c b/lib/misc.c new file mode 100644 index 000000000..a08da132d --- /dev/null +++ b/lib/misc.c @@ -0,0 +1,42 @@ +#include <stdlib.h> + +#include "misc.h" + +char ** splitString(char * str, int length, char sep) { + char * s, * source, * dest; + char ** list; + int i; + int fields; + + s = malloc(length + 1); + + fields = 1; + for (source = str, dest = s, i = 0; i < length; i++, source++, dest++) { + *dest = *source; + if (*dest == sep) fields++; + } + + *dest = '\0'; + + list = malloc(sizeof(char *) * (fields + 1)); + + dest = s; + list[0] = dest; + i = 1; + while (i < fields) { + if (*dest == sep) { + list[i++] = dest + 1; + *dest = 0; + } + dest++; + } + + list[i] = NULL; + + return list; +} + +void freeSplitString(char ** list) { + free(list[0]); + free(list); +} diff --git a/lib/misc.h b/lib/misc.h new file mode 100644 index 000000000..c82a9a9a1 --- /dev/null +++ b/lib/misc.h @@ -0,0 +1,7 @@ +#ifndef H_MISC +#define H_MISC + +char ** splitString(char * str, int length, char sep); +void freeSplitString(char ** list); + +#endif diff --git a/lib/oldrpmdb.h b/lib/oldrpmdb.h new file mode 100644 index 000000000..f28a45057 --- /dev/null +++ b/lib/oldrpmdb.h @@ -0,0 +1,70 @@ +#ifndef _H_RPMDB +#define _H_RPMDB + +#include <gdbm.h> + +#include "oldrpmfile.h" + +typedef enum { RPMDB_NONE, RPMDB_GDBM_ERROR, RPMDB_NO_MEMORY } rpm_error; + +struct rpmdb { + GDBM_FILE packages; + GDBM_FILE nameIndex; + GDBM_FILE pathIndex; + GDBM_FILE groupIndex; + GDBM_FILE iconIndex; + GDBM_FILE postIndex; + rpm_error rpmdbError; + gdbm_error gdbmError; +}; + +enum rpmdbFreeType { RPMDB_NOFREE, RPMDB_FREENAME, RPMDB_FREEALL } ; + +struct rpmdbLabel { + char * name, * version, * release; + enum rpmdbFreeType freeType; + struct rpmdbLabel * next; + int fileNumber; /* -1 means invalid */ +}; + +struct rpmdbPackageInfo { + char * name, * version, * release; + char * labelstr; + unsigned int installTime, buildTime; + unsigned int size; + char * description; + char * distribution; + char * vendor; + char * buildHost; + char * preamble; + unsigned int fileCount; + struct rpmFileInfo * files; +} ; + +#define RPMDB_READER 1 + +int rpmdbOpen(struct rpmdb * rpmdb); +void rpmdbClose(struct rpmdb * rpmdb); +struct rpmdbLabel * rpmdbGetAllLabels(struct rpmdb * rpmdb); +struct rpmdbLabel * rpmdbFindPackagesByFile(struct rpmdb * rpmdb, char * path); +struct rpmdbLabel * rpmdbFindPackagesByLabel(struct rpmdb * rpmdb, + struct rpmdbLabel label); + +char * rpmdbGetPackageGroup(struct rpmdb * rpmdb, struct rpmdbLabel label); +int rpmdbGetPackageInfo(struct rpmdb * rpmdb, struct rpmdbLabel label, + struct rpmdbPackageInfo * pinfo); +void rpmdbFreePackageInfo(struct rpmdbPackageInfo package); + +struct rpmdbLabel rpmdbMakeLabel(char * name, char * version, char * release, + int fileNumber, enum rpmdbFreeType freeType); +void rpmdbFreeLabelList(struct rpmdbLabel * list); +void rpmdbFreeLabel(struct rpmdbLabel label); +int rpmdbWasError(struct rpmdb * rpmdb); + +int rpmdbLabelstrToLabel(char * str, int length, struct rpmdbLabel * label); +char * rpmdbLabelToLabelstr(struct rpmdbLabel label, int withFileNum); +int rpmdbLabelCmp(struct rpmdbLabel * one, struct rpmdbLabel * two); + +void rpmdbSetPrefix(char * new); + +#endif diff --git a/lib/rpm_malloc.h b/lib/rpm_malloc.h new file mode 100644 index 000000000..63c924693 --- /dev/null +++ b/lib/rpm_malloc.h @@ -0,0 +1,8 @@ +#ifndef H_RPM_MALLOC +#define H_RPM_MALLOC + +#ifndef __linux__ +#error malloc definition needed for non Linux OS +#endif + +#endif diff --git a/lib/rpmerr.c b/lib/rpmerr.c new file mode 100644 index 000000000..84f743ceb --- /dev/null +++ b/lib/rpmerr.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +#include "rpmerr.h" + +void error(int code, ...) +{ + fprintf(stderr, "error, error, error\n"); +} diff --git a/lib/test.c b/lib/test.c new file mode 100644 index 000000000..7e93a96ae --- /dev/null +++ b/lib/test.c @@ -0,0 +1,32 @@ +#include "header.h" + +void main(int argc, char ** argv) +{ + Header h; + FILE *f; + char *sa[] = { "one", "two", "three" }; + int_32 i32 = 400; + int_32 i32a[] = { 100, 200, 300 }; + int_16 i16 = 1; + int_16 i16a[] = { 100, 200, 300 }; + char ca[] = "char array"; + + h = newHeader(); + + addEntry(h, NAME, STRING_TYPE, "MarcEwing", 1); + addEntry(h, VERSION, STRING_TYPE, "1.1", 1); + addEntry(h, VERSION, STRING_TYPE, sa, 3); + addEntry(h, SIZE, INT32_TYPE, &i32, 1); + addEntry(h, SIZE, INT16_TYPE, &i16, 1); + addEntry(h, SIZE, INT16_TYPE, i16a, 3); + addEntry(h, VENDOR, CHAR_TYPE, ca, strlen(ca)); + addEntry(h, SIZE, INT32_TYPE, i32a, 3); + + f = fopen("test.out", "w"); + writeHeader(f, h); + fclose(f); + + dumpHeader(h, stdout, 1); +} + + |