ChangeLog, badblocks.8.in, badblocks.c:
  badblocks.8.in: Added text explaining that the -n and -w options are
  	mutually exclusive.
  badblocks.c (usage): Fix usage message to make it clear that the block
  	count must be specified if the starting block is to be specified.
  	(The starting block should be a option, in the long run.)
  badblocks.c (test_nd): Save and restore the currently_testing variable
  	before going into the write verification loop.  This avoids a loop
  	termination problem if the last block on the disk is bad.  Also, turn
  	off the SIGALRM signal while restoring blocks after the user types ^C.
  	The num_saved variable is now static so that it won't get clobbered by
  	a longjmp.  buf_used and bb_count are no longer static, since they
  	aren't used by the cleanup routines anymore.
  badblocks.c (main): Removed an unsued varaible (buf_size).  Fixed bad
  	getopt argument that didn't allow the 'b' option to take an argument.
  	Added error checking when parsing the starting block number.  Fixed
  	lint warning in fscanf format string.

diff --git a/misc/ChangeLog b/misc/ChangeLog
index c60a656..b9170bd 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,3 +1,29 @@
+2000-07-13    <tytso@snap.thunk.org>
+
+	* badblocks.8.in: Added text explaining that the -n and -w options
+		are mutually exclusive.
+
+	* badblocks.c (usage): Fix usage message to make it clear that the
+		block count must be specified if the starting block is to
+		be specified.  (The starting block should be a option, in
+		the long run.)
+
+	* badblocks.c (test_nd): Save and restore the currently_testing
+		variable before going into the write verification loop.
+		This avoids a loop termination problem if the last block
+		on the disk is bad.  Also, turn off the SIGALRM signal
+		while restoring blocks after the user types ^C.  The
+		num_saved variable is now static so that it won't get
+		clobbered by a longjmp.  buf_used and bb_count are no
+		longer static, since they aren't used by the cleanup
+		routines anymore.
+
+	* badblocks.c (main): Removed an unsued varaible (buf_size).
+		Fixed bad getopt argument that didn't allow the 'b' option
+		to take an argument.  Added error checking when parsing
+		the starting block number.  Fixed lint warning in fscanf
+		format string.
+
 2000-07-06  Theodore Ts'o  <tytso@valinux.com>
 
 	* fsck.c (execute, wait_one): Treat fsck.ext3 the same as
diff --git a/misc/badblocks.8.in b/misc/badblocks.8.in
index 5be9c74..ed858a8 100644
--- a/misc/badblocks.8.in
+++ b/misc/badblocks.8.in
@@ -110,7 +110,10 @@
 will exit after the first pass.
 .TP
 .B \-n
-Use non-destructive read-write mode.
+Use non-destructive read-write mode.  By default only a non-destructive 
+read-only test is done.  This option must not be combined with the 
+.B \-w
+option, as they are mutually exclusive.
 .TP
 .B \-s
 Show the progress of the scan by writing out the block numbers as they
@@ -123,7 +126,10 @@
 Use write-mode test. With this option,
 .B badblocks
 scans for bad blocks by writing some patterns (0xaa, 0x55, 0xff, 0x00) on
-every block of the device, reading every block and comparing the contents.
+every block of the device, reading every block and comparing the contents.  
+This option may not be compiled with the 
+.B \-n 
+option, as they are mutually exclusive.
 .SH WARNING
 Never use the
 .B \-w
@@ -131,7 +137,7 @@
 This option erases data!  If you want to do write-mode testing on
 an existing file system, use the
 .B \-n
-option.  It is slower, but it will preserve your data.
+option instead.  It is slower, but it will preserve your data.  
 .SH AUTHOR
 .B badblocks
 was written by Remy Card <Remy.Card@linux.org>.  Current maintainer is
diff --git a/misc/badblocks.c b/misc/badblocks.c
index 785f732..66e352b 100644
--- a/misc/badblocks.c
+++ b/misc/badblocks.c
@@ -66,12 +66,9 @@
 static int s_flag = 0;			/* show progress of test */
 static int force = 0;			/* force check of mounted device */
 
