Drop table based section lookup and look up sections on demand.
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);