diff --git a/e2fsck/e2fsck.8.in b/e2fsck/e2fsck.8.in index f5ed7582..3367f4fa 100644 --- a/e2fsck/e2fsck.8.in +++ b/e2fsck/e2fsck.8.in @@ -68,6 +68,19 @@ are not valid if the filesystem is mounted. If asks whether or not you should check a filesystem which is mounted, the only correct answer is ``no''. Only experts who really know what they are doing should consider answering this question in any other way. +.PP +If +.B e2fsck +is run in interactive mode (meaning that none of +.BR \-y , +.BR \-n , +or +.BR \-p +are specified), the program will ask the user to fix each problem found in the +filesystem. A response of 'y' will fix the error; 'n' will leave the error +unfixed; and 'a' will fix the problem and all subsequent problems; pressing +Enter will proceed with the default response, which is printed before the +question mark. Pressing Control-C terminates e2fsck immediately. .SH OPTIONS .TP .B \-a diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 96551a13..e6291367 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -760,7 +760,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); - if (isatty(0) && isatty(1)) { + if (getenv("E2FSCK_FORCE_INTERACTIVE") || (isatty(0) && isatty(1))) { ctx->interactive = 1; } else { ctx->start_meta[0] = '\001'; diff --git a/e2fsck/util.c b/e2fsck/util.c index 2de45f85..e2fb982f 100644 --- a/e2fsck/util.c +++ b/e2fsck/util.c @@ -189,6 +189,10 @@ int ask_yn(e2fsck_t ctx, const char * string, int def) const char *defstr; const char *short_yes = _("yY"); const char *short_no = _("nN"); + const char *short_yesall = _("aA"); + const char *yesall_prompt = _(" ('a' enables 'yes' to all) "); + const char *extra_prompt = ""; + static int yes_answers; #ifdef HAVE_TERMIOS_H struct termios termios, tmp; @@ -207,7 +211,16 @@ int ask_yn(e2fsck_t ctx, const char * string, int def) defstr = _(_("")); else defstr = _(" (y/n)"); - log_out(ctx, "%s%s? ", string, defstr); + /* + * If the user presses 'y' more than 8 (but less than 12) times in + * succession without pressing anything else, display a hint about + * yes-to-all mode. + */ + if (yes_answers > 12) + yes_answers = -1; + else if (yes_answers > 8) + extra_prompt = yesall_prompt; + log_out(ctx, "%s%s%s? ", string, extra_prompt, defstr); while (1) { fflush (stdout); if ((c = read_a_char()) == EOF) @@ -221,20 +234,31 @@ int ask_yn(e2fsck_t ctx, const char * string, int def) longjmp(e2fsck_global_ctx->abort_loc, 1); } log_out(ctx, "%s", _("cancelled!\n")); + yes_answers = 0; return 0; } if (strchr(short_yes, (char) c)) { def = 1; + if (yes_answers >= 0) + yes_answers++; break; - } - else if (strchr(short_no, (char) c)) { + } else if (strchr(short_no, (char) c)) { def = 0; + yes_answers = -1; + break; + } else if (strchr(short_yesall, (char)c)) { + def = 2; + yes_answers = -1; + ctx->options |= E2F_OPT_YES; + break; + } else if ((c == 27 || c == ' ' || c == '\n') && (def != -1)) { + yes_answers = -1; break; } - else if ((c == 27 || c == ' ' || c == '\n') && (def != -1)) - break; } - if (def) + if (def == 2) + log_out(ctx, "%s", _("yes to all\n")); + else if (def) log_out(ctx, "%s", _("yes\n")); else log_out(ctx, "%s", _("no\n")); diff --git a/tests/f_no/expect b/tests/f_no/expect new file mode 100644 index 00000000..e7b619d5 --- /dev/null +++ b/tests/f_no/expect @@ -0,0 +1,48 @@ +Pass 1: Checking inodes, blocks, and sizes +Inode 12 has an invalid extent + (logical block 0, invalid physical block 999999999, len 1) +Clear? no +Inode 12 has an invalid extent + (logical block 1, invalid physical block 9999999999, len 1) +Clear? no +Inode 13 is in use, but has dtime set. Fix? no +Inode 13 has an invalid extent + (logical block 1, invalid physical block 8888888888888, len 1) +Clear? no +Inode 13 has an invalid extent + (logical block 0, invalid physical block 888888888888, len 1) +Clear? no +Inode 14 is in use, but has dtime set. Fix? no +Inode 14 has an invalid extent + (logical block 300, invalid physical block 777777777777, len 300) +Clear? no +Inode 14 has an invalid extent + (logical block 0, invalid physical block 7777777777, len 1) +Clear? no +Inode 14, i_blocks is 52574694748113, should be 0. Fix? no +Pass 2: Checking directory structure +Extended attribute block for inode 12 (/a) is invalid (999999). +Clear? no +Extended attribute block for inode 13 (/b) is invalid (298954296). +Clear? no +Extended attribute block for inode 14 (/c) is invalid (388697201). +Clear? no +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Inode 12 ref count is 34463, should be 1. Fix? no +Inode 13 ref count is 9999, should be 1. Fix? no +Inode 14 ref count is 12241, should be 1. Fix? no +Pass 5: Checking group summary information +Block bitmap differences: -202 -381 -457 +Fix? no +Free blocks count wrong for group #0 (0, counted=491). +Fix? no +Free blocks count wrong (494, counted=491). +Fix? no +Free inodes count wrong for group #0 (4294967293, counted=114). +Fix? no + +test_filesys: ********** WARNING: Filesystem still has errors ********** + +test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks +Exit status is 4 diff --git a/tests/f_no/script b/tests/f_no/script new file mode 100644 index 00000000..2a67e77a --- /dev/null +++ b/tests/f_no/script @@ -0,0 +1,27 @@ +test_description="e2fsck with repeated no" +FSCK_OPT=-f +OUT=$test_name.log +EXP=$test_dir/expect + +gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE + +rm -rf $OUT +echo "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1 +status=$? +echo Exit status is $status >> $OUT.new +sed -f $cmd_dir/filter.sed $OUT.new >> $OUT +rm -f $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed + rm -f tmp_expect +fi + +unset IMAGE FSCK_OPT OUT EXP diff --git a/tests/f_yes/expect b/tests/f_yes/expect new file mode 100644 index 00000000..c73e6204 --- /dev/null +++ b/tests/f_yes/expect @@ -0,0 +1,45 @@ +Pass 1: Checking inodes, blocks, and sizes +Inode 12 has an invalid extent + (logical block 0, invalid physical block 999999999, len 1) +Clear? yes +Inode 12 has an invalid extent + (logical block 1, invalid physical block 9999999999, len 1) +Clear? yes +Inode 13 is in use, but has dtime set. Fix? yes +Inode 13 has an invalid extent + (logical block 1, invalid physical block 8888888888888, len 1) +Clear? yes +Inode 13 has an invalid extent + (logical block 0, invalid physical block 888888888888, len 1) +Clear? yes +Inode 14 is in use, but has dtime set. Fix? yes +Inode 14 has an invalid extent + (logical block 300, invalid physical block 777777777777, len 300) +Clear? yes +Inode 14 has an invalid extent + (logical block 0, invalid physical block 7777777777, len 1) +Clear? yes +Inode 14, i_blocks is 52574694748113, should be 0. Fix? yes +Pass 2: Checking directory structure +Extended attribute block for inode 12 (/a) is invalid (999999). +Clear ('a' enables 'yes' to all) ? yes +Extended attribute block for inode 13 (/b) is invalid (298954296). +Clear ('a' enables 'yes' to all) ? yes +Extended attribute block for inode 14 (/c) is invalid (388697201). +Clear ('a' enables 'yes' to all) ? yes +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Inode 12 ref count is 34463, should be 1. Fix ('a' enables 'yes' to all) ? yes +Inode 13 ref count is 9999, should be 1. Fix? yes +Inode 14 ref count is 12241, should be 1. Fix? yes +Pass 5: Checking group summary information +Block bitmap differences: -202 -381 -457 +Fix? yes +Free blocks count wrong for group #0 (0, counted=494). +Fix? yes +Free inodes count wrong for group #0 (4294967293, counted=114). +Fix? yes + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks +Exit status is 1 diff --git a/tests/f_yes/script b/tests/f_yes/script new file mode 100644 index 00000000..4e114c50 --- /dev/null +++ b/tests/f_yes/script @@ -0,0 +1,27 @@ +test_description="e2fsck with repeated yes" +FSCK_OPT=-f +OUT=$test_name.log +EXP=$test_dir/expect + +gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE + +rm -rf $OUT +echo "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1 +status=$? +echo Exit status is $status >> $OUT.new +sed -f $cmd_dir/filter.sed $OUT.new >> $OUT +rm -f $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed + rm -f tmp_expect +fi + +unset IMAGE FSCK_OPT OUT EXP diff --git a/tests/f_yesall/expect b/tests/f_yesall/expect new file mode 100644 index 00000000..f6d3c2b8 --- /dev/null +++ b/tests/f_yesall/expect @@ -0,0 +1,62 @@ +Pass 1: Checking inodes, blocks, and sizes +Inode 12 has an invalid extent + (logical block 0, invalid physical block 999999999, len 1) +Clear? yes to all +Inode 12 has an invalid extent + (logical block 1, invalid physical block 9999999999, len 1) +Clear? yes + +Inode 13 is in use, but has dtime set. Fix? yes + +Inode 13 has an invalid extent + (logical block 1, invalid physical block 8888888888888, len 1) +Clear? yes + +Inode 13 has an invalid extent + (logical block 0, invalid physical block 888888888888, len 1) +Clear? yes + +Inode 14 is in use, but has dtime set. Fix? yes + +Inode 14 has an invalid extent + (logical block 300, invalid physical block 777777777777, len 300) +Clear? yes + +Inode 14 has an invalid extent + (logical block 0, invalid physical block 7777777777, len 1) +Clear? yes + +Inode 14, i_blocks is 52574694748113, should be 0. Fix? yes + +Pass 2: Checking directory structure +Extended attribute block for inode 12 (/a) is invalid (999999). +Clear? yes + +Extended attribute block for inode 13 (/b) is invalid (298954296). +Clear? yes + +Extended attribute block for inode 14 (/c) is invalid (388697201). +Clear? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Inode 12 ref count is 34463, should be 1. Fix? yes + +Inode 13 ref count is 9999, should be 1. Fix? yes + +Inode 14 ref count is 12241, should be 1. Fix? yes + +Pass 5: Checking group summary information +Block bitmap differences: -202 -381 -457 +Fix? yes + +Free blocks count wrong for group #0 (0, counted=494). +Fix? yes + +Free inodes count wrong for group #0 (4294967293, counted=114). +Fix? yes + + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks +Exit status is 1 diff --git a/tests/f_yesall/image.gz b/tests/f_yesall/image.gz new file mode 100644 index 00000000..0f8b205d Binary files /dev/null and b/tests/f_yesall/image.gz differ diff --git a/tests/f_yesall/script b/tests/f_yesall/script new file mode 100644 index 00000000..c3721ffd --- /dev/null +++ b/tests/f_yesall/script @@ -0,0 +1,27 @@ +test_description="e2fsck with yes-to-all" +FSCK_OPT=-f +OUT=$test_name.log +EXP=$test_dir/expect + +gunzip < $test_dir/image.gz > $TMPFILE + +rm -rf $OUT +echo "annnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1 +status=$? +echo Exit status is $status >> $OUT.new +sed -f $cmd_dir/filter.sed $OUT.new >> $OUT +rm -f $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed + rm -f tmp_expect +fi + +unset IMAGE FSCK_OPT OUT EXP diff --git a/tests/f_yesthenall/expect b/tests/f_yesthenall/expect new file mode 100644 index 00000000..1fc3bde6 --- /dev/null +++ b/tests/f_yesthenall/expect @@ -0,0 +1,52 @@ +Pass 1: Checking inodes, blocks, and sizes +Inode 12 has an invalid extent + (logical block 0, invalid physical block 999999999, len 1) +Clear? yes +Inode 12 has an invalid extent + (logical block 1, invalid physical block 9999999999, len 1) +Clear? yes +Inode 13 is in use, but has dtime set. Fix? yes +Inode 13 has an invalid extent + (logical block 1, invalid physical block 8888888888888, len 1) +Clear? yes +Inode 13 has an invalid extent + (logical block 0, invalid physical block 888888888888, len 1) +Clear? yes +Inode 14 is in use, but has dtime set. Fix? yes +Inode 14 has an invalid extent + (logical block 300, invalid physical block 777777777777, len 300) +Clear? yes +Inode 14 has an invalid extent + (logical block 0, invalid physical block 7777777777, len 1) +Clear? yes +Inode 14, i_blocks is 52574694748113, should be 0. Fix? yes +Pass 2: Checking directory structure +Extended attribute block for inode 12 (/a) is invalid (999999). +Clear ('a' enables 'yes' to all) ? yes +Extended attribute block for inode 13 (/b) is invalid (298954296). +Clear ('a' enables 'yes' to all) ? yes to all +Extended attribute block for inode 14 (/c) is invalid (388697201). +Clear? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Inode 12 ref count is 34463, should be 1. Fix? yes + +Inode 13 ref count is 9999, should be 1. Fix? yes + +Inode 14 ref count is 12241, should be 1. Fix? yes + +Pass 5: Checking group summary information +Block bitmap differences: -202 -381 -457 +Fix? yes + +Free blocks count wrong for group #0 (0, counted=494). +Fix? yes + +Free inodes count wrong for group #0 (4294967293, counted=114). +Fix? yes + + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks +Exit status is 1 diff --git a/tests/f_yesthenall/script b/tests/f_yesthenall/script new file mode 100644 index 00000000..eb11c231 --- /dev/null +++ b/tests/f_yesthenall/script @@ -0,0 +1,27 @@ +test_description="e2fsck with yes then yes-to-all" +FSCK_OPT=-f +OUT=$test_name.log +EXP=$test_dir/expect + +gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE + +rm -rf $OUT +echo "yyyyyyyyyyannnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1 +status=$? +echo Exit status is $status >> $OUT.new +sed -f $cmd_dir/filter.sed $OUT.new >> $OUT +rm -f $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed + rm -f tmp_expect +fi + +unset IMAGE FSCK_OPT OUT EXP diff --git a/tests/f_yesthenno/expect b/tests/f_yesthenno/expect new file mode 100644 index 00000000..de55f47d --- /dev/null +++ b/tests/f_yesthenno/expect @@ -0,0 +1,50 @@ +Pass 1: Checking inodes, blocks, and sizes +Inode 12 has an invalid extent + (logical block 0, invalid physical block 999999999, len 1) +Clear? yes +Inode 12 has an invalid extent + (logical block 1, invalid physical block 9999999999, len 1) +Clear? yes +Inode 13 is in use, but has dtime set. Fix? yes +Inode 13 has an invalid extent + (logical block 1, invalid physical block 8888888888888, len 1) +Clear? yes +Inode 13 has an invalid extent + (logical block 0, invalid physical block 888888888888, len 1) +Clear? yes +Inode 14 is in use, but has dtime set. Fix? yes +Inode 14 has an invalid extent + (logical block 300, invalid physical block 777777777777, len 300) +Clear? yes +Inode 14 has an invalid extent + (logical block 0, invalid physical block 7777777777, len 1) +Clear? yes +Inode 14, i_blocks is 52574694748113, should be 0. Fix? yes +Pass 2: Checking directory structure +Extended attribute block for inode 12 (/a) is invalid (999999). +Clear ('a' enables 'yes' to all) ? yes +Extended attribute block for inode 13 (/b) is invalid (298954296). +Clear ('a' enables 'yes' to all) ? no +Extended attribute block for inode 14 (/c) is invalid (388697201). +Clear? no +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Inode 12 ref count is 34463, should be 1. Fix? no +Inode 13 ref count is 9999, should be 1. Fix? no +Inode 14 ref count is 12241, should be 1. Fix? no +Pass 5: Checking group summary information +Block bitmap differences: -202 -381 -457 +Fix? no +Free blocks count wrong for group #0 (0, counted=491). +Fix? no +Free blocks count wrong (494, counted=491). +Fix? no +Free inodes count wrong for group #0 (4294967293, counted=114). +Fix? no + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** + +test_filesys: ********** WARNING: Filesystem still has errors ********** + +test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks +Exit status is 4 diff --git a/tests/f_yesthenno/script b/tests/f_yesthenno/script new file mode 100644 index 00000000..f41b78b5 --- /dev/null +++ b/tests/f_yesthenno/script @@ -0,0 +1,27 @@ +test_description="e2fsck with yes then no" +FSCK_OPT=-f +OUT=$test_name.log +EXP=$test_dir/expect + +gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE + +rm -rf $OUT +echo "yyyyyyyyyynnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1 +status=$? +echo Exit status is $status >> $OUT.new +sed -f $cmd_dir/filter.sed $OUT.new >> $OUT +rm -f $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed + rm -f tmp_expect +fi + +unset IMAGE FSCK_OPT OUT EXP