void xa_open_rpm (XArchive *archive) { unsigned short int i; int response; GSList *list = NULL; FILE *stream; gboolean result; signal (SIGPIPE, SIG_IGN); stream = fopen ( archive->path , "r" ); if (stream == NULL) { gchar *msg = g_strdup_printf (_("Can't open RPM file %s:") , archive->path); response = xa_show_message_dialog (GTK_WINDOW (xa_main_window) , GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK, msg,g_strerror(errno)); g_free (msg); return; } archive->can_extract = archive->has_properties = TRUE; archive->can_add = archive->has_sfx = archive->has_test = FALSE; archive->dummy_size = 0; archive->nr_of_files = 0; archive->nc = 8; archive->format ="RPM"; char *names[]= {(_("Points to")),(_("Size")),(_("Permission")),(_("Date")),(_("Hard Link")),(_("Owner")),(_("Group")),NULL}; GType types[]= {GDK_TYPE_PIXBUF,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_UINT64,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_POINTER}; archive->column_types = g_malloc0(sizeof(types)); for (i = 0; i < 10; i++) archive->column_types[i] = types[i]; xa_create_liststore (archive,names); /* Create a unique temp dir in /tmp */ result = xa_create_temp_directory (archive); if (!result) return; /* Now I run dd to have the bzip2 / gzip compressed cpio archive in /tmp */ gchar *command = g_strconcat ( "sh -c \"rpm2cpio ",archive->escaped_path," > ",archive->tmp, "/file.cpio\"",NULL); list = NULL; list = g_slist_append(list,command); result = xa_run_command (archive,list); if (result == FALSE) { gtk_widget_set_sensitive(Stop_button,FALSE); xa_set_button_state (1,1,1,1,archive->can_add,archive->can_extract,0,archive->has_test,archive->has_properties,archive->has_passwd,0); gtk_label_set_text(GTK_LABEL(total_label),""); return; } /* And finally cpio to receive the content */ command = g_strconcat ("sh -c \"cpio -tv < ",archive->tmp,"/file.cpio\"",NULL); archive->parse_output = xa_get_cpio_line_content; xa_spawn_async_process (archive,command); g_free(command); }
static int xa_rpm2cpio (XArchive *archive) { unsigned char bytes[HDRSIG_ENTRY_INFO_LEN]; int datalen, entries; long offset; gchar *cpio_z, *ibs, *command, *executable; GSList *list; FILE *stream; signal(SIGPIPE, SIG_IGN); stream = fopen(archive->path, "r"); if (stream == NULL) { gchar *msg = g_strdup_printf(_("Can't open RPM file %s:"), archive->path); xa_show_message_dialog(GTK_WINDOW(xa_main_window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg, g_strerror(errno)); g_free(msg); return -1; } /* Signature section */ if (fseek(stream, SIGNATURE_START, SEEK_CUR) == -1) { fclose (stream); xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't fseek to position 104:"),g_strerror(errno)); return -1; } if (fread(bytes, 1, HDRSIG_ENTRY_INFO_LEN, stream) != HDRSIG_ENTRY_INFO_LEN) { fclose ( stream ); xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't read data from file:"),g_strerror(errno)); return -1; } entries = 256 * (256 * (256 * bytes[0] + bytes[1]) + bytes[2]) + bytes[3]; datalen = 256 * (256 * (256 * bytes[4] + bytes[5]) + bytes[6]) + bytes[7]; datalen += (16 - (datalen % 16)) % 16; // header section is aligned offset = HDRSIG_ENTRY_INDEX_LEN * entries + datalen; /* Header section */ if (fseek(stream, offset, SEEK_CUR)) { fclose (stream); xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't fseek in file:"),g_strerror(errno)); return -1; } if (fread(bytes, 1, HDRSIG_ENTRY_INFO_LEN, stream) != HDRSIG_ENTRY_INFO_LEN) { fclose ( stream ); xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't read data from file:"),g_strerror(errno)); return -1; } entries = 256 * (256 * (256 * bytes[0] + bytes[1]) + bytes[2]) + bytes[3]; datalen = 256 * (256 * (256 * bytes[4] + bytes[5]) + bytes[6]) + bytes[7]; offset = HDRSIG_ENTRY_INDEX_LEN * entries + datalen; offset += ftell(stream); // offset from top fclose(stream); /* create a unique temp dir in /tmp */ if (!xa_create_temp_directory(archive)) return -1; cpio_z = g_strconcat(archive->tmp, "/xa-tmp.cpio_z", NULL); ibs = g_strdup_printf("%lu", offset); /* run dd to have the payload (compressed cpio archive) in /tmp */ command = g_strconcat("dd if=", archive->escaped_path, " ibs=", ibs, " skip=1 of=", cpio_z, NULL); list = g_slist_append(NULL, command); g_free(ibs); if (!xa_run_command(archive, list)) { g_free(cpio_z); return -1; } switch (xa_detect_archive_type(cpio_z)) { case XARCHIVETYPE_GZIP: executable = "gzip -dc "; break; case XARCHIVETYPE_BZIP2: executable = "bzip2 -dc "; break; default: executable = "xz -dc "; break; } command = g_strconcat("sh -c \"", executable, cpio_z, " > ", archive->tmp, "/xa-tmp.cpio\"", NULL); list = g_slist_append(NULL, command); g_free(cpio_z); if (!xa_run_command(archive, list)) return 0; return 1; }