diff -r 000000000000 -r f23a93d41f32 rpm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rpm.c Wed Nov 07 00:33:56 2007 -0500 @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define RPM_LEAD_SIZE 96 + +struct rpm_lead { + unsigned char magic[4]; + unsigned char major; + unsigned char minor; + short type; + short archnum; + char name[66]; + short osnum; + short signature_type; + char reserved[16]; +}; + +struct rpm_header { + unsigned char magic[4]; + unsigned char reserved[4]; + int nindex; + int hsize; +}; + +struct rpm_header_index { + int tag; + int type; + int offset; + int count; +}; + +#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1)) + +static void dump_header(struct rpm_header *header) +{ + struct rpm_header_index *base, *index; + int i, j, nindex, tag, offset, type, count; + char *pool, *name; + + nindex = ntohl(header->nindex); + printf("header index records: %d\n", nindex); + printf("header storage size: %d\n", ntohl(header->hsize)); + base = (struct rpm_header_index *) (header + 1); + pool = (void *) (header + 1) + nindex * sizeof *index; + + printf("headers:\n"); + for (i = 0; i < nindex; i++) { + index = base + i; + tag = ntohl(index->tag); + offset = ntohl(index->offset); + type = ntohl(index->type); + count = ntohl(index->count); + printf(" 0x%08x 0x%08x 0x%08x 0x%08x\n", + tag, type, offset, count); + + switch (tag) { + case RPMTAG_NAME: + name = "name"; + break; + case RPMTAG_VERSION: + name = "version"; + break; + case RPMTAG_RELEASE: + name = "release"; + break; + case RPMTAG_REQUIRENAME: + name = "requires"; + break; + default: + name = "unknown"; + break; + } + + switch (type) { + case RPM_STRING_TYPE: + printf(" (%s %s)\n", name, pool + offset); + break; + case RPM_STRING_ARRAY_TYPE: + printf(" (%s", name); + for (j = 0; j < count; j++) { + printf(" %s", pool + offset); + offset += strlen(pool + offset) + 1; + } + printf(")\n"); + break; + } + } +} + +void +razor_rpm_dump(const char *filename) +{ + struct stat buf; + void *p; + int fd, nindex, hsize; + struct rpm_header *signature, *header; + struct rpm_header_index *index; + + if (stat(filename, &buf) < 0) { + fprintf(stderr, "no such file %s\n", filename); + return; + } + + fd = open(filename, O_RDONLY); + p = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + + printf("%s: %ldkB\n", filename, buf.st_size / 1024); + signature = p + RPM_LEAD_SIZE; + + nindex = ntohl(signature->nindex); + hsize = ntohl(signature->hsize); + header = (void *) (signature + 1) + + ALIGN(nindex * sizeof *index + hsize, 8); + + dump_header(signature); + dump_header(header); + + munmap(p, buf.st_size); +}