gunzip: inflate_codes(): add fix from upstream gzip to prevent false CRC error
[oweals/busybox.git] / archival / rpm.c
index e1f3c89305a839c69be717de6880375aa4281bc2..6c1e341cdbfad41c44731a14c2e1030b27973c2c 100644 (file)
@@ -115,8 +115,10 @@ int rpm_main(int argc, char **argv)
                }
        }
        argv += optind;
-       argc -= optind;
-       if (!argc) bb_show_usage();
+       //argc -= optind;
+       if (!argv[0]) {
+               bb_show_usage();
+       }
 
        while (*argv) {
                rpm_fd = xopen(*argv++, O_RDONLY);
@@ -143,13 +145,13 @@ int rpm_main(int argc, char **argv)
                        if (func & rpm_query_info) {
                                /* Do the nice printout */
                                time_t bdate_time;
-                               struct tm *bdate;
+                               struct tm *bdate_ptm;
                                char bdatestring[50];
                                printf("Name        : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_PREFIXS, 0) ? rpm_getstr(TAG_PREFIXS, 0) : "(not relocateable)");
                                printf("Version     : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_VENDOR, 0) ? rpm_getstr(TAG_VENDOR, 0) : "(none)");
                                bdate_time = rpm_getint(TAG_BUILDTIME, 0);
-                               bdate = localtime((time_t *) &bdate_time);
-                               strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate);
+                               bdate_ptm = localtime(&bdate_time);
+                               strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm);
                                printf("Release     : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring);
                                printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0));
                                printf("Group       : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), rpm_getstr(TAG_SOURCERPM, 0));
@@ -190,7 +192,7 @@ static void extract_cpio_gz(int fd)
        archive_handle_t *archive_handle;
        unsigned char magic[2];
 #if BB_MMU
-       USE_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
+       IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
        enum { xformer_prog = 0 };
 #else
        enum { xformer = 0 };
@@ -202,7 +204,12 @@ static void extract_cpio_gz(int fd)
        archive_handle->seek = seek_by_read;
        //archive_handle->action_header = header_list;
        archive_handle->action_data = data_extract_all;
-       archive_handle->ah_flags = ARCHIVE_PRESERVE_DATE | ARCHIVE_CREATE_LEADING_DIRS;
+       archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS
+               /* compat: overwrite existing files.
+                * try "rpm -i foo.src.rpm" few times in a row -
+                * standard rpm will not complain.
+                * (TODO? real rpm creates "file;1234" and then renames it) */
+               | ARCHIVE_UNLINK_OLD;
        archive_handle->src_fd = fd;
        /*archive_handle->offset = 0; - init_handle() did it */
 
@@ -219,7 +226,7 @@ static void extract_cpio_gz(int fd)
                 || magic[0] != 'B' || magic[1] != 'Z'
                ) {
                        bb_error_msg_and_die("no gzip"
-                               USE_FEATURE_SEAMLESS_BZ2("/bzip2")
+                               IF_FEATURE_SEAMLESS_BZ2("/bzip2")
                                " magic");
                }
 #if BB_MMU
@@ -246,7 +253,7 @@ static void extract_cpio_gz(int fd)
 static rpm_index **rpm_gettags(int fd, int *num_tags)
 {
        /* We should never need mode than 200, and realloc later */
-       rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *));
+       rpm_index **tags = xzalloc(200 * sizeof(tags[0]));
        int pass, tagindex = 0;
 
        xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
@@ -260,6 +267,9 @@ static rpm_index **rpm_gettags(int fd, int *num_tags)
                        uint32_t entries; /* Number of entries in header (4 bytes) */
                        uint32_t size; /* Size of store (4 bytes) */
                } header;
+               struct BUG_header {
+                       char BUG_header[sizeof(header) == 16 ? 1 : -1];
+               };
                rpm_index *tmpindex;
                int storepos;
 
@@ -273,8 +283,8 @@ static rpm_index **rpm_gettags(int fd, int *num_tags)
                storepos = xlseek(fd,0,SEEK_CUR) + header.entries * 16;
 
                while (header.entries--) {
-                       tmpindex = tags[tagindex++] = xmalloc(sizeof(rpm_index));
-                       xread(fd, tmpindex, sizeof(rpm_index));
+                       tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex));
+                       xread(fd, tmpindex, sizeof(*tmpindex));
                        tmpindex->tag = ntohl(tmpindex->tag);
                        tmpindex->type = ntohl(tmpindex->type);
                        tmpindex->count = ntohl(tmpindex->count);
@@ -287,7 +297,7 @@ static rpm_index **rpm_gettags(int fd, int *num_tags)
                if (pass == 0)
                        xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR);
        }
-       tags = xrealloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */
+       tags = xrealloc(tags, tagindex * sizeof(tags[0])); /* realloc tags to save space */
        *num_tags = tagindex;
        return tags; /* All done, leave the file at the start of the gzipped cpio archive */
 }
@@ -316,7 +326,7 @@ static char *rpm_getstr(int tag, int itemindex)
                return NULL;
        if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) {
                int n;
-               char *tmpstr = (char *) (map + found[0]->offset);
+               char *tmpstr = (char *) map + found[0]->offset;
                for (n=0; n < itemindex; n++)
                        tmpstr = tmpstr + strlen(tmpstr) + 1;
                return tmpstr;
@@ -335,7 +345,7 @@ static int rpm_getint(int tag, int itemindex)
        if (!found || itemindex >= found[0]->count)
                return -1;
 
-       tmpint = (int *) (map + found[0]->offset);
+       tmpint = (int *) ((char *) map + found[0]->offset);
 
        if (found[0]->type == RPM_INT32_TYPE) {
                tmpint = (int *) ((char *) tmpint + itemindex*4);
@@ -378,9 +388,11 @@ static void fileaction_dobackup(char *filename, int fileref)
 
 static void fileaction_setowngrp(char *filename, int fileref)
 {
-       int uid, gid;
-       uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref));
-       gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref));
+       /* real rpm warns: "user foo does not exist - using <you>" */
+       struct passwd *pw = getpwnam(rpm_getstr(TAG_FILEUSERNAME, fileref));
+       int uid = pw ? pw->pw_uid : getuid(); /* or euid? */
+       struct group *gr = getgrnam(rpm_getstr(TAG_FILEGROUPNAME, fileref));
+       int gid = gr ? gr->gr_gid : getgid();
        chown(filename, uid, gid);
 }