Files scsiinfo-1.7/scsiformat and scsiinfo-1.7.fmt/scsiformat differ
diff -uNrp scsiinfo-1.7/scsiformat.c scsiinfo-1.7.fmt/scsiformat.c
--- scsiinfo-1.7/scsiformat.c	2004-05-08 16:48:49.000000000 +0200
+++ scsiinfo-1.7.fmt/scsiformat.c	2004-05-08 19:14:57.000000000 +0200
@@ -54,6 +54,10 @@
 #include <linux/fs.h>
 #endif
 #include <linux/hdreg.h>
+#include <scsi/scsi.h>
+//#include <sys/ioctl.h>
+#include <scsi/scsi_ioctl.h>
+#include <scsi/sg.h>
 /* #include <linux/genhd.h> */
 
 struct partition {
@@ -69,11 +73,8 @@ struct partition {
         unsigned int nr_sects;          /* nr of sectors in partition */
 } __attribute__((packed));
 
-#define TEST_UNIT_READY	(0x00)
-#define FORMAT_UNIT	(0x04)
-#define NOT_READY	(0x01)
-
-#define VERSION "scsiformat V1.0 08/23/97 by Michael Weller."
+#define VERSION "scsiformat V1.0  08/23/97 by Michael Weller.\n"	\
+		"           V1.0a 05/08/04 by Kurt Garloff."
 
 #define SECTOR_SIZE 512
 #define WAIT_DISK 10		/* Timeouts for flush and rrpart */
@@ -439,6 +440,13 @@ void format_unit()
     catch_term();
     mk_tmpfile();
 
+    /* Hmm, do we need to find the corresponding sg device instead
+     * to be able to tune the timeout? */
+    *(int*) buffer = 1+12*3600;
+    status = ioctl(fd, SG_SET_TIMEOUT, buffer);
+    status = ioctl(fd, SG_GET_TIMEOUT, buffer);
+    //printf("Using a timeout of %i minutes\n", status/60);
+
     memset(buffer, -1, sizeof(buffer));
 
     *(((int *) buffer) + 1) = 255;	/* length of output buffer */
@@ -509,7 +517,7 @@ void format_unit()
 	exit(2);
     }
 #ifndef DONT_FORMAT
-    status = ioctl(fd, 1 /* SCSI_IOCTL_SEND_COMMAND */ , buffer);
+    status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, buffer);
     if (status < 0) {
 	argperr("scsiformat (sending FORMAT_UNIT to %s)", devicename);
 	exit(1);
@@ -1180,16 +1188,18 @@ int remove_swaps(void)
     partdev = alloca(o + 5);
     strcpy(partdev, devicename);
 
-    for (i = 1; i < 32; i++) {
+    for (i = 1; i < 16; i++) {
 	sprintf(partdev + o, "%d", i);
 	if (!swapoff(partdev)) {
 	    fprintf(stderr, "Warning, turned swap off on %s!\n", partdev);
-	} else if ((errno != ENOENT) && (errno != EINVAL)) {
-	    fprintf(stderr, "Warning, unable to turn swap off on %s!\n", partdev);
+	} else if ((errno != ENOENT) && (errno != EINVAL) && (errno != ENXIO)) {
+	    fprintf(stderr, "Warning, unable to turn swap off on %s! (%s)\n", 
+		    partdev, strerror(errno));
 	    flag = 1;
 	}
 	errno = 0;
     }
+    /*
     partdev[o + 1] = 0;
     for (partdev[o] = 'a'; partdev[o] <= 'z'; partdev[o]++) {
 	if (!swapoff(partdev)) {
@@ -1200,6 +1210,7 @@ int remove_swaps(void)
 	}
 	errno = 0;
     }
+    */
     return flag;
 }
 
@@ -1316,6 +1327,100 @@ void add_defect(char type)
     }
 }
 
