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 +}