Initial revision
CVS patchset: 1 CVS date: 1995/11/27 22:31:21
This commit is contained in:
commit
7153c16096
|
@ -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)
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
/* This converts an old style (rpm 1.x) database to the new style */
|
||||
|
||||
#include <oldrpmdb.h>
|
||||
|
||||
int convertDB(char * dbprefix) {
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef H_MISC
|
||||
#define H_MISC
|
||||
|
||||
char ** splitString(char * str, int length, char sep);
|
||||
void freeSplitString(char ** list);
|
||||
|
||||
#endif
|
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef H_RPM_MALLOC
|
||||
#define H_RPM_MALLOC
|
||||
|
||||
#ifndef __linux__
|
||||
#error malloc definition needed for non Linux OS
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "rpmerr.h"
|
||||
|
||||
void error(int code, ...)
|
||||
{
|
||||
fprintf(stderr, "error, error, error\n");
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "rpmerr.h"
|
||||
|
||||
void error(int code, ...)
|
||||
{
|
||||
fprintf(stderr, "error, error, error\n");
|
||||
}
|
Loading…
Reference in New Issue