rpm.c
author Kristian H?gsberg <krh@redhat.com>
Wed Nov 07 00:33:56 2007 -0500 (2007-11-07)
changeset 74 f23a93d41f32
child 75 93278d8ec39c
permissions -rw-r--r--
Add the first bits of rpm file parser.
krh@74
     1
#include <stdio.h>
krh@74
     2
#include <string.h>
krh@74
     3
#include <sys/stat.h>
krh@74
     4
#include <sys/mman.h>
krh@74
     5
#include <fcntl.h>
krh@74
     6
#include <unistd.h>
krh@74
     7
#include <arpa/inet.h>
krh@74
     8
#include <rpm/rpmlib.h>
krh@74
     9
krh@74
    10
#define	RPM_LEAD_SIZE 96
krh@74
    11
krh@74
    12
struct rpm_lead {
krh@74
    13
	unsigned char magic[4];
krh@74
    14
	unsigned char major;
krh@74
    15
	unsigned char minor;
krh@74
    16
	short type;
krh@74
    17
	short archnum;
krh@74
    18
	char name[66];
krh@74
    19
	short osnum;
krh@74
    20
	short signature_type;
krh@74
    21
	char reserved[16];
krh@74
    22
};
krh@74
    23
krh@74
    24
struct rpm_header {
krh@74
    25
	unsigned char magic[4];
krh@74
    26
	unsigned char reserved[4];
krh@74
    27
	int nindex;
krh@74
    28
	int hsize;
krh@74
    29
};
krh@74
    30
krh@74
    31
struct rpm_header_index {
krh@74
    32
	int tag;
krh@74
    33
	int type;
krh@74
    34
	int offset;
krh@74
    35
	int count;
krh@74
    36
};
krh@74
    37
krh@74
    38
#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
krh@74
    39
krh@74
    40
static void dump_header(struct rpm_header *header)
krh@74
    41
{
krh@74
    42
	struct rpm_header_index *base, *index;
krh@74
    43
	int i, j, nindex, tag, offset, type, count;
krh@74
    44
	char *pool, *name;
krh@74
    45
krh@74
    46
	nindex = ntohl(header->nindex);
krh@74
    47
	printf("header index records: %d\n", nindex);
krh@74
    48
	printf("header storage size: %d\n", ntohl(header->hsize));
krh@74
    49
	base = (struct rpm_header_index *) (header + 1);
krh@74
    50
	pool = (void *) (header + 1) + nindex * sizeof *index;
krh@74
    51
krh@74
    52
	printf("headers:\n");
krh@74
    53
	for (i = 0; i < nindex; i++) {
krh@74
    54
		index = base + i;
krh@74
    55
		tag = ntohl(index->tag);
krh@74
    56
		offset = ntohl(index->offset);
krh@74
    57
		type = ntohl(index->type);
krh@74
    58
		count = ntohl(index->count);
krh@74
    59
		printf("  0x%08x 0x%08x 0x%08x 0x%08x\n",
krh@74
    60
		       tag, type, offset, count);
krh@74
    61
krh@74
    62
		switch (tag) {
krh@74
    63
		case RPMTAG_NAME:
krh@74
    64
			name = "name";
krh@74
    65
			break;
krh@74
    66
		case RPMTAG_VERSION:
krh@74
    67
			name = "version";
krh@74
    68
			break;
krh@74
    69
		case RPMTAG_RELEASE:
krh@74
    70
			name = "release";
krh@74
    71
			break;
krh@74
    72
		case RPMTAG_REQUIRENAME:
krh@74
    73
			name = "requires";
krh@74
    74
			break;
krh@74
    75
		default:
krh@74
    76
			name = "unknown";
krh@74
    77
			break;
krh@74
    78
		}
krh@74
    79
krh@74
    80
		switch (type) {
krh@74
    81
		case RPM_STRING_TYPE:
krh@74
    82
			printf("    (%s %s)\n", name, pool + offset);
krh@74
    83
			break;
krh@74
    84
		case RPM_STRING_ARRAY_TYPE:
krh@74
    85
			printf("    (%s", name);
krh@74
    86
			for (j = 0; j < count; j++) {
krh@74
    87
				printf(" %s", pool + offset);
krh@74
    88
				offset += strlen(pool + offset) + 1;
krh@74
    89
			}
krh@74
    90
			printf(")\n");
krh@74
    91
			break;
krh@74
    92
		}
krh@74
    93
	}
krh@74
    94
}
krh@74
    95
krh@74
    96
void
krh@74
    97
razor_rpm_dump(const char *filename)
krh@74
    98
{
krh@74
    99
	struct stat buf;
krh@74
   100
	void *p;
krh@74
   101
	int fd, nindex, hsize;
krh@74
   102
	struct rpm_header *signature, *header;
krh@74
   103
	struct rpm_header_index *index;
krh@74
   104
krh@74
   105
	if (stat(filename, &buf) < 0) {
krh@74
   106
		fprintf(stderr, "no such file %s\n", filename);
krh@74
   107
		return;
krh@74
   108
	}
krh@74
   109
krh@74
   110
	fd = open(filename, O_RDONLY);
krh@74
   111
	p = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
krh@74
   112
	close(fd);
krh@74
   113
krh@74
   114
	printf("%s: %ldkB\n", filename, buf.st_size / 1024);
krh@74
   115
	signature = p + RPM_LEAD_SIZE;
krh@74
   116
krh@74
   117
	nindex = ntohl(signature->nindex);
krh@74
   118
	hsize = ntohl(signature->hsize);
krh@74
   119
	header = (void *) (signature + 1) +
krh@74
   120
		ALIGN(nindex * sizeof *index + hsize, 8);
krh@74
   121
krh@74
   122
	dump_header(signature);
krh@74
   123
	dump_header(header);
krh@74
   124
krh@74
   125
	munmap(p, buf.st_size);
krh@74
   126
}