-static char *blkbuf;		/* Allocation array for bad block testing */
-
-
 static void usage(NOARGS)
 {
-	fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n [-c blocks_at_once] [-p num_passes] device [blocks_count] [start_count]\n"),
+	fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n [-c blocks_at_once] [-p num_passes] device [blocks_count [start_count]]\n"),
 		 program_name);
 	exit (1);
 }
@@ -415,14 +412,14 @@
 	char *blkbuf, *save_ptr, *test_ptr, *read_ptr;
 	char * ptr;
 	int try, i;
-	long got, used2, written;
+	long got, used2, written, save_currently_testing;
 	struct saved_blk_record *test_record;
-	int	num_saved;
+	/* This is static to prevent being clobbered by the longjmp */
+	static int num_saved;
 	jmp_buf terminate_env;
 	errcode_t errcode;
-	/* These are static to prevent being clobbered by the longjmp */
-	static long buf_used = 0;
-	static unsigned int bb_count = 0;
+	long buf_used;
+	unsigned int bb_count;
 
 	errcode = ext2fs_badblocks_list_iterate_begin(bb_list,&bb_iter);
 	if (errcode) {
@@ -467,8 +464,8 @@
 		/*
 		 * Abnormal termination by a signal is handled here.
 		 */
-
-		fprintf(stderr, _("Interrupt caught, cleaning up\n"));
+		signal (SIGALRM, SIG_IGN);
+		fprintf(stderr, _("\nInterrupt caught, cleaning up\n"));
 
 		save_ptr = blkbuf;
 		for (i=0; i < num_saved; i++) {
@@ -484,6 +481,7 @@
 	capture_terminate(terminate_env);
 
 	buf_used = 0;
+	bb_count = 0;
 	save_ptr = blkbuf;
 	test_ptr = blkbuf + (blocks_at_once * block_size);
 	currently_testing = from_count;
@@ -545,6 +543,7 @@
 			continue;
 
 		flush_bufs(dev);
+		save_currently_testing = currently_testing;
 
 		/*
 		 * for each contiguous block that we read into the
@@ -601,6 +600,7 @@
 		buf_used = 0;
 		save_ptr = blkbuf;
 		test_ptr = blkbuf + (blocks_at_once * block_size);
+		currently_testing = save_currently_testing;
 	}
 	num_blocks = 0;
 	alarm(0);
@@ -662,7 +662,6 @@
 	unsigned int (*test_func)(int dev, unsigned long blocks_count,
 				  int block_size, unsigned long from_count,
 				  unsigned long blocks_at_once);
-	size_t	buf_size;
 
 	setbuf(stdout, NULL);
 	setbuf(stderr, NULL);
@@ -675,7 +674,7 @@
 	
 	if (argc && *argv)
 		program_name = *argv;
-	while ((c = getopt (argc, argv, "bf:i:o:svwnc:p:h:")) != EOF) {
+	while ((c = getopt (argc, argv, "b:fi:o:svwnc:p:h:")) != EOF) {
 		switch (c) {
 		case 'b':
 			block_size = strtoul (optarg, &tmp, 0);
@@ -764,6 +763,11 @@
 	}
 	if (optind <= argc-1) {
 		from_count = strtoul (argv[optind], &tmp, 0);
+		if (*tmp) {
+			com_err (program_name, 0, _("bad starting block - %s"),
+				 argv[optind]);
+			exit (1);
+		}
 	} else from_count = 0;
 	if (from_count >= blocks_count) {
 	    com_err (program_name, 0, _("bad blocks range: %lu-%lu"),
@@ -827,7 +831,7 @@
 
 	if (in) {
 		for(;;) {
-			switch(fscanf (in, "%lu\n", &next_bad)) {
+			switch(fscanf (in, "%u\n", &next_bad)) {
 				case 0:
 					com_err (program_name, 0, "input file - bad format");
 					exit (1);