+void show_part()
+{
+    unsigned char* shortnm = strrchr(devicename, '/') + 1;
+    FILE* proc_part = fopen("/proc/partitions", "r");
+    unsigned long fmtblk = 0;
+    unsigned char nm[64];
+    int rd = 1;
+    if (!proc_part)
+	return;
+  
+    printf("Partitions:\n"); 
+    fgets(nm, 64, proc_part);
+    fgets(nm, 64, proc_part);
+    while (!feof(proc_part) && rd) {
+	unsigned int maj, min;
+	unsigned long blocks;
+	rd = fscanf(proc_part, "%i %i %li %s\n",
+		&maj, &min, &blocks, nm);
+	if (!strcmp(shortnm, nm) || 
+	    (!memcmp(shortnm, nm, strlen(shortnm)) && isdigit(nm[strlen(shortnm)]))) {
+		printf("%i:%2i %-5s %7li MiB\n",
+			maj, min, nm, blocks*1024/1000000);
+		if (blocks > fmtblk)
+			fmtblk = blocks;
+	}
+    }
+    printf("\nFormatting %li MiB can take very long. Estimate: %li min\n\n",
+	   fmtblk*1024/1000000, 1+fmtblk/294912);
+        
+}
+
+void get_info(void)
+{
+    unsigned char buffer[64];
+    unsigned char word[20];
+    int id[2];
+    int status;
+    int lun;
+    unsigned char *cmd;
+
+    status = ioctl (fd, SCSI_IOCTL_GET_IDLUN, &id);
+    if (status == -1)
+	exit(1);
+
+    lun = id[0] >> 8 & 0xff;
+    printf("About to format SCSI disk %s on host %i chan %i id %i lun %i\n",
+	   devicename, id[0] >> 24 & 0xff, id[0] >> 16 & 0xff, 
+	   id[0] & 0xff, lun);
+
+    memset(buffer, -1, sizeof(buffer));
+
+    *((int *) buffer) = 0;	/* length of input data */
+    *(((int *) buffer) + 1) = 8+36;	/* length of output buffer */
+
+    cmd = (char *) (((int *) buffer) + 2);
+
+    cmd[0] = INQUIRY;
+    cmd[1] = (lun & 0x7) << 5;	/* LUN / (reserved) */
+    cmd[2] = 0x00;		/* page */
+    cmd[3] = 0x00;		/* alloc ln hi */
+    cmd[4] = 0x24;		/* alloc ln lo */
+    cmd[5] = 0x00;		/* (reserved) */
+
+    if (par_debug) {
+	printf("Sending INQUIRY command:\n");
+	dump(stdout, ((int *) buffer) + 2, *((int *) buffer));
+    }
+    status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, buffer);
+    if ((status == EAGAIN) || (status == EBUSY))
+	exit(1);
+    if (status < 0) {
+	argperr("scsiformat (sending INQUIRY to %s)", devicename);
+	exit(1);
+    }
+    if (par_debug) {
+	printf("Got SCSI status %02x and extended sense information:\n", status);
+	dump(stdout, buffer + 8, 36);
+    }
+
+    if (cmd[4] < 32)
+	printf("Short INQUIRY answer :-(i\n");
+    else {
+	memcpy(word, cmd+8, 8); word[8] = 0;
+	printf("%s ", word);
+	memcpy(word, cmd+16, 16); word[16] = 0;
+	printf("%s ", word);
+	memcpy(word, cmd+32, 4); word[4] = 0;
+	printf("%s\n", word);
+    }
+
+    show_part();
+
+}
+
 void prompt_user(void)
 {
     FILE *ttyIN = NULL;
@@ -1332,6 +1437,8 @@ void prompt_user(void)
     ttystat.c_lflag |= ICANON | ISIG | ECHO;
     tcsetattr(ttyfd, TCSANOW, &ttystat);
 
+    get_info();
+
     srand((unsigned) time(NULL));
     a = 1 + (int) (24.0 * rand() / (RAND_MAX + 1.0));
     b = 1 + (int) (24.0 * rand() / (RAND_MAX + 1.0));
Files scsiinfo-1.7/scsiinfo and scsiinfo-1.7.fmt/scsiinfo differ
Files scsiinfo-1.7/tworands and scsiinfo-1.7.fmt/tworands differ
