Add the first bits of rpm file parser.
authorKristian H?gsberg <krh@redhat.com>
Wed Nov 07 00:33:56 2007 -0500 (2007-11-07)
changeset 74f23a93d41f32
parent 73 0ff316e24339
child 75 93278d8ec39c
Add the first bits of rpm file parser.
Makefile
TODO
main.c
razor.h
rpm.c
     1.1 --- a/Makefile	Mon Nov 05 22:54:33 2007 -0500
     1.2 +++ b/Makefile	Wed Nov 07 00:33:56 2007 -0500
     1.3 @@ -1,7 +1,7 @@
     1.4  CFLAGS = -Wall -g -O2
     1.5  LDLIBS = -lexpat -lz -g -lrpm -lcurl
     1.6  
     1.7 -razor : razor.o import.o sha1.o main.o
     1.8 +razor : razor.o import.o sha1.o main.o rpm.o
     1.9  
    1.10  clean :
    1.11  	rm -f *.o razor
     2.1 --- a/TODO	Mon Nov 05 22:54:33 2007 -0500
     2.2 +++ b/TODO	Wed Nov 07 00:33:56 2007 -0500
     2.3 @@ -21,6 +21,11 @@
     2.4  
     2.5  - pre-link changing binaries and libs on disk screwing up checksum?
     2.6  
     2.7 +- nail down byte-order and word sizes of repo file.
     2.8 +
     2.9 +- version the sections in the file, put the element size in the header
    2.10 +  so we can add stuff to elements in a backwards compatible way.
    2.11 +
    2.12  Misc ideas:
    2.13  
    2.14  - eliminate duplicate entries in package property lists.
    2.15 @@ -72,9 +77,6 @@
    2.16  
    2.17    idiom for iteration of directories.
    2.18  
    2.19 -- version the sections in the file, put the element size in the header
    2.20 -  so we can add stuff to elements in a backwards compatible way.
    2.21 -
    2.22  - overlay package sets?  mount a read-only /usr over nfs or from the
    2.23    virt-host and have a local package set overlaid over the read-only
    2.24    one.  shouldn't need new features in the core package set data
    2.25 @@ -89,3 +91,6 @@
    2.26  
    2.27  - incremental rawhide repo updates? instead of downloading 10MB zipped
    2.28    repo every time, download a diff repo?
    2.29 +
    2.30 +- use hash tables for dirs when importing files to avoid qsorting all
    2.31 +  files in rawhide.
     3.1 --- a/main.c	Mon Nov 05 22:54:33 2007 -0500
     3.2 +++ b/main.c	Wed Nov 07 00:33:56 2007 -0500
     3.3 @@ -291,6 +291,14 @@
     3.4  	return 0;
     3.5  }
     3.6  
     3.7 +static int
     3.8 +command_dump_rpm(int argc, const char *argv[])
     3.9 +{
    3.10 +	razor_rpm_dump(argv[0]);
    3.11 +
    3.12 +	return 0;
    3.13 +}
    3.14 +
    3.15  static struct {
    3.16  	const char *name;
    3.17  	const char *description;
    3.18 @@ -310,7 +318,8 @@
    3.19  	{ "import-rpmdb", "import the system rpm database", command_import_rpmdb },
    3.20  	{ "validate", "validate a package set", command_validate },
    3.21  	{ "update", "update all or specified packages", command_update },
    3.22 -	{ "diff", "show diff between two package sets", command_diff }
    3.23 +	{ "diff", "show diff between two package sets", command_diff },
    3.24 +	{ "dump", "dump rpm file contents", command_dump_rpm }
    3.25  };
    3.26  
    3.27  static int
     4.1 --- a/razor.h	Mon Nov 05 22:54:33 2007 -0500
     4.2 +++ b/razor.h	Wed Nov 07 00:33:56 2007 -0500
     4.3 @@ -61,4 +61,8 @@
     4.4  struct razor_set *razor_set_create_from_yum(void);
     4.5  struct razor_set *razor_set_create_from_rpmdb(void);
     4.6  
     4.7 +/* RPM functions */
     4.8 +void
     4.9 +razor_rpm_dump(const char *filename);
    4.10 +
    4.11  #endif /* _RAZOR_H_ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/rpm.c	Wed Nov 07 00:33:56 2007 -0500
     5.3 @@ -0,0 +1,126 @@
     5.4 +#include <stdio.h>
     5.5 +#include <string.h>
     5.6 +#include <sys/stat.h>
     5.7 +#include <sys/mman.h>
     5.8 +#include <fcntl.h>
     5.9 +#include <unistd.h>
    5.10 +#include <arpa/inet.h>
    5.11 +#include <rpm/rpmlib.h>
    5.12 +
    5.13 +#define	RPM_LEAD_SIZE 96
    5.14 +
    5.15 +struct rpm_lead {
    5.16 +	unsigned char magic[4];
    5.17 +	unsigned char major;
    5.18 +	unsigned char minor;
    5.19 +	short type;
    5.20 +	short archnum;
    5.21 +	char name[66];
    5.22 +	short osnum;
    5.23 +	short signature_type;
    5.24 +	char reserved[16];
    5.25 +};
    5.26 +
    5.27 +struct rpm_header {
    5.28 +	unsigned char magic[4];
    5.29 +	unsigned char reserved[4];
    5.30 +	int nindex;
    5.31 +	int hsize;
    5.32 +};
    5.33 +
    5.34 +struct rpm_header_index {
    5.35 +	int tag;
    5.36 +	int type;
    5.37 +	int offset;
    5.38 +	int count;
    5.39 +};
    5.40 +
    5.41 +#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
    5.42 +
    5.43 +static void dump_header(struct rpm_header *header)
    5.44 +{
    5.45 +	struct rpm_header_index *base, *index;
    5.46 +	int i, j, nindex, tag, offset, type, count;
    5.47 +	char *pool, *name;
    5.48 +
    5.49 +	nindex = ntohl(header->nindex);
    5.50 +	printf("header index records: %d\n", nindex);
    5.51 +	printf("header storage size: %d\n", ntohl(header->hsize));
    5.52 +	base = (struct rpm_header_index *) (header + 1);
    5.53 +	pool = (void *) (header + 1) + nindex * sizeof *index;
    5.54 +
    5.55 +	printf("headers:\n");
    5.56 +	for (i = 0; i < nindex; i++) {
    5.57 +		index = base + i;
    5.58 +		tag = ntohl(index->tag);
    5.59 +		offset = ntohl(index->offset);
    5.60 +		type = ntohl(index->type);
    5.61 +		count = ntohl(index->count);
    5.62 +		printf("  0x%08x 0x%08x 0x%08x 0x%08x\n",
    5.63 +		       tag, type, offset, count);
    5.64 +
    5.65 +		switch (tag) {
    5.66 +		case RPMTAG_NAME:
    5.67 +			name = "name";
    5.68 +			break;
    5.69 +		case RPMTAG_VERSION:
    5.70 +			name = "version";
    5.71 +			break;
    5.72 +		case RPMTAG_RELEASE:
    5.73 +			name = "release";
    5.74 +			break;
    5.75 +		case RPMTAG_REQUIRENAME:
    5.76 +			name = "requires";
    5.77 +			break;
    5.78 +		default:
    5.79 +			name = "unknown";
    5.80 +			break;
    5.81 +		}
    5.82 +
    5.83 +		switch (type) {
    5.84 +		case RPM_STRING_TYPE:
    5.85 +			printf("    (%s %s)\n", name, pool + offset);
    5.86 +			break;
    5.87 +		case RPM_STRING_ARRAY_TYPE:
    5.88 +			printf("    (%s", name);
    5.89 +			for (j = 0; j < count; j++) {
    5.90 +				printf(" %s", pool + offset);
    5.91 +				offset += strlen(pool + offset) + 1;
    5.92 +			}
    5.93 +			printf(")\n");
    5.94 +			break;
    5.95 +		}
    5.96 +	}
    5.97 +}
    5.98 +
    5.99 +void
   5.100 +razor_rpm_dump(const char *filename)
   5.101 +{
   5.102 +	struct stat buf;
   5.103 +	void *p;
   5.104 +	int fd, nindex, hsize;
   5.105 +	struct rpm_header *signature, *header;
   5.106 +	struct rpm_header_index *index;
   5.107 +
   5.108 +	if (stat(filename, &buf) < 0) {
   5.109 +		fprintf(stderr, "no such file %s\n", filename);
   5.110 +		return;
   5.111 +	}
   5.112 +
   5.113 +	fd = open(filename, O_RDONLY);
   5.114 +	p = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   5.115 +	close(fd);
   5.116 +
   5.117 +	printf("%s: %ldkB\n", filename, buf.st_size / 1024);
   5.118 +	signature = p + RPM_LEAD_SIZE;
   5.119 +
   5.120 +	nindex = ntohl(signature->nindex);
   5.121 +	hsize = ntohl(signature->hsize);
   5.122 +	header = (void *) (signature + 1) +
   5.123 +		ALIGN(nindex * sizeof *index + hsize, 8);
   5.124 +
   5.125 +	dump_header(signature);
   5.126 +	dump_header(header);
   5.127 +
   5.128 +	munmap(p, buf.st_size);
   5.129 +}