rpm.c
changeset 87 c1e04d4e3bc9
parent 86 e44ccd213756
child 88 4c38558a4873
     1.1 --- a/rpm.c	Thu Dec 27 17:45:18 2007 -0500
     1.2 +++ b/rpm.c	Sat Dec 29 15:36:13 2007 -0500
     1.3 @@ -15,18 +15,6 @@
     1.4  
     1.5  #define	RPM_LEAD_SIZE 96
     1.6  
     1.7 -struct rpm_lead {
     1.8 -	unsigned char magic[4];
     1.9 -	unsigned char major;
    1.10 -	unsigned char minor;
    1.11 -	short type;
    1.12 -	short archnum;
    1.13 -	char name[66];
    1.14 -	short osnum;
    1.15 -	short signature_type;
    1.16 -	char reserved[16];
    1.17 -};
    1.18 -
    1.19  struct rpm_header {
    1.20  	unsigned char magic[4];
    1.21  	unsigned char reserved[4];
    1.22 @@ -41,33 +29,10 @@
    1.23  	int count;
    1.24  };
    1.25  
    1.26 -struct properties {
    1.27 -	struct rpm_header_index *name;
    1.28 -	struct rpm_header_index *version;
    1.29 -	struct rpm_header_index *flags;
    1.30 -};
    1.31 -
    1.32  struct razor_rpm {
    1.33  	struct rpm_header *signature;
    1.34  	struct rpm_header *header;
    1.35 -
    1.36 -	struct rpm_header_index *name;
    1.37 -	struct rpm_header_index *version;
    1.38 -	struct rpm_header_index *release;
    1.39 -
    1.40 -	struct rpm_header_index *dirnames;
    1.41 -	struct rpm_header_index *dirindexes;
    1.42 -	struct rpm_header_index *basenames;
    1.43 -	struct rpm_header_index *filesizes;
    1.44 -	struct rpm_header_index *filemodes;
    1.45 -	struct rpm_header_index *fileflags;
    1.46  	const char **dirs;
    1.47 -
    1.48 -	struct properties provides;
    1.49 -	struct properties requires;
    1.50 -	struct properties obsoletes;
    1.51 -	struct properties conflicts;
    1.52 -
    1.53  	const char *pool;
    1.54  	void *map;
    1.55  	size_t size;
    1.56 @@ -76,83 +41,6 @@
    1.57  
    1.58  #define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
    1.59  
    1.60 -static void
    1.61 -import_properties(struct razor_importer *importer,
    1.62 -		  struct properties *properties,
    1.63 -		  const char *pool, unsigned long type)
    1.64 -{
    1.65 -	const char *name, *version;
    1.66 -	int i, count;
    1.67 -
    1.68 -	/* assert: count is the same for all arrays */
    1.69 -
    1.70 -	if (properties->name == NULL)
    1.71 -		return;
    1.72 -
    1.73 -	count = ntohl(properties->name->count);
    1.74 -	name = pool + ntohl(properties->name->offset);
    1.75 -	version = pool + ntohl(properties->version->offset);
    1.76 -	for (i = 0; i < count; i++) {
    1.77 -		razor_importer_add_property(importer, name, version, type);
    1.78 -		name += strlen(name) + 1;
    1.79 -		version += strlen(version) + 1;
    1.80 -	}
    1.81 -}
    1.82 -
    1.83 -static void
    1.84 -import_files(struct razor_importer *importer, struct razor_rpm *rpm)
    1.85 -{
    1.86 -	const char *name;
    1.87 -	unsigned long *index;
    1.88 -	int i, count;
    1.89 -	char buffer[256];
    1.90 -
    1.91 -	/* assert: count is the same for all arrays */
    1.92 -
    1.93 -	if (rpm->dirnames == NULL)
    1.94 -		return;
    1.95 -
    1.96 -	count = ntohl(rpm->basenames->count);
    1.97 -	index = (unsigned long *) (rpm->pool + ntohl(rpm->dirindexes->offset));
    1.98 -	name = rpm->pool + ntohl(rpm->basenames->offset);
    1.99 -	for (i = 0; i < count; i++) {
   1.100 -		snprintf(buffer, sizeof buffer,
   1.101 -			 "%s%s", rpm->dirs[ntohl(*index)], name);
   1.102 -		razor_importer_add_file(importer, buffer);
   1.103 -		name += strlen(name) + 1;
   1.104 -		index++;
   1.105 -	}
   1.106 -}
   1.107 -
   1.108 -#define MAP_ENTRY(field, tag) { offsetof(struct razor_rpm, field), tag }
   1.109 -
   1.110 -static struct index_map {
   1.111 -	unsigned int offset;
   1.112 -	unsigned int tag;
   1.113 -} index_map[] =	{
   1.114 -	MAP_ENTRY(name, RPMTAG_NAME),
   1.115 -	MAP_ENTRY(version, RPMTAG_VERSION),
   1.116 -	MAP_ENTRY(release, RPMTAG_RELEASE),
   1.117 -	MAP_ENTRY(requires.name, RPMTAG_REQUIRENAME),
   1.118 -	MAP_ENTRY(requires.version, RPMTAG_REQUIREVERSION),
   1.119 -	MAP_ENTRY(requires.flags, RPMTAG_REQUIREFLAGS),
   1.120 -	MAP_ENTRY(provides.name, RPMTAG_PROVIDENAME),
   1.121 -	MAP_ENTRY(provides.version, RPMTAG_PROVIDEVERSION),
   1.122 -	MAP_ENTRY(provides.flags, RPMTAG_PROVIDEFLAGS),
   1.123 -	MAP_ENTRY(obsoletes.name, RPMTAG_OBSOLETENAME),
   1.124 -	MAP_ENTRY(obsoletes.version, RPMTAG_OBSOLETEVERSION),
   1.125 -	MAP_ENTRY(obsoletes.flags, RPMTAG_OBSOLETEFLAGS),
   1.126 -	MAP_ENTRY(conflicts.name, RPMTAG_CONFLICTNAME),
   1.127 -	MAP_ENTRY(conflicts.version, RPMTAG_CONFLICTVERSION),
   1.128 -	MAP_ENTRY(conflicts.flags, RPMTAG_CONFLICTFLAGS),
   1.129 -	MAP_ENTRY(dirindexes, RPMTAG_DIRINDEXES),
   1.130 -	MAP_ENTRY(basenames, RPMTAG_BASENAMES),
   1.131 -	MAP_ENTRY(dirnames, RPMTAG_DIRNAMES),
   1.132 -	MAP_ENTRY(filesizes, RPMTAG_FILESIZES),
   1.133 -	MAP_ENTRY(filemodes, RPMTAG_FILEMODES),
   1.134 -	MAP_ENTRY(fileflags, RPMTAG_FILEFLAGS),
   1.135 -};
   1.136 -
   1.137  static struct rpm_header_index *
   1.138  razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
   1.139  {
   1.140 @@ -169,14 +57,74 @@
   1.141  	return NULL;
   1.142  }
   1.143  
   1.144 +static const void *
   1.145 +razor_rpm_get_indirect(struct razor_rpm *rpm,
   1.146 +		       unsigned int tag, unsigned int *count)
   1.147 +{
   1.148 +	struct rpm_header_index *index;
   1.149 +
   1.150 +	index = razor_rpm_get_header(rpm, tag);
   1.151 +	if (index != NULL) {
   1.152 +		if (count)
   1.153 +			*count = ntohl(index->count);
   1.154 +
   1.155 +		return rpm->pool + ntohl(index->offset);
   1.156 +	}
   1.157 +
   1.158 +	return NULL;
   1.159 +}
   1.160 +
   1.161 +static void
   1.162 +import_properties(struct razor_importer *importer, unsigned long type,
   1.163 +		  struct razor_rpm *rpm,
   1.164 +		  int name_tag, int version_tag, int flags_tag)
   1.165 +{
   1.166 +	const char *name, *version;
   1.167 +	unsigned int i, count;
   1.168 +
   1.169 +	name = razor_rpm_get_indirect(rpm, name_tag, &count);
   1.170 +	if (name == NULL)
   1.171 +		return;
   1.172 +
   1.173 +	/* FIXME: Concat version and release. */
   1.174 +	version = razor_rpm_get_indirect(rpm, version_tag, &count);
   1.175 +	for (i = 0; i < count; i++) {
   1.176 +		razor_importer_add_property(importer, name, version, type);
   1.177 +		name += strlen(name) + 1;
   1.178 +		version += strlen(version) + 1;
   1.179 +	}
   1.180 +}
   1.181 +
   1.182 +static void
   1.183 +import_files(struct razor_importer *importer, struct razor_rpm *rpm)
   1.184 +{
   1.185 +	const char *name;
   1.186 +	const unsigned long *index;
   1.187 +	unsigned int i, count;
   1.188 +	char buffer[256];
   1.189 +
   1.190 +	/* assert: count is the same for all arrays */
   1.191 +
   1.192 +	index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
   1.193 +	name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
   1.194 +	for (i = 0; i < count; i++) {
   1.195 +		snprintf(buffer, sizeof buffer,
   1.196 +			 "%s%s", rpm->dirs[ntohl(*index)], name);
   1.197 +		razor_importer_add_file(importer, buffer);
   1.198 +		name += strlen(name) + 1;
   1.199 +		index++;
   1.200 +	}
   1.201 +}
   1.202 +
   1.203  struct razor_rpm *
   1.204  razor_rpm_open(const char *filename)
   1.205  {
   1.206  	struct razor_rpm *rpm;
   1.207  	struct rpm_header_index *base, *index;
   1.208  	struct stat buf;
   1.209 -	int fd, nindex, hsize, i, j, count;
   1.210 +	unsigned int count, i, nindex, hsize;
   1.211  	const char *name;
   1.212 +	int fd;
   1.213  
   1.214  	rpm = malloc(sizeof *rpm);
   1.215  	memset(rpm, 0, sizeof *rpm);
   1.216 @@ -211,26 +159,17 @@
   1.217  	base = (struct rpm_header_index *) (rpm->header + 1);
   1.218  	rpm->pool = (void *) base + nindex * sizeof *index;
   1.219  
   1.220 -	for (i = 0; i < nindex; i++) {
   1.221 -		index = base + i;
   1.222 -		for (j = 0; j < ARRAY_SIZE(index_map); j++) {
   1.223 -			struct rpm_header_index **p;
   1.224 -			if (index_map[j].tag == ntohl(index->tag)) {
   1.225 -				p = (void *) rpm + index_map[j].offset;
   1.226 -				*p = index;
   1.227 -			}
   1.228 -		}				 
   1.229 +	/* Look up dir names now so we can index them directly. */
   1.230 +	name = razor_rpm_get_indirect(rpm, RPMTAG_DIRNAMES, &count);
   1.231 +	if (name == NULL) {
   1.232 +		fprintf(stderr, "old filename style not handled\n");
   1.233 +		return NULL;
   1.234  	}
   1.235  
   1.236 -	/* Look up dir names now so we can index them directly. */
   1.237 -	if (rpm->dirnames != NULL) {
   1.238 -		count = ntohl(rpm->dirnames->count);
   1.239 -		rpm->dirs = calloc(count, sizeof *rpm->dirs);
   1.240 -		name = rpm->pool + ntohl(rpm->dirnames->offset);
   1.241 -		for (i = 0; i < count; i++) {
   1.242 -			rpm->dirs[i] = name;
   1.243 -			name += strlen(name) + 1;
   1.244 -		}
   1.245 +	rpm->dirs = calloc(count, sizeof *rpm->dirs);
   1.246 +	for (i = 0; i < count; i++) {
   1.247 +		rpm->dirs[i] = name;
   1.248 +		name += strlen(name) + 1;
   1.249  	}
   1.250  
   1.251  	return rpm;
   1.252 @@ -412,18 +351,11 @@
   1.253  run_script(struct installer *installer,
   1.254  	   unsigned int program_tag, unsigned int script_tag)
   1.255  {
   1.256 -	struct rpm_header_index *index;
   1.257  	int pid, status, fd[2];
   1.258  	const char *script = NULL, *program = NULL;
   1.259  
   1.260 -	index = razor_rpm_get_header(installer->rpm, program_tag);
   1.261 -	if (index != NULL)
   1.262 -		program = installer->rpm->pool + ntohl(index->offset);
   1.263 -
   1.264 -	index = razor_rpm_get_header(installer->rpm, script_tag);
   1.265 -	if (index != NULL)
   1.266 -		script = installer->rpm->pool + ntohl(index->offset);
   1.267 -
   1.268 +	program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
   1.269 +	script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
   1.270  	if (program == NULL && script == NULL) {
   1.271  		printf("no script or program for tags %d and %d\n",
   1.272  		       program_tag, script_tag);
   1.273 @@ -538,10 +470,10 @@
   1.274  razor_rpm_install(struct razor_rpm *rpm, const char *root)
   1.275  {
   1.276  	struct installer installer;
   1.277 -	int count, i;
   1.278 +	unsigned int count, i, length;
   1.279  	struct cpio_file_header *header;
   1.280 -	unsigned long *size, *index, length, *flags;
   1.281 -	unsigned short *mode;
   1.282 +	const unsigned long *size, *index, *flags;
   1.283 +	const unsigned short *mode;
   1.284  	const char *name, *dir;
   1.285  	struct stat buf;
   1.286  
   1.287 @@ -561,13 +493,12 @@
   1.288  
   1.289  	run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN);
   1.290  
   1.291 -	count = ntohl(rpm->basenames->count);
   1.292 -	size = (unsigned long *) (rpm->pool + ntohl(rpm->filesizes->offset));
   1.293 -	index = (unsigned long *) (rpm->pool + ntohl(rpm->dirindexes->offset));
   1.294 -	mode = (unsigned short *) (rpm->pool + ntohl(rpm->filemodes->offset));
   1.295 -	flags = (unsigned long *) (rpm->pool + ntohl(rpm->fileflags->offset));
   1.296 +	name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
   1.297 +	size = razor_rpm_get_indirect(rpm, RPMTAG_FILESIZES, &count);
   1.298 +	index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
   1.299 +	mode = razor_rpm_get_indirect(rpm, RPMTAG_FILEMODES, &count);
   1.300 +	flags = razor_rpm_get_indirect(rpm, RPMTAG_FILEFLAGS, &count);
   1.301  
   1.302 -	name = rpm->pool + ntohl(rpm->basenames->offset);
   1.303  	for (i = 0; i < count; i++) {
   1.304  		dir = rpm->dirs[ntohl(*index)];
   1.305  
   1.306 @@ -615,18 +546,35 @@
   1.307  int
   1.308  razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm)
   1.309  {
   1.310 -	razor_importer_begin_package(importer,
   1.311 -				     rpm->pool + ntohl(rpm->name->offset),
   1.312 -				     rpm->pool + ntohl(rpm->version->offset));
   1.313 +	const char *name, *version, *release;
   1.314  
   1.315 -	import_properties(importer, &rpm->requires,
   1.316 -			  rpm->pool, RAZOR_PROPERTY_REQUIRES);
   1.317 -	import_properties(importer, &rpm->provides,
   1.318 -			  rpm->pool, RAZOR_PROPERTY_PROVIDES);
   1.319 -	import_properties(importer, &rpm->conflicts,
   1.320 -			  rpm->pool, RAZOR_PROPERTY_CONFLICTS);
   1.321 -	import_properties(importer, &rpm->obsoletes,
   1.322 -			  rpm->pool, RAZOR_PROPERTY_OBSOLETES);
   1.323 +	name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL);
   1.324 +	version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL);
   1.325 +	release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL);
   1.326 +
   1.327 +	/* FIXME: Concatenate version and release. */
   1.328 +	razor_importer_begin_package(importer, name, version);
   1.329 +
   1.330 +	import_properties(importer, RAZOR_PROPERTY_REQUIRES, rpm,
   1.331 +			  RPMTAG_REQUIRENAME,
   1.332 +			  RPMTAG_REQUIREVERSION,
   1.333 +			  RPMTAG_REQUIREFLAGS);
   1.334 +
   1.335 +	import_properties(importer, RAZOR_PROPERTY_PROVIDES, rpm,
   1.336 +			  RPMTAG_PROVIDENAME,
   1.337 +			  RPMTAG_PROVIDEVERSION,
   1.338 +			  RPMTAG_PROVIDEFLAGS);
   1.339 +
   1.340 +	import_properties(importer, RAZOR_PROPERTY_OBSOLETES, rpm,
   1.341 +			  RPMTAG_OBSOLETENAME,
   1.342 +			  RPMTAG_OBSOLETEVERSION,
   1.343 +			  RPMTAG_OBSOLETEFLAGS);
   1.344 +
   1.345 +	import_properties(importer, RAZOR_PROPERTY_CONFLICTS, rpm,
   1.346 +			  RPMTAG_CONFLICTNAME,
   1.347 +			  RPMTAG_CONFLICTVERSION,
   1.348 +			  RPMTAG_CONFLICTFLAGS);
   1.349 +
   1.350  	import_files(importer, rpm);
   1.351  
   1.352  	razor_importer_finish_package(importer);