Initial revision

CVS patchset: 1
CVS date: 1995/11/27 22:31:21
This commit is contained in:
root 1995-11-27 22:31:21 +00:00
commit 7153c16096
19 changed files with 1544 additions and 0 deletions

25
Makefile.in Normal file
View File

@ -0,0 +1,25 @@
SUBDIRS = lib
OBJS = spec.o
PROGS = build
WARNINGS = -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes
DEBUG = -g
OPTS = -O2
CFLAGS = $(WARNINGS) $(DEBUG) $(OPTS) -Ilib
LDFLAGS = $(DEBUG) -Llib
LOADLIBES = -lrpm
all: make-subdirs $(OBJS) $(PROGS)
make-subdirs:
for d in $(SUBDIRS); do \
(cd $$d; $(MAKE)) ;\
done
build: build.o spec.o
clean:
for d in $(SUBDIRS); do \
(cd $$d; $(MAKE) $@) ;\
done
rm -f *.o *~ $(PROGS)

12
build/build.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include "spec.h"
void main(int argc, char **argv)
{
FILE *f;
printf("hello\n");
f = fopen(argv[1], "r");
parse_spec(f);
fclose(f);
}

118
build/spec.c Normal file
View File

@ -0,0 +1,118 @@
/* RPM - Copyright (C) 1995 Red Hat Software
*
* spec.c - routines for parsing a spec file
*/
#include "header.h"
#include "spec.h"
#include "rpmerr.h"
#include <stdlib.h>
#include <string.h>
#define LINE_BUF_SIZE 1024
struct spec {
Header header;
char *prep;
char *build;
char *install;
char *clean;
};
void free_spec(Spec s)
{
freeHeader(s->header);
free(s->prep);
free(s->build);
free(s->install);
free(s->clean);
free(s);
}
static int read_line(FILE *f, char *line);
static int match_arch(char *s);
static int match_os(char *s);
static int match_arch(char *s)
{
if (! strncmp(s, "%ifarch i386", 12)) {
return 1;
} else {
return 0;
}
}
static int match_os(char *s)
{
if (! strncmp(s, "%ifos linux", 11)) {
return 1;
} else {
return 0;
}
}
static int reading = 0;
static int iflevels = 0;
static int skiplevels = 0;
static int skip = 0;
static int read_line(FILE *f, char *line)
{
char *r = fgets(line, LINE_BUF_SIZE, f);
if (! r) {
/* the end */
if (iflevels) return RPMERR_UNMATCHEDIF;
return 0;
}
skip = 0;
if (! strncmp("%ifarch", line, 7)) {
iflevels++;
skip = 1;
if (! match_arch(line)) {
reading = 0;
skiplevels++;
}
}
if (! strncmp("%ifos", line, 5)) {
iflevels++;
skip = 1;
if (! match_os(line)) {
reading = 0;
skiplevels++;
}
}
if (! strncmp("%endif", line, 6)) {
iflevels--;
skip = 1;
if (skiplevels) {
if (! --skiplevels) reading = 1;
}
}
return 1;
}
Spec parse_spec(FILE *f)
{
char line[LINE_BUF_SIZE];
Spec s = (struct spec *) malloc(sizeof(struct spec));
int x;
reading = 1;
while ((x = read_line(f, line))) {
if (!reading) continue;
if (skip) continue;
puts(line);
}
if (x < 0) {
/* error */
return NULL;
}
return s;
}

14
build/spec.h Normal file
View File

@ -0,0 +1,14 @@
/* RPM - Copyright (C) 1995 Red Hat Software
*
* spec.h - routines for parsing are looking up info in a spec file
*/
#ifndef _spec_h
#define _spec_h
typedef struct spec *Spec;
Spec parse_spec(FILE *f);
void free_spec(Spec s);
#endif _spec_h

7
convertdb.c Normal file
View File

@ -0,0 +1,7 @@
/* This converts an old style (rpm 1.x) database to the new style */
#include <oldrpmdb.h>
int convertDB(char * dbprefix) {
}

31
lib/Makefile.in Normal file
View File

@ -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

464
lib/header.c Normal file
View File

@ -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;
}

85
lib/header.h Normal file
View File

@ -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

49
lib/messages.c Normal file
View File

@ -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;
}
}
}

17
lib/messages.h Normal file
View File

@ -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

42
lib/misc.c Normal file
View File

@ -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);
}

7
lib/misc.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef H_MISC
#define H_MISC
char ** splitString(char * str, int length, char sep);
void freeSplitString(char ** list);
#endif

70
lib/oldrpmdb.h Normal file
View File

@ -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

