Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/archival/rpm.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/archival/rpm.c
r1765 r2725 5 5 * Copyright (C) 2001,2002 by Laurence Anderson 6 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 10 10 #include "libbb.h" 11 #include " unarchive.h"12 13 #define RPM_HEADER_MAGIC "\216\255\350" 11 #include "archive.h" 12 #include "rpm.h" 13 14 14 #define RPM_CHAR_TYPE 1 15 15 #define RPM_INT8_TYPE 2 … … 47 47 #define TAG_BASENAMES 1117 48 48 #define TAG_DIRNAMES 1118 49 49 50 #define RPMFILE_CONFIG (1 << 0) 50 51 #define RPMFILE_DOC (1 << 1) … … 71 72 static int tagcount; 72 73 73 static void extract_cpio _gz(int fd);74 static void extract_cpio(int fd, const char *source_rpm); 74 75 static rpm_index **rpm_gettags(int fd, int *num_tags); 75 76 static int bsearch_rpmtag(const void *key, const void *item); … … 81 82 static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref)); 82 83 83 int rpm_main(int argc, char **argv) ;84 int rpm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 84 85 int rpm_main(int argc, char **argv) 85 86 { … … 116 117 } 117 118 argv += optind; 118 argc -= optind; 119 if (!argc) bb_show_usage(); 119 //argc -= optind; 120 if (!argv[0]) { 121 bb_show_usage(); 122 } 120 123 121 124 while (*argv) { 125 const char *source_rpm; 126 122 127 rpm_fd = xopen(*argv++, O_RDONLY); 123 128 mytags = rpm_gettags(rpm_fd, &tagcount); … … 128 133 map = mmap(0, offset > pagesize ? (offset + offset % pagesize) : pagesize, PROT_READ, MAP_PRIVATE, rpm_fd, 0); 129 134 135 source_rpm = rpm_getstr(TAG_SOURCERPM, 0); 136 130 137 if (func & rpm_install) { 131 138 /* Backup any config files */ 132 139 loop_through_files(TAG_BASENAMES, fileaction_dobackup); 133 140 /* Extact the archive */ 134 extract_cpio _gz(rpm_fd);141 extract_cpio(rpm_fd, source_rpm); 135 142 /* Set the correct file uid/gid's */ 136 143 loop_through_files(TAG_BASENAMES, fileaction_setowngrp); … … 144 151 /* Do the nice printout */ 145 152 time_t bdate_time; 146 struct tm *bdate ;153 struct tm *bdate_ptm; 147 154 char bdatestring[50]; 148 printf("Name : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_PREFIXS, 0) ? rpm_getstr(TAG_PREFIXS, 0) : "(not relocateable)"); 149 printf("Version : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_VENDOR, 0) ? rpm_getstr(TAG_VENDOR, 0) : "(none)"); 155 const char *p; 156 157 p = rpm_getstr(TAG_PREFIXS, 0); 158 if (!p) p = "(not relocateable)"; 159 printf("Name : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), p); 160 p = rpm_getstr(TAG_VENDOR, 0); 161 if (!p) p = "(none)"; 162 printf("Version : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), p); 150 163 bdate_time = rpm_getint(TAG_BUILDTIME, 0); 151 bdate = localtime((time_t *)&bdate_time);152 strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate );164 bdate_ptm = localtime(&bdate_time); 165 strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm); 153 166 printf("Release : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring); 154 167 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0)); 155 printf("Group : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), rpm_getstr(TAG_SOURCERPM, 0));168 printf("Group : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), source_rpm); 156 169 printf("Size : %-33dLicense: %s\n", rpm_getint(TAG_SIZE, 0), rpm_getstr(TAG_LICENSE, 0)); 157 170 printf("URL : %s\n", rpm_getstr(TAG_URL, 0)); … … 186 199 } 187 200 188 static void extract_cpio _gz(int fd)201 static void extract_cpio(int fd, const char *source_rpm) 189 202 { 190 203 archive_handle_t *archive_handle; 191 unsigned char magic[2]; 192 #if BB_MMU 193 USE_DESKTOP(long long) int (*xformer)(int src_fd, int dst_fd); 194 enum { xformer_prog = 0 }; 195 #else 196 enum { xformer = 0 }; 197 const char *xformer_prog; 198 #endif 204 205 if (source_rpm != NULL) { 206 /* Binary rpm (it was built from some SRPM), install to root */ 207 xchdir("/"); 208 } /* else: SRPM, install to current dir */ 199 209 200 210 /* Initialize */ 201 211 archive_handle = init_handle(); 202 212 archive_handle->seek = seek_by_read; 203 //archive_handle->action_header = header_list;204 213 archive_handle->action_data = data_extract_all; 205 archive_handle->flags |= ARCHIVE_PRESERVE_DATE; 206 archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; 214 #if 0 /* For testing (rpm -i only lists the files in internal cpio): */ 215 archive_handle->action_header = header_list; 216 archive_handle->action_data = data_skip; 217 #endif 218 archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS 219 /* compat: overwrite existing files. 220 * try "rpm -i foo.src.rpm" few times in a row - 221 * standard rpm will not complain. 222 * (TODO? real rpm creates "file;1234" and then renames it) */ 223 | ARCHIVE_UNLINK_OLD; 207 224 archive_handle->src_fd = fd; 208 archive_handle->offset = 0; 209 210 xread(archive_handle->src_fd, &magic, 2); 211 #if BB_MMU 212 xformer = unpack_gz_stream; 213 #else 214 xformer_prog = "gunzip"; 215 #endif 216 if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { 217 if (ENABLE_FEATURE_RPM_BZ2 218 && (magic[0] == 0x42) && (magic[1] == 0x5a)) { 219 #if BB_MMU 220 xformer = unpack_bz2_stream; 221 #else 222 xformer_prog = "bunzip2"; 223 #endif 224 /* We can do better, need modifying unpack_bz2_stream to not require 225 * first 2 bytes. Not very hard to do... I mean, TODO :) */ 226 xlseek(archive_handle->src_fd, -2, SEEK_CUR); 227 } else 228 bb_error_msg_and_die("no gzip" 229 USE_FEATURE_RPM_BZ2("/bzip") 230 " magic"); 231 } else { 232 check_header_gzip_or_die(archive_handle->src_fd); 233 #if !BB_MMU 234 /* NOMMU version of open_transformer execs an external unzipper that should 235 * have the file position at the start of the file */ 236 xlseek(archive_handle->src_fd, 0, SEEK_SET); 237 #endif 238 } 239 240 xchdir("/"); /* Install RPM's to root */ 241 archive_handle->src_fd = open_transformer(archive_handle->src_fd, xformer, xformer_prog, xformer_prog, "-cf", "-", NULL); 242 archive_handle->offset = 0; 225 /*archive_handle->offset = 0; - init_handle() did it */ 226 227 setup_unzip_on_fd(archive_handle->src_fd /*, fail_if_not_detected: 1*/); 243 228 while (get_header_cpio(archive_handle) == EXIT_SUCCESS) 244 229 continue; 245 230 } 246 231 247 248 232 static rpm_index **rpm_gettags(int fd, int *num_tags) 249 233 { 250 /* We should never need mo de than 200, and realloc later*/251 rpm_index **tags = xzalloc(200 * sizeof( struct rpmtag *));234 /* We should never need more than 200 (shrink via realloc later) */ 235 rpm_index **tags = xzalloc(200 * sizeof(tags[0])); 252 236 int pass, tagindex = 0; 253 237 … … 256 240 /* 1st pass is the signature headers, 2nd is the main stuff */ 257 241 for (pass = 0; pass < 2; pass++) { 258 struct { 259 char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */ 260 uint8_t version; /* 1 byte version number */ 261 uint32_t reserved; /* 4 bytes reserved */ 262 uint32_t entries; /* Number of entries in header (4 bytes) */ 263 uint32_t size; /* Size of store (4 bytes) */ 264 } header; 242 struct rpm_header header; 265 243 rpm_index *tmpindex; 266 244 int storepos; 267 245 268 246 xread(fd, &header, sizeof(header)); 269 if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) 270 return NULL; /* Invalid magic */ 271 if (header.version != 1) 272 return NULL; /* This program only supports v1 headers */ 247 if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) 248 return NULL; /* Invalid magic, or not version 1 */ 273 249 header.size = ntohl(header.size); 274 250 header.entries = ntohl(header.entries); 275 storepos = xlseek(fd, 0,SEEK_CUR) + header.entries * 16;251 storepos = xlseek(fd, 0, SEEK_CUR) + header.entries * 16; 276 252 277 253 while (header.entries--) { 278 tmpindex = tags[tagindex++] = xmalloc(sizeof( rpm_index));279 xread(fd, tmpindex, sizeof( rpm_index));254 tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex)); 255 xread(fd, tmpindex, sizeof(*tmpindex)); 280 256 tmpindex->tag = ntohl(tmpindex->tag); 281 257 tmpindex->type = ntohl(tmpindex->type); 282 258 tmpindex->count = ntohl(tmpindex->count); 283 259 tmpindex->offset = storepos + ntohl(tmpindex->offset); 284 if (pass ==0)260 if (pass == 0) 285 261 tmpindex->tag -= 743; 286 262 } 287 xlseek(fd, header.size, SEEK_CUR); /* Seek past store */263 storepos = xlseek(fd, header.size, SEEK_CUR); /* Seek past store */ 288 264 /* Skip padding to 8 byte boundary after reading signature headers */ 289 if (pass==0) 290 xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); 291 } 292 tags = xrealloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */ 265 if (pass == 0) 266 xlseek(fd, (-storepos) & 0x7, SEEK_CUR); 267 } 268 /* realloc tags to save space */ 269 tags = xrealloc(tags, tagindex * sizeof(tags[0])); 293 270 *num_tags = tagindex; 294 return tags; /* All done, leave the file at the start of the gzipped cpio archive */ 271 /* All done, leave the file at the start of the gzipped cpio archive */ 272 return tags; 295 273 } 296 274 … … 317 295 if (!found || itemindex >= found[0]->count) 318 296 return NULL; 319 if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) { 297 if (found[0]->type == RPM_STRING_TYPE 298 || found[0]->type == RPM_I18NSTRING_TYPE 299 || found[0]->type == RPM_STRING_ARRAY_TYPE 300 ) { 320 301 int n; 321 char *tmpstr = (char *) (map + found[0]->offset);322 for (n =0; n < itemindex; n++)302 char *tmpstr = (char *) map + found[0]->offset; 303 for (n = 0; n < itemindex; n++) 323 304 tmpstr = tmpstr + strlen(tmpstr) + 1; 324 305 return tmpstr; … … 338 319 return -1; 339 320 340 tmpint = (int *) ( map + found[0]->offset);321 tmpint = (int *) ((char *) map + found[0]->offset); 341 322 342 323 if (found[0]->type == RPM_INT32_TYPE) { … … 381 362 static void fileaction_setowngrp(char *filename, int fileref) 382 363 { 383 int uid, gid; 384 uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref)); 385 gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref)); 364 /* real rpm warns: "user foo does not exist - using <you>" */ 365 struct passwd *pw = getpwnam(rpm_getstr(TAG_FILEUSERNAME, fileref)); 366 int uid = pw ? pw->pw_uid : getuid(); /* or euid? */ 367 struct group *gr = getgrnam(rpm_getstr(TAG_FILEGROUPNAME, fileref)); 368 int gid = gr ? gr->gr_gid : getgid(); 386 369 chown(filename, uid, gid); 387 370 }
Note:
See TracChangeset
for help on using the changeset viewer.