diff --git a/GNUmakefile.template b/GNUmakefile.template index d826f79..f052966 100644 --- a/GNUmakefile.template +++ b/GNUmakefile.template @@ -114,6 +114,7 @@ src/inlined-icons.h: icons/read.png icons/create.png icons/scan.png icons/fix.pn @gdk-pixbuf-csource --raw --name=dvdisaster_scan icons/scan.png >>src/inlined-icons.h @gdk-pixbuf-csource --raw --name=dvdisaster_fix icons/fix.png >>src/inlined-icons.h @gdk-pixbuf-csource --raw --name=dvdisaster_verify icons/verify.png >>src/inlined-icons.h + @gdk-pixbuf-csource --raw --name=dvdisaster_strip icons/strip.png >>src/inlined-icons.h @gdk-pixbuf-csource --raw --name=dvdisaster_open_ecc icons/open-ecc.png >>src/inlined-icons.h @gdk-pixbuf-csource --raw --name=dvdisaster_open_img icons/open-img.png >>src/inlined-icons.h @gdk-pixbuf-csource --raw --name=dvdisaster_cd icons/cd.png >>src/inlined-icons.h diff --git a/icons/strip.png b/icons/strip.png new file mode 100644 index 0000000..f0f7b30 Binary files /dev/null and b/icons/strip.png differ diff --git a/regtest/common.bash b/regtest/common.bash index 2c0bd41..867c7a4 100644 --- a/regtest/common.bash +++ b/regtest/common.bash @@ -260,10 +260,11 @@ function run_regtest() if test "$answer" == "a"; then cp $REFLOG $LOGDIR head -n 2 $LOGDIR/${CODEC_PREFIX}_${testsymbol} >$REFLOG - sed -e "s=${SED_REMOVE_ISO_DIR}==g" $NEWLOG >>$REFLOG + sed -re "s=${SED_REMOVE_ISO_DIR}==g" $NEWLOG >>$REFLOG pass="skip" elif test "$answer" == "v"; then vimdiff $REFLOG $NEWLOG + continue else pass="false" @@ -295,7 +296,7 @@ function run_regtest() image_md5=$(head -n 1 $REFLOG) ecc_md5=$(head -n 2 $REFLOG | tail -n 1) - if test ${image_md5} != "ignore"; then + if test "${image_md5}" != "ignore"; then md5=$($MD5SUM ${testiso} | cut -d\ -f 1) if test "$image_md5" != "$md5"; then if [ "$REGTEST_NO_UTF8" = 1 ]; then @@ -309,7 +310,7 @@ function run_regtest() fi fi - if test ${ecc_md5} != "ignore"; then + if test "${ecc_md5}" != "ignore"; then md5=$($MD5SUM ${testecc} | cut -d\ -f 1) if test "$ecc_md5" != "$md5"; then if [ "$pass" = false ] || [ "$REGTEST_NO_UTF8" = 1 ]; then @@ -340,7 +341,7 @@ function run_regtest() [ $nbfailed -ge 256 ] && nbfailed=255 echo "test symbol for config: $testsymbol" if test "$fail_on_bad" == "yes"; then - next=$(grep -A 1 ${CODEC_PREFIX}_$testsymbol config.txt | tail -n 1 | cut -d\ -f 1) + next=$(grep -A 1 "${CODEC_PREFIX}_$testsymbol" config.txt | tail -n 1 | cut -d\ -f 1) echo "FAIL_ON_BAD set to yes -- exiting" if test "$gui_mode" == "true"; then guiarg="gui" diff --git a/regtest/config.txt b/regtest/config.txt index bdc4b58..8042f58 100644 --- a/regtest/config.txt +++ b/regtest/config.txt @@ -170,6 +170,11 @@ RS01_adaptive_medium_with_dsm yes ### RS02 tests +# Strip tests + +RS02_strip_ecc yes +RS02_strip_ecc_not yes + # Verify tests RS02_good yes RS02_good_quick yes @@ -335,6 +340,11 @@ RS02_adaptive_with_wrong_rs03_file yes ### RS03 augmented image tests +# Strip tests + +RS03i_strip_ecc yes +RS03i_strip_ecc_not yes + # Verify tests RS03i_good yes diff --git a/regtest/rs01.bash b/regtest/rs01.bash index ab82d42..68b1fcc 100755 --- a/regtest/rs01.bash +++ b/regtest/rs01.bash @@ -440,15 +440,16 @@ fi # Read image with wrong ecc file and create new (other) ecc in the same program call. # Tests whether CRC and ECC information is taken from the read process, # not the wrong ecc file. +# FIXME expected output not in database, disabling for now: -if try "read image with wrong ecc (RS01) and create new ecc" ecc_recreate_after_read_wrong_rs01; then +if false && try "read image with wrong ecc (RS01) and create new ecc" ecc_recreate_after_read_wrong_rs01; then cp $MASTERISO $SIMISO $NEWVER --debug -i$TMPISO --random-image $((ISOSIZE-777)) --random-seed 1337 >>$LOGFILE 2>&1 $NEWVER --regtest --debug --set-version $SETVERSION -i$TMPISO -e$TMPECC -c -n 8 >>$LOGFILE 2>&1 extra_args="--debug --set-version $SETVERSION --sim-cd=$SIMISO --fixed-speed-values" - #run_regtest ecc_recreate_after_read_wrong_rs01 "-r -c $REDUNDANCY --spinup-delay=0 -v" $TMPISO $TMPECC + run_regtest ecc_recreate_after_read_wrong_rs01 "-r -c $REDUNDANCY --spinup-delay=0 -v" $TMPISO $TMPECC fi REGTEST_SECTION="Fixing tests" diff --git a/regtest/rs02.bash b/regtest/rs02.bash index fb07d79..270077d 100755 --- a/regtest/rs02.bash +++ b/regtest/rs02.bash @@ -39,6 +39,27 @@ if ! file_exists $ISO_PLUS137; then FILE_MSG="" fi +### Strip tests + +REGTEST_SECTION="Strip tests" + +# Strip ECC from an augmented image + +if try "strip ECC from augmented image" strip_ecc; then + cp $MASTERISO $TMPISO + + run_regtest strip_ecc "-v --strip" $TMPISO +fi + +# Strip ECC from a non-augmented image + +if try "strip ECC from a non-augmented image" strip_ecc_not; then + cp $MASTERISO $TMPISO + $NEWVER -i$TMPISO --strip >>$LOGFILE 2>&1 + + run_regtest strip_ecc_not "-v --strip" $TMPISO +fi + ### Verification tests REGTEST_SECTION="Verify tests" diff --git a/regtest/rs03i.bash b/regtest/rs03i.bash index 8fecfea..563dbfa 100755 --- a/regtest/rs03i.bash +++ b/regtest/rs03i.bash @@ -36,6 +36,27 @@ if ! file_exists $LARGEMASTERISO; then FILE_MSG="" fi +### Strip tests + +REGTEST_SECTION="Strip tests" + +# Strip ECC from an augmented image + +if try "strip ECC from augmented image" strip_ecc; then + cp $MASTERISO $TMPISO + + run_regtest strip_ecc "-v --strip" $TMPISO +fi + +# Strip ECC from a non-augmented image + +if try "strip ECC from a non-augmented image" strip_ecc_not; then + cp $MASTERISO $TMPISO + $NEWVER -i$TMPISO --strip >>$LOGFILE 2>&1 + + run_regtest strip_ecc_not "-v --strip" $TMPISO +fi + ### Verification tests REGTEST_SECTION="Verify tests" diff --git a/src/dvdisaster.c b/src/dvdisaster.c index 5cf8513..73c75d1 100644 --- a/src/dvdisaster.c +++ b/src/dvdisaster.c @@ -67,6 +67,7 @@ typedef enum MODE_SHOW_SECTOR, MODE_TRUNCATE, MODE_ZERO_UNREADABLE, + MODE_STRIP_ECC, /* don't use the ascii range 32-127 so that we avoid collision with the single-char options */ @@ -280,6 +281,7 @@ int main(int argc, char *argv[]) {"sim-defects", 1, 0, MODIFIER_SIMULATE_DEFECTS}, {"speed-warning", 2, 0, MODIFIER_SPEED_WARNING}, {"spinup-delay", 1, 0, MODIFIER_SPINUP_DELAY}, + {"strip", 0, 0, 'z'}, {"test", 2, 0, 't'}, {"threads", 1, 0, 'x'}, {"truncate", 2, 0, MODIFIER_TRUNCATE}, @@ -291,7 +293,7 @@ int main(int argc, char *argv[]) }; c = getopt_long(argc, argv, - "a:cd:e:fhi:j:lm::n:o:p:r::s::t::uvx:", + "a:cd:e:fhi:j:lm::n:o:p:r::s::t::uvx:z", long_options, &option_index); if(c == -1) break; @@ -395,6 +397,9 @@ int main(int argc, char *argv[]) if(Closure->codecThreads < 1 || Closure->codecThreads > MAX_CODEC_THREADS) Stop(_("--threads must be 1..%d\n"), MAX_CODEC_THREADS); break; + case 'z': + mode = MODE_STRIP_ECC; + break; case 0 : break; /* flag argument */ @@ -918,6 +923,10 @@ int main(int argc, char *argv[]) TruncateImageFile(debug_arg); break; + case MODE_STRIP_ECC: + StripECCFromImageFile(); + break; + case MODE_ZERO_UNREADABLE: ZeroUnreadable(); break; @@ -945,6 +954,7 @@ int main(int argc, char *argv[]) " dvdisaster -f,--fix # Try to fix medium image using .ecc information.\n" " dvdisaster -s,--scan # Scan the medium for read errors.\n" " dvdisaster -t,--test # Test integrity of the .iso and .ecc files.\n" + " dvdisaster -z,--strip # Strip ECC data from an augmented .iso.\n" " dvdisaster -u,--unlink # Delete .iso files (when other actions complete)\n\n")); PrintCLI(_("Drive and file specification:\n" diff --git a/src/dvdisaster.h b/src/dvdisaster.h index 61922d9..7ab4c8f 100644 --- a/src/dvdisaster.h +++ b/src/dvdisaster.h @@ -354,6 +354,7 @@ typedef struct _GlobalClosure GtkWidget *scanButton; GtkWidget *fixButton; GtkWidget *testButton; + GtkWidget *stripButton; /*** The preferences window */ @@ -1012,7 +1013,8 @@ typedef enum ACTION_VERIFY, /* VERIFY, CREATE and FIX have separate windows assigned */ ACTION_CREATE, /* for each method. */ ACTION_CREATE_CONT, - ACTION_FIX + ACTION_FIX, + ACTION_STRIP /* --- does not have a window */ } MajorActions; void CreateMainWindow(int*, char***); @@ -1200,6 +1202,7 @@ void LockLabelSize(GtkLabel*, char*, ...) PRINTF_FORMAT(2); int ConfirmImageDeletion(char *); int ConfirmEccDeletion(char *); +void StripECCFromImageFile(void); #ifndef WITH_CLI_ONLY_YES /*** diff --git a/src/icon-factory.c b/src/icon-factory.c index 9f99bfd..bf1337d 100644 --- a/src/icon-factory.c +++ b/src/icon-factory.c @@ -72,6 +72,7 @@ void CreateIconFactory() create_icon(ifact, "dvdisaster-scan", dvdisaster_scan); create_icon(ifact, "dvdisaster-fix", dvdisaster_fix); create_icon(ifact, "dvdisaster-verify", dvdisaster_verify); + create_icon(ifact, "dvdisaster-strip", dvdisaster_strip); /*** Stock GTK icons to defeat theming */ diff --git a/src/main-window.c b/src/main-window.c index 0055c09..11cc935 100644 --- a/src/main-window.c +++ b/src/main-window.c @@ -189,6 +189,11 @@ static void action_cb(GtkWidget *widget, gpointer data) CreateGThread((GThreadFunc)ReadMediumLinear, (gpointer)1); break; + case ACTION_STRIP: + AllowActions(FALSE); + CreateGThread((GThreadFunc)StripECCFromImageFile, (gpointer)0); + break; + case ACTION_VERIFY: /* If something is wrong with the .iso or .ecc files we fall back to the RS01 method for verifying since it is robust @@ -315,6 +320,13 @@ static GtkWidget* create_action_bar(GtkNotebook *notebook) gtk_box_pack_start(GTK_BOX(vbox), wid, FALSE, FALSE, 0); AttachTooltip(wid, _("tooltip|Consistency check"), _("Tests consistency of error correction data and image file.")); + /*** Strip */ + + Closure->stripButton = wid = create_button(_("button|Strip"), "dvdisaster-strip"); + g_signal_connect(G_OBJECT(wid), "clicked", G_CALLBACK(action_cb), (gpointer)ACTION_STRIP); + gtk_box_pack_start(GTK_BOX(vbox), wid, FALSE, FALSE, 0); + AttachTooltip(wid, _("tooltip|Strip ECC"), _("Strip ECC data from an augmented image.")); + /*** Stop */ wid = create_button(_("button|Stop"), "dvdisaster-gtk-stop"); diff --git a/src/misc.c b/src/misc.c index fd16c30..a4dbc55 100644 --- a/src/misc.c +++ b/src/misc.c @@ -822,6 +822,7 @@ static gboolean allow_actions_idle_func(gpointer data) gtk_widget_set_sensitive(Closure->createButton, s); gtk_widget_set_sensitive(Closure->fixButton, s); gtk_widget_set_sensitive(Closure->testButton, s); + gtk_widget_set_sensitive(Closure->stripButton, s); gtk_widget_set_sensitive(Closure->prefsButton, s); if(!s && Closure->prefsWindow) @@ -1358,3 +1359,78 @@ int ConfirmEccDeletion(char *file) #endif } +/* + * --strip method and associated cleanup func + */ + +static void stripecc_cleanup(gpointer data) +{ + Image *image = (Image*)data; + + UnregisterCleanup(); + + if (image) + CloseImage(image); + +#ifndef WITH_CLI_ONLY_YES + if(Closure->guiMode) + { AllowActions(TRUE); + g_thread_exit(0); + } +#endif +} + + +void StripECCFromImageFile() +{ Image *image = NULL; + gint64 end; + + RegisterCleanup(_("Strip ECC aborted"), stripecc_cleanup, (gpointer)image); + + /*** Open the image file */ + image = OpenImageFromFile(Closure->imageName, O_RDWR, IMG_PERMS); + if(!image) + Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno)); + + if (!image->eccHeader) + Stop(_("Image is not augmented (no dvdisaster signature found).")); + + PrintLog("Image is augmented (expected sectors = %" PRId64 ")\n", image->expectedSectors); + + end = uchar_to_gint64(image->eccHeader->sectors); + if (end <= 0) + Stop(_("Invalid end data sector (%" PRId64 "), aborting"), end); + + PrintLog(_("Truncating image to %" PRId64 " sectors.\n"), end); + + /*** Last chance to cancel in GUI mode */ + +#ifndef WITH_CLI_ONLY_YES + if(Closure->guiMode) + { int answer = ModalDialog(GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, NULL, + _("We're about to truncate the image from %" PRId64 " sectors (%" PRId64 " MiB)\n" + "to %" PRId64 " sectors (%" PRId64 " MiB), removing any dvdisaster-added ECC data.\n" + "This will restore the image to its pre-augmented original size."), + image->expectedSectors, image->expectedSectors >> 9, end, end >> 9); + /* >> 9 is 2048 bytes (1 sector) to MiB */ + + if (answer != 1) + Stop(_("Aborted on user request")); + } +#endif + + /*** Truncate it. */ + + if(!LargeTruncate(image->file, (gint64)(2048*end))) + Stop(_("Could not truncate %s: %s\n"),Closure->imageName,strerror(errno)); + + PrintLog(_("Image successfully truncated back to its original size.\n")); + +#ifndef WITH_CLI_ONLY_YES + ModalDialog(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, NULL, _("Image successfully truncated")); +#endif + + /*** Clean up */ + + stripecc_cleanup((gpointer)image); +}