8
lib/rpm_malloc.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef H_RPM_MALLOC
#define H_RPM_MALLOC
#ifndef __linux__
#error malloc definition needed for non Linux OS
#endif
#endif

8
lib/rpmerr.c Normal file
View File

@ -0,0 +1,8 @@
#include <stdio.h>
#include "rpmerr.h"
void error(int code, ...)
{
fprintf(stderr, "error, error, error\n");
}

32
lib/test.c Normal file
View File

@ -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);
}

498
oldrpmdb.c Normal file
View File

@ -0,0 +1,498 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rpmerr.h"
#include "rpm_malloc.h"
#include "messages.h"
#include "misc.h"
#include "oldrpmdb.h"
static int labelstrlistToLabelList(char * str, int length,
struct rpmdbLabel ** list);
static char * prefix = "/var/lib/rpm";
char * rpmdbLabelToLabelstr(struct rpmdbLabel label, int withFileNum) {
char * c;
char buffer[50];
if (withFileNum && label.fileNumber > -1)
c = malloc(strlen(label.name) + strlen(label.version) +
strlen(label.release) + 10);
else
c = malloc(strlen(label.name) + strlen(label.version) +
strlen(label.release) + 3);
strcpy(c, label.name);
strcat(c, ":");
strcat(c, label.version);
strcat(c, ":");
strcat(c, label.release);
if (withFileNum && label.fileNumber > -1) {
sprintf(buffer, "%d", label.fileNumber);
strcat(c, ":");
strcat(c, buffer);
}
return c;
}
int rpmdbLabelstrToLabel(char * str, int length, struct rpmdbLabel * label) {
char * chptr;
label->freeType = RPMDB_FREENAME;
label->next = NULL;
label->name = malloc(length + 1);
if (!label->name) {
return 1;
}
memcpy(label->name, str, length);
label->name[length] = '\0';
chptr = label->name;
while (*chptr != ':') chptr++;
*chptr = '\0';
label->version = ++chptr;
while (*chptr != ':') chptr++;
*chptr = '\0';
label->release = chptr + 1;
label->fileNumber = -1;
/* there might be a path number tagged on to the end of this */
while ((chptr - label->name) < length && *chptr != ':') chptr++;
if ((chptr - label->name) < length) {
*chptr = '\0';
label->fileNumber = atoi(chptr + 1);
}
return 0;
}
static int labelstrlistToLabelList(char * str, int length,
struct rpmdbLabel ** list) {
char * start, * chptr;
struct rpmdbLabel * head = NULL;
struct rpmdbLabel * tail = NULL;
struct rpmdbLabel * label;
start = str;
for (chptr = start; (chptr - str) < length; chptr++) {
/* spaces following a space get ignored */
if (*chptr == ' ' && start < chptr) {
label = malloc(sizeof(struct rpmdbLabel));
if (!label) {
rpmdbFreeLabelList(head);
return 1;
}
if (rpmdbLabelstrToLabel(start, chptr - start, label)) {
free(label);
rpmdbFreeLabelList(head);
return 1;
}
if (!head) {
head = label;
tail = label;
} else {
tail->next = label;
tail = tail->next;
}
start = chptr + 1;
}
}
/* a space on the end would break things horribly w/o this test */
if (start < chptr) {
label = malloc(sizeof(struct rpmdbLabel));
if (!label) {
rpmdbFreeLabelList(head);
return 1;
}
if (rpmdbLabelstrToLabel(start, chptr - start, label)) {
free(label);
rpmdbFreeLabelList(head);
return 1;
}
if (!head) {
head = label;
tail = label;
} else {
tail->next = label;
tail = tail->next;
}
start = chptr + 1;
}
*list = head;
return 0;
}
/* returns 0 on success, -1 on failure */
int rpmdbOpen(struct rpmdb * rpmdb) {
unsigned int gdbmFlags;
char path[255];
int goterr = 0;
rpmdb->rpmdbError = RPMDB_NONE;
gdbmFlags = GDBM_READER;
strcpy(path, prefix);
strcat(path, "/packages");
rpmdb->packages = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
if (!rpmdb->packages) {
error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
goterr = 1;
}
strcpy(path, prefix);
strcat(path, "/nameidx");
rpmdb->nameIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
if (!rpmdb->packages) {
error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
goterr = 1;
}
strcpy(path, prefix);
strcat(path, "/pathidx");
rpmdb->pathIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
if (!rpmdb->packages) {
error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
goterr = 1;
}
strcpy(path, prefix);
strcat(path, "/iconidx");
rpmdb->iconIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
if (!rpmdb->iconIndex) {
error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
goterr = 1;
}
strcpy(path, prefix);
strcat(path, "/groupindex");
rpmdb->groupIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
if (!rpmdb->packages) {
error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
goterr = 1;
}
strcpy(path, prefix);
strcat(path, "/postidx");
rpmdb->postIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
if (!rpmdb->postIndex) {
error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
goterr = 1;
}
if (goterr) {
rpmdbClose(rpmdb);
return -1;
}
return 0;
}
void rpmdbClose(struct rpmdb * rpmdb) {
gdbm_close(rpmdb->packages);
gdbm_close(rpmdb->nameIndex);
gdbm_close(rpmdb->pathIndex);
gdbm_close(rpmdb->postIndex);
gdbm_close(rpmdb->groupIndex);
gdbm_close(rpmdb->iconIndex);
}
struct rpmdbLabel * rpmdbGetAllLabels(struct rpmdb * rpmdb) {
datum rec;
struct rpmdbLabel * head = NULL;
struct rpmdbLabel * tail = NULL;
struct rpmdbLabel * label;
rpmdb->rpmdbError = RPMDB_NONE;
rec = gdbm_firstkey(rpmdb->packages);
while (rec.dptr) {
label = malloc(sizeof(struct rpmdbLabel));
if (!label) {
rpmdbFreeLabelList(head);
rpmdb->rpmdbError = RPMDB_NO_MEMORY;
return NULL;
}
if (rpmdbLabelstrToLabel(rec.dptr, rec.dsize, label)) {
free(label);
rpmdbFreeLabelList(head);
rpmdb->rpmdbError = RPMDB_NO_MEMORY;
return NULL;
}
if (!head) {
head = label;
tail = label;
} else {
tail->next = label;
tail = tail->next;
}
rec = gdbm_nextkey(rpmdb->packages, rec);
}
return head;
}
struct rpmdbLabel * rpmdbFindPackagesByFile(struct rpmdb * rpmdb, char * path) {
datum rec;
datum key;
struct rpmdbLabel * list;
rpmdb->rpmdbError = RPMDB_NONE;
key.dptr = path;
key.dsize = strlen(path);
rec = gdbm_fetch(rpmdb->pathIndex, key);
if (!rec.dptr)
return NULL;
if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
free(rec.dptr);
rpmdb->rpmdbError = RPMDB_NO_MEMORY;
return NULL;
}
free(rec.dptr);
return list;
}
struct rpmdbLabel * rpmdbFindPackagesByLabel(struct rpmdb * rpmdb,
struct rpmdbLabel label)
/* the Name has to be here. The version/release fields optionally
restrict the search. Either will do. */
{
datum rec;
datum key;
struct rpmdbLabel * list;
struct rpmdbLabel * prospect;
struct rpmdbLabel * parent;
int bad;
rpmdb->rpmdbError = RPMDB_NONE;
key.dptr = label.name;
key.dsize = strlen(label.name);
rec = gdbm_fetch(rpmdb->nameIndex, key);
if (!rec.dptr)
return NULL;
if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
free(rec.dptr);
rpmdb->rpmdbError = RPMDB_NO_MEMORY;
return NULL;
}
free(rec.dptr);
prospect = list;
parent = NULL;
while (prospect) {
bad = 0;
if (label.version && strcmp(label.version, prospect->version))
bad = 1;
else if (label.release && strcmp(label.release, prospect->release))
bad = 1;
if (bad) {
rpmdbFreeLabel(*prospect);
if (!parent) {
list = prospect->next;
free(prospect);
prospect = list;
} else {
parent->next = prospect->next;
free(prospect);
prospect = parent->next;
}
} else {
prospect = prospect->next;
}
}
return list;
}
struct rpmdbLabel rpmdbMakeLabel(char * name, char * version, char * release,
int fileNumber, enum rpmdbFreeType freeType) {
struct rpmdbLabel label;
label.next = NULL;
label.freeType = freeType;
label.name = name;
label.version = version;
label.release = release;
label.fileNumber = fileNumber;
return label;
}
void rpmdbFreeLabelList(struct rpmdbLabel * list) {
struct rpmdbLabel * saved;
while (list) {
rpmdbFreeLabel(*list);
saved = list->next;
free(list);
list = saved;
}
}
void rpmdbFreeLabel(struct rpmdbLabel label) {
if (label.freeType == RPMDB_NOFREE) return;
free(label.name);
if (label.freeType == RPMDB_FREEALL) {
free(label.version);
free(label.release);
}
}
/* Returns NULL on error */
char * rpmdbGetPackageGroup(struct rpmdb * rpmdb, struct rpmdbLabel label) {
datum key, rec;
key.dptr = label.name;
key.dsize = strlen(label.name);
rec = gdbm_fetch(rpmdb->groupIndex, key);
if (!rec.dptr)
error(RPMERR_OLDDBCORRUPT, "group not found in database");
return rec.dptr;
}
/* return 0 on success, 1 on failure */
int rpmdbGetPackageInfo(struct rpmdb * rpmdb, struct rpmdbLabel label,
struct rpmdbPackageInfo * pinfo) {
char * labelstr;
char ** list, ** prelist;
char ** strptr;
datum key, rec;
int i, j;
labelstr = rpmdbLabelToLabelstr(label, 0);
message(MESS_DEBUG, "pulling %s from database\n", labelstr);
key.dptr = labelstr;
key.dsize = strlen(labelstr);
rec = gdbm_fetch(rpmdb->packages, key);
if (!rec.dptr)
error(RPMERR_OLDDBCORRUPT, "package not found in database");
return 1;
free(labelstr);
list = splitString(rec.dptr, rec.dsize, '\1');
free(rec.dptr);
pinfo->version = strdup(list[1]);
pinfo->release = strdup(list[2]);
/* list[3] == "1" always */
pinfo->name = malloc(strlen(list[0]) + strlen(list[4]) + 2);
strcpy(pinfo->name, list[0]);
if (strlen(list[4])) {
strcat(pinfo->name, "-");
strcat(pinfo->name, list[4]);
}
pinfo->labelstr = malloc(strlen(pinfo->name) + strlen(pinfo->version) +
strlen(pinfo->release) + 3);
strcpy(pinfo->labelstr, pinfo->name);
strcat(pinfo->labelstr, ":");
strcat(pinfo->labelstr, pinfo->version);
strcat(pinfo->labelstr, ":");
strcat(pinfo->labelstr, pinfo->release);
pinfo->preamble = strdup(list[5]);
pinfo->installTime = atoi(list[6]);
pinfo->fileCount = atoi(list[7]);
prelist = splitString(pinfo->preamble, strlen(pinfo->preamble), '\n');
/* these are optional */
pinfo->distribution = NULL;
pinfo->vendor = NULL;
pinfo->description = NULL;
for (strptr = prelist; *strptr; strptr++) {
if (!strncmp("Description: ", *strptr, 13))
pinfo->description = strdup((*strptr) + 13);
else if (!strncmp("Distribution: ", *strptr, 14))
pinfo->distribution = strdup((*strptr) + 14);
else if (!strncmp("Vendor: ", *strptr, 8))
pinfo->vendor = strdup((*strptr) + 8);
else if (!strncmp("size: ", *strptr, 6))
pinfo->size = atoi((*strptr) + 6);
else if (!strncmp("BuildTime: ", *strptr, 11))
pinfo->buildTime =atoi((*strptr) + 11);
else if (!strncmp("BuildHost: ", *strptr, 11))
pinfo->buildHost = strdup((*strptr) + 11);
}
freeSplitString(prelist);
if (!pinfo->vendor) pinfo->vendor = strdup("");
if (!pinfo->description) pinfo->description = strdup("");
if (!pinfo->distribution) pinfo->distribution = strdup("");
pinfo->files = malloc(sizeof(struct rpmFileInfo) * pinfo->fileCount);
j = 8;
for (i = 0; i < pinfo->fileCount; i++) {
rpmfileFromInfoLine(list[j], list[j + 1], list[j + 2],
&pinfo->files[i]);
j += 3;
}
freeSplitString(list);
return 0;
}
void rpmdbFreePackageInfo(struct rpmdbPackageInfo package) {
int i;
free(package.version);
free(package.release);
free(package.name);
free(package.labelstr);
free(package.buildHost);
free(package.vendor);
free(package.description);
free(package.distribution);
free(package.preamble);
for (i = 0; i < package.fileCount; i++) {
rpmfileFree(&package.files[i]);
}
free(package.files);
}
int rpmdbLabelCmp(struct rpmdbLabel * one, struct rpmdbLabel * two) {
int i;
if ((i = strcmp(one->name, two->name)))
return i;
else if ((i = strcmp(one->version, two->version)))
return i;
else
return strcmp(one->release, two->release);
}
void rpmdbSetPrefix(char * new) {
prefix = new;
}

49
rpmio/messages.c Normal file
View File

@ -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;
}
}
}

8
rpmio/rpmerr.c Normal file
View File

@ -0,0 +1,8 @@
#include <stdio.h>
#include "rpmerr.h"
void error(int code, ...)
{
fprintf(stderr, "error, error, error\n");
}