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