rpm.c
changeset 74 f23a93d41f32
child 75 93278d8ec39c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/rpm.c	Wed Nov 07 00:33:56 2007 -0500
     1.3 @@ -0,0 +1,126 @@
     1.4 +#include <stdio.h>
     1.5 +#include <string.h>
     1.6 +#include <sys/stat.h>
     1.7 +#include <sys/mman.h>
     1.8 +#include <fcntl.h>
     1.9 +#include <unistd.h>
    1.10 +#include <arpa/inet.h>
    1.11 +#include <rpm/rpmlib.h>
    1.12 +
    1.13 +#define	RPM_LEAD_SIZE 96
    1.14 +
    1.15 +struct rpm_lead {
    1.16 +	unsigned char magic[4];
    1.17 +	unsigned char major;
    1.18 +	unsigned char minor;
    1.19 +	short type;
    1.20 +	short archnum;
    1.21 +	char name[66];
    1.22 +	short osnum;
    1.23 +	short signature_type;
    1.24 +	char reserved[16];
    1.25 +};
    1.26 +
    1.27 +struct rpm_header {
    1.28 +	unsigned char magic[4];
    1.29 +	unsigned char reserved[4];
    1.30 +	int nindex;
    1.31 +	int hsize;
    1.32 +};
    1.33 +
    1.34 +struct rpm_header_index {
    1.35 +	int tag;
    1.36 +	int type;
    1.37 +	int offset;
    1.38 +	int count;
    1.39 +};
    1.40 +
    1.41 +#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
    1.42 +
    1.43 +static void dump_header(struct rpm_header *header)
    1.44 +{
    1.45 +	struct rpm_header_index *base, *index;
    1.46 +	int i, j, nindex, tag, offset, type, count;
    1.47 +	char *pool, *name;
    1.48 +
    1.49 +	nindex = ntohl(header->nindex);
    1.50 +	printf("header index records: %d\n", nindex);
    1.51 +	printf("header storage size: %d\n", ntohl(header->hsize));
    1.52 +	base = (struct rpm_header_index *) (header + 1);
    1.53 +	pool = (void *) (header + 1) + nindex * sizeof *index;
    1.54 +
    1.55 +	printf("headers:\n");
    1.56 +	for (i = 0; i < nindex; i++) {
    1.57 +		index = base + i;
    1.58 +		tag = ntohl(index->tag);
    1.59 +		offset = ntohl(index->offset);
    1.60 +		type = ntohl(index->type);
    1.61 +		count = ntohl(index->count);
    1.62 +		printf("  0x%08x 0x%08x 0x%08x 0x%08x\n",
    1.63 +		       tag, type, offset, count);
    1.64 +
    1.65 +		switch (tag) {
    1.66 +		case RPMTAG_NAME:
    1.67 +			name = "name";
    1.68 +			break;
    1.69 +		case RPMTAG_VERSION:
    1.70 +			name = "version";
    1.71 +			break;
    1.72 +		case RPMTAG_RELEASE:
    1.73 +			name = "release";
    1.74 +			break;
    1.75 +		case RPMTAG_REQUIRENAME:
    1.76 +			name = "requires";
    1.77 +			break;
    1.78 +		default:
    1.79 +			name = "unknown";
    1.80 +			break;
    1.81 +		}
    1.82 +
    1.83 +		switch (type) {
    1.84 +		case RPM_STRING_TYPE:
    1.85 +			printf("    (%s %s)\n", name, pool + offset);
    1.86 +			break;
    1.87 +		case RPM_STRING_ARRAY_TYPE:
    1.88 +			printf("    (%s", name);
    1.89 +			for (j = 0; j < count; j++) {
    1.90 +				printf(" %s", pool + offset);
    1.91 +				offset += strlen(pool + offset) + 1;
    1.92 +			}
    1.93 +			printf(")\n");
    1.94 +			break;
    1.95 +		}
    1.96 +	}
    1.97 +}
    1.98 +
    1.99 +void
   1.100 +razor_rpm_dump(const char *filename)
   1.101 +{
   1.102 +	struct stat buf;
   1.103 +	void *p;
   1.104 +	int fd, nindex, hsize;
   1.105 +	struct rpm_header *signature, *header;
   1.106 +	struct rpm_header_index *index;
   1.107 +
   1.108 +	if (stat(filename, &buf) < 0) {
   1.109 +		fprintf(stderr, "no such file %s\n", filename);
   1.110 +		return;
   1.111 +	}
   1.112 +
   1.113 +	fd = open(filename, O_RDONLY);
   1.114 +	p = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   1.115 +	close(fd);
   1.116 +
   1.117 +	printf("%s: %ldkB\n", filename, buf.st_size / 1024);
   1.118 +	signature = p + RPM_LEAD_SIZE;
   1.119 +
   1.120 +	nindex = ntohl(signature->nindex);
   1.121 +	hsize = ntohl(signature->hsize);
   1.122 +	header = (void *) (signature + 1) +
   1.123 +		ALIGN(nindex * sizeof *index + hsize, 8);
   1.124 +
   1.125 +	dump_header(signature);
   1.126 +	dump_header(header);
   1.127 +
   1.128 +	munmap(p, buf.st_size);
   1.129 +}