diff -Naur xarchiver-0.5.3.orig/src/rpm.c xarchiver-0.5.3/src/rpm.c --- xarchiver-0.5.3.orig/src/rpm.c 2014-02-09 16:26:24.000000000 +0100 +++ xarchiver-0.5.3/src/rpm.c 2014-02-19 07:54:27.744136749 +0100 @@ -23,8 +23,11 @@ void xa_open_rpm (XArchive *archive) { + unsigned char bytes[8]; unsigned short int i; - int response; + int dl,il,sigsize,offset,response; + gchar *ibs,*executable; + gchar *gzip_tmp = NULL; GSList *list = NULL; FILE *stream; gboolean result; @@ -53,14 +56,68 @@ archive->column_types[i] = types[i]; xa_create_liststore (archive,names); + if (fseek ( stream, 104 , SEEK_CUR ) ) + { + fclose (stream); + response = 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; + } + if ( fread ( bytes, 1, 8, stream ) == 0 ) + { + fclose ( stream ); + response = 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; + } + il = 256 * ( 256 * ( 256 * bytes[0] + bytes[1]) + bytes[2] ) + bytes[3]; + dl = 256 * ( 256 * ( 256 * bytes[4] + bytes[5]) + bytes[6] ) + bytes[7]; + sigsize = 8 + 16 * il + dl; + offset = 104 + sigsize + ( 8 - ( sigsize % 8 ) ) % 8 + 8; + if (fseek ( stream, offset , SEEK_SET ) ) + { + fclose (stream); + response = 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; + } + if ( fread ( bytes, 1, 8, stream ) == 0 ) + { + fclose ( stream ); + response = 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; + } + il = 256 * ( 256 * ( 256 * bytes[0] + bytes[1]) + bytes[2] ) + bytes[3]; + dl = 256 * ( 256 * ( 256 * bytes[4] + bytes[5]) + bytes[6] ) + bytes[7]; + sigsize = 8 + 16 * il + dl; + offset = offset + sigsize; + fclose (stream); /* Create a unique temp dir in /tmp */ result = xa_create_temp_directory (archive); if (!result) return; + gzip_tmp = g_strconcat (archive->tmp,"/file.gz_bz",NULL); + ibs = g_strdup_printf ( "%u" , offset ); + /* 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); + gchar *command = g_strconcat ( "dd if=",archive->escaped_path," ibs=",ibs," skip=1 of=",gzip_tmp,NULL); + g_free (ibs); + list = g_slist_append(list,command); + batch_mode = TRUE; + result = xa_run_command (archive,list); + if (result == FALSE) + { + g_free (gzip_tmp); + return; + } + if (xa_detect_archive_type (gzip_tmp) == XARCHIVETYPE_GZIP) + executable = "gzip -dc "; + else if (xa_detect_archive_type (gzip_tmp) == XARCHIVETYPE_BZIP2) + executable = "bzip2 -dc "; + else + executable = "xz -dc "; + + command = g_strconcat("sh -c \"",executable,gzip_tmp," > ",archive->tmp,"/file.cpio\"",NULL); + g_free(gzip_tmp); list = NULL; list = g_slist_append(list,command); result = xa_run_command (archive,list);