[comp.os.minix] dosread error message solved and patch

hall@cod.NOSC.MIL (Robert R. Hall) (04/12/89)

In using dosread/dosdir on some of sub directories on my hard disk
I would get the error message: "I/O error: Error 0"
This responce was from a read request that the file system thought
was an lseek address beyond the end of file mark for the disk.  I wrote
the following program to display what size the file system thought the
disk was:
---------------------   sizedisk.c -------------------------
#include <stdio.h>

main()
{
   long            pos, lseek();
   char           *device;
   short	   disk;

   device = "/dev/hd0";
   if ((disk = open(device, 0) < 0))
      fprintf(stderr, "Cannot open %s\n", device);
   pos = lseek(disk, 0L, 2);
   printf("Size of disk on drive C is: %D 0x%X\n", pos, pos);
   close(disk);
}
------------------     end     -----------------------
It displayed 7M as the disk size which is the size of my Minix
partition and is too small for the total size of the hard disk which
is 32M.  I corrected this problem by deleting the special file:
  /dev/hd0 and recreating it with
  mknod /dev/hd0 b 3 0
sizedisk now show the hard disk size to be zero but the error message
changes to: "Cannot set break!".  I had to uncomment
the print statement for disk parameters to get the exact mumber for
fat_size and cluster_size and match the define constants MAX_FAT_SIZE
and MAX_CLUSTER_SIZE to them otherwise I had a very small stack and
couldn't read beyond the root directory.  With these changes I now
have a dosread working for my hard disk.

  The next problem I have is that forget to exchange the boot disk
for my MS-DOS file transfer disk and I get the error message:
    "DISK is not DOS Format." written as the file and I did not
see the message and was wondering why my new file was so short.
The follow cdiff is my redirection what I consider to be error messages
to stderr.  The cdiff is relative to 1.3 and also includes the 1.4a
changes.

Robert R. Hall
hall@nosc.mil
---------------   cut here --------
echo x - dosread.dif
sed '/^X/s///' > dosread.dif << '/'
X*** /usr/v1.3d/commands/dosread.c	Tue Nov  1 08:38:55 1988
X--- dosread.c	Tue Apr 11 07:57:30 1989
X***************
X*** 1,6 ****
X  /* dos{read|write|dir} - handle DOS disks	Author: Michiel Huisjes */
X  
X! /* dosdir - list MS-DOS directories.
X   * doswrite - write stdin to DOS-file
X   * dosread - read DOS-file to stdout
X   *
X--- 1,7 ----
X  /* dos{read|write|dir} - handle DOS disks	Author: Michiel Huisjes */
X  
X! /**
X!  * dosdir - list MS-DOS directories.
X   * doswrite - write stdin to DOS-file
X   * dosread - read DOS-file to stdout
X   *
X***************
X*** 25,44 ****
X   *			properly then all the rest should be okay.
X   *		If there are any problems there is debugging information
X   *		  in fdinit() -- please let me know of any problems
X!  */
X! 
X! #include <sys/stat.h>
X  
X  #define DRIVE0		"/dev/at0"
X  #define DRIVE1		"/dev/at1"
X! #define FDRIVE		"/dev/hd0"
X  
X  #define DDDD	0xFD
X  #define DDHD	0xF9
X  #define DDFD	0xF8
X  
X  #define	MAX_CLUSTER_SIZE	4096
X! #define MAX_FAT_SIZE		23552	/* 46 sectoren */
X  #define HMASK		0xFF00
X  #define LMASK		0x00FF
X  
X--- 26,54 ----
X   *			properly then all the rest should be okay.
X   *		If there are any problems there is debugging information
X   *		  in fdinit() -- please let me know of any problems
X!  *
X!  * 	Modified by Al Crew January 5, 1989
X!  *		allow 720K (and when the kernel does 1.44M) diskettes
X!  *			(for 1.44M the size of /dev/at[01] will have to
X!  *			 be changed or a new device name added)
X!  *		adjusted MAX_FAT_SIZE and MAX_CLUSTER_SIZE to better
X!  *			match my fixed disk (you may want to change them)
X!  *              fixed bug in read_cluster (sbrk failures were not reported)
X!  */
X! 
X! #include <stdio.h>
X  
X  #define DRIVE0		"/dev/at0"
X  #define DRIVE1		"/dev/at1"
X! #define FDRIVE0		"/dev/hd0"
X! #define FDRIVE1		"/dev/hd5"
X  
X  #define DDDD	0xFD
X  #define DDHD	0xF9
X  #define DDFD	0xF8
X  
X  #define	MAX_CLUSTER_SIZE	4096
X! #define MAX_FAT_SIZE		20992	/* 41 sectoren */
X  #define HMASK		0xFF00
X  #define LMASK		0x00FF
X  
X***************
X*** 101,107 ****
X  
X  #define is_dir(d)		((d)->d_attribute & SUB_DIR)
X  
X! #define EOF			0400
X  #define EOF_MARK		'\032'
X  #define STD_OUT			1
X  #define flush()			print(STD_OUT, NIL_PTR, 0)
X--- 111,117 ----
X  
X  #define is_dir(d)		((d)->d_attribute & SUB_DIR)
X  
X! #define EOF_1			0400
X  #define EOF_MARK		'\032'
X  #define STD_OUT			1
X  #define flush()			print(STD_OUT, NIL_PTR, 0)
X***************
X*** 120,126 ****
X  BOOL Rflag, Lflag, Aflag, dos_read, dos_write, dos_dir, Tfat = TRUE;
X  
X  unsigned short free_cluster(), next_cluster();
X! char *make_name(), *num_out(), *slash(), *brk();
X  long mark, data_start, lseek(), time(), f_start;
X  
X  leave(nr)
X--- 130,136 ----
X  BOOL Rflag, Lflag, Aflag, dos_read, dos_write, dos_dir, Tfat = TRUE;
X  
X  unsigned short free_cluster(), next_cluster();
X! char *make_name(), *slash(), *brk();
X  long mark, data_start, lseek(), time(), f_start;
X  
X  leave(nr)
X***************
X*** 133,139 ****
X  usage(prog_name)
X  register char *prog_name;
X  {
X! 	print_string(TRUE, "Usage: %s [%s\n", prog_name,
X  		     dos_dir ? "-lr] drive [dir]" : "-a] drive file");
X  	exit(1);
X  }
X--- 143,149 ----
X  usage(prog_name)
X  register char *prog_name;
X  {
X! 	fprintf(stderr, "Usage: %s [%s\n", prog_name,
X  		     dos_dir ? "-lr] drive [dir]" : "-a] drive file");
X  	exit(1);
X  }
X***************
X*** 157,163 ****
X  	else if (!strcmp(arg_ptr, "doswrite"))
X  		dos_write = TRUE;
X  	else {
X! 		print_string(TRUE, "Program should be named dosread, doswrite or dosdir.\n");
X  		exit(1);
X  	}
X  
X--- 167,173 ----
X  	else if (!strcmp(arg_ptr, "doswrite"))
X  		dos_write = TRUE;
X  	else {
X! 		fprintf(stderr, "Program should be named dosread, doswrite or dosdir.\n");
X  		exit(1);
X  	}
X  
X***************
X*** 187,240 ****
X  		case 'a':	device = DRIVE0; break;
X  		case '1':
X  		case 'b':	device = DRIVE1; break;
X! 		case 'c':
X! 		case 'd':
X! 		case 'e':
X! 		case 'f':	fdisk = TRUE; device = FDRIVE; break;
X  		default :	usage(argv[0]);
X  	}
X  
X  	if ((disk = open(device, 2)) < 0) {
X! 		print_string(TRUE, "Cannot open %s\n", device);
X  		exit(1);
X  	}
X  
X! 	if (fdisk) {		/* fixed disk */
X! 		fdinit(dev_nr);
X! 		disk_read(f_start, &fat_type, sizeof(fat_type));
X! 		if (fat_type != DDFD) {
X! 			print_string(TRUE, "Fixed disk is not DOS\n");
X! 			leave(1);
X! 		}
X! 	}
X! 	else {		/* use standard start for floppies */
X! 		f_start = FAT_START;
X! 		disk_read(f_start, &fat_type, sizeof(fat_type));
X! 		if (fat_type == DDDD) {		/* Double-sided double-density 9 s/t */
X! 			total_clusters = 355;	/* 720 - 7 - 2 - 2 - 1 */
X! 			cluster_size = 1024;	/* 2 sectors per cluster */
X! 			fat_size = 1024;	/* 2 sectors */
X! 			data_start = 6144L;	/* Starts on sector #12 */
X! 			root_entries = 112;	
X! 			sub_entries = 32;	/* 1024 / 32 */
X! 		}
X! 		else if (fat_type == DDHD) {	/* Double-sided high-density 15 s/t */
X! 			total_clusters = 2372;	/* 2400 - 14 - 7 - 7 - 1 */
X! 			cluster_size = 512;	/* 1 sector per cluster */
X! 			fat_size = 3584;	/* 7 sectors */
X! 			data_start = 14848L;	/* Starts on sector #29 */
X! 			root_entries = 224;	
X! 			sub_entries = 16;	/* 512 / 32 */
X! 		}
X! 		else {
X!         		print_string(TRUE, "Diskette is not DOS 2.0 360K or 1.2M\n");
X! 			leave(1);
X! 		}
X! 	}
X! 
X! 	disk_read(f_start + (long) fat_size, &fat_check, sizeof(fat_check));
X! 	if (fat_check != fat_type) {
X! 		print_string(TRUE, "Disk type in FAT copy differs from disk type in FAT original.\n");
X  		leave(1);
X  	}
X  
X--- 197,217 ----
X  		case 'a':	device = DRIVE0; break;
X  		case '1':
X  		case 'b':	device = DRIVE1; break;
X! 		case 'c':	fdisk = TRUE; device = FDRIVE0; break;
X! 		case 'd':	fdisk = TRUE; device = FDRIVE1; break;
X  		default :	usage(argv[0]);
X  	}
X  
X  	if ((disk = open(device, 2)) < 0) {
X! 		fprintf(stderr, "Cannot open %s\n", device);
X  		exit(1);
X  	}
X  
X! 	fdinit(dev_nr);
X! 	disk_read(f_start, &fat_type, sizeof(fat_type));
X! 	disk_read(f_start + (long) fat_size, &fat_check, sizeof(fat_check));
X! 	if (fat_check != fat_type) {
X! 		fprintf(stderr, "Disk type in FAT copy differs from disk type in FAT original.\n");
X  		leave(1);
X  	}
X  
X***************
X*** 265,284 ****
X  /*********/
X  	if (dos_dir) {
X  		entry = label();
X! 		print_string(FALSE, "Volume in drive %c ", dev_nr);
X! 		if (entry == NIL_DIR)
X! 			print(STD_OUT, "has no label.\n\n", 0);
X! 		else
X! 			print_string(FALSE, "is %S\n\n", entry->d_name);
X  	}
X  
X  	if (argv[index] == NIL_PTR) {
X  		if (!dos_dir)
X  			usage(argv[0]);
X! 		print(STD_OUT, "Root directory:\n", 0);
X! 		list_dir(root, root_entries, FALSE);
X! 		free_blocks();
X! 		flush();
X  		leave(0);
X  	}
X  
X--- 242,260 ----
X  /*********/
X  	if (dos_dir) {
X  		entry = label();
X! 		printf("Volume in drive %c ", dev_nr);
X! 		if (entry == NIL_DIR)
X! 			printf("has no label.\n\n", 0);
X! 		else
X! 			printf("is %S\n\n", entry->d_name);
X  	}
X  
X  	if (argv[index] == NIL_PTR) {
X  		if (!dos_dir)
X  			usage(argv[0]);
X! 		printf("Root directory:\n", 0);
X! 		list_dir(root, root_entries, FALSE);
X! 		free_blocks();
X  		leave(0);
X  	}
X  
X***************
X*** 294,300 ****
X  	add_path("/", FALSE);
X  
X  	if (dos_dir)
X! 		print_string(FALSE, "Directory %s:\n", path);
X  
X  	entry = find_entry(root, root_entries, argv[index]);
X  
X--- 270,276 ----
X  	add_path("/", FALSE);
X  
X  	if (dos_dir)
X! 		printf("Directory %s:\n", path);
X  
X  	entry = find_entry(root, root_entries, argv[index]);
X  
X***************
X*** 308,316 ****
X  		if (entry != NIL_DIR) {
X  			flush();
X  			if (is_dir(entry))
X! 				print_string(TRUE, "%s is a directory.\n", path);
X! 			else
X! 				print_string(TRUE, "%s already exists.\n", argv[index]);
X  			leave(1);
X  		}
X  
X--- 284,292 ----
X  		if (entry != NIL_DIR) {
X  			flush();
X  			if (is_dir(entry))
X! 				fprintf(stderr, "%s is a directory.\n", path);
X! 			else
X! 				fprintf(stderr, "%s already exists.\n", argv[index]);
X  			leave(1);
X  		}
X  
X***************
X*** 328,334 ****
X  	leave(0);
X  }
X  
X! fdinit(part_nr)		/* Fixed Disk Initializations */
X  char part_nr;
X  {
X  
X--- 304,310 ----
X  	leave(0);
X  }
X  
X! fdinit(part_nr)		/* Initializations */
X  char part_nr;
X  {
X  
X***************
X*** 379,389 ****
X  	pe = (struct part_entry *)&secbuf[TABLEOFFSET];
X  		/* get the proper partition */
X  	switch(part_nr) {
X! 		case 'f': pe++;
X! 		case 'e': pe++;
X! 		case 'd': pe++;
X! 		case 'c': boot_loc = pe->lowsec * 512L; break;
X!         	default:  printf("Error: unknown partition\n"); leave();
X  	}
X  		/* now read the boot block for the partition needed */
X  	disk_read(boot_loc, &boot, sizeof(boot));
X--- 355,367 ----
X  	pe = (struct part_entry *)&secbuf[TABLEOFFSET];
X  		/* get the proper partition */
X  	switch(part_nr) {
X! 		case '0':
X! 		case 'a':
X! 		case '1':
X! 		case 'b': boot_loc=0; break;
X! 		case 'd':
X! 		case 'c': boot_loc = pe->lowsec * 512L; break;
X!         	default:  fprintf(stderr, "Error: unknown partition\n"); leave(1);
X  	}
X  		/* now read the boot block for the partition needed */
X  	disk_read(boot_loc, &boot, sizeof(boot));
X***************
X*** 412,430 ****
X  		(boot.hidden_sectors[1]  << 8 & HMASK) + (boot.hidden_sectors[0] & LMASK));
X  	leave(1);
X  /**************/
X! 	if (boot.media_type != DDFD) {
X! 		printf("DISK is not DOS Format.\n");
X  		leave(1);
X  	}
X  	if (boot.num_fats != 2) {
X! 		printf("Disk does not have two FAT Tables!\n");
X  		leave(1);
X  	}
X  	block_size = (boot.bytes_sector[1] << 8 & HMASK) +
X  			 (boot.bytes_sector[0] & LMASK);
X  	if ((cluster_size = block_size * boot.cluster_size)
X  					> MAX_CLUSTER_SIZE) {
X! 		printf("Cluster size is larger than MAX_CLUSTER_SIZE.\n");
X  		leave(1);
X  	}
X  	reserved =  ((boot.res_sectors[1] << 8 & HMASK) +
X--- 390,410 ----
X  		(boot.hidden_sectors[1]  << 8 & HMASK) + (boot.hidden_sectors[0] & LMASK));
X  	leave(1);
X  /**************/
X! 	if (((boot.media_type & 0xf0) != 0xf0)
X!             || (boot.jump[0] != 0xeb) || (boot.jump[2] != 0x90) ) {
X! 		fprintf(stderr, "DISK is not DOS Format.\n");
X  		leave(1);
X  	}
X  	if (boot.num_fats != 2) {
X! 		fprintf(stderr, "Disk does not have two FAT Tables!\n");
X  		leave(1);
X  	}
X  	block_size = (boot.bytes_sector[1] << 8 & HMASK) +
X  			 (boot.bytes_sector[0] & LMASK);
X  	if ((cluster_size = block_size * boot.cluster_size)
X  					> MAX_CLUSTER_SIZE) {
X! 		fprintf(stderr, "Cluster size is larger than MAX_CLUSTER_SIZE. %d\n", 
X!                        cluster_size);
X  		leave(1);
X  	}
X  	reserved =  ((boot.res_sectors[1] << 8 & HMASK) +
X***************
X*** 442,448 ****
X  	if (total_clusters > 4096)
X  		Tfat = FALSE;		/* sixteen bit fat entries */
X  	if ( (fat_size *= block_size) > MAX_FAT_SIZE) {
X! 		printf("Disk FAT is larger than MAX_FAT_SIZE.\n");
X  		leave(1);
X  	}
X  	sub_entries = cluster_size / 32;
X--- 422,429 ----
X  	if (total_clusters > 4096)
X  		Tfat = FALSE;		/* sixteen bit fat entries */
X  	if ( (fat_size *= block_size) > MAX_FAT_SIZE) {
X! 		fprintf(stderr, "Disk FAT %d is larger than MAX_FAT_SIZE.\n",
X! 		   fat_size);
X  		leave(1);
X  	}
X  	sub_entries = cluster_size / 32;
X***************
X*** 521,533 ****
X  				if (!type) {
X  					if (dos_dir || *pathname) {
X  						flush();
X! 						print_string(TRUE, "Not a directory: %s\n", file_name);
X  						leave(1);
X  					}
X  				}
X  				else if (*pathname == '\0' && dos_read) {
X  					flush();
X! 					print_string(TRUE, "%s is a directory.\n", path);
X  					leave(1);
X  				}
X  				if (*pathname) {
X--- 502,514 ----
X  				if (!type) {
X  					if (dos_dir || *pathname) {
X  						flush();
X! 						fprintf(stderr, "Not a directory: %s\n", file_name);
X  						leave(1);
X  					}
X  				}
X  				else if (*pathname == '\0' && dos_read) {
X  					flush();
X! 					fprintf(stderr, "%s is a directory.\n", path);
X  					leave(1);
X  				}
X  				if (*pathname) {
X***************
X*** 547,553 ****
X  				if (function == FALSE)
X  					show(dir_ptr, name);
X  				else if (type) {	/* Recursive */
X! 					print_string(FALSE, "Directory %s%s:\n", path, name);
X  					add_path(name, FALSE);
X  					list_dir(dir_ptr, sub_entries, FALSE);
X  					add_path(NIL_PTR, FALSE);
X--- 528,534 ----
X  				if (function == FALSE)
X  					show(dir_ptr, name);
X  				else if (type) {	/* Recursive */
X! 					printf("Directory %s%s:\n", path, name);
X  					add_path(name, FALSE);
X  					list_dir(dir_ptr, sub_entries, FALSE);
X  					add_path(NIL_PTR, FALSE);
X***************
X*** 564,577 ****
X  			if (dos_write && *pathname == '\0')
X  				return NIL_DIR;
X  			flush();
X! 			print_string(TRUE, "Cannot find `%s'.\n", file_name);
X  			leave(1);
X  		case LABEL:
X  			return NIL_DIR;
X  		case ENTRY:
X  			if (!mem) {
X  				flush();
X! 				print_string(TRUE, "No entries left in root directory.\n");
X  				leave(1);
X  			}
X  
X--- 545,558 ----
X  			if (dos_write && *pathname == '\0')
X  				return NIL_DIR;
X  			flush();
X! 			fprintf(stderr, "Cannot find `%s'.\n", file_name);
X  			leave(1);
X  		case LABEL:
X  			return NIL_DIR;
X  		case ENTRY:
X  			if (!mem) {
X  				flush();
X! 				fprintf(stderr, "No entries left in root directory.\n");
X  				leave(1);
X  			}
X  
X***************
X*** 586,592 ****
X  			return new_entry(dir, entries);
X  		case FALSE:
X  			if (Rflag) {
X! 				print(STD_OUT, "\n", 0);
X  				list_dir(dir, entries, TRUE);
X  			}
X  	}
X--- 567,573 ----
X  			return new_entry(dir, entries);
X  		case FALSE:
X  			if (Rflag) {
X! 				printf("\n", 0);
X  				list_dir(dir, entries, TRUE);
X  			}
X  	}
X***************
X*** 610,625 ****
X  		cl_no = next_cluster(cl_no);
X  		if ((Tfat && cl_no == BAD) || (!Tfat && cl_no == BAD_16)){
X  			flush();
X! 			print_string(TRUE, "Reserved cluster value encountered.\n");
X  			leave(1);
X  		}
X  	} while ((Tfat && entry->d_size && cl_no != LAST_CLUSTER) ||
X  		 (!Tfat && entry->d_size && cl_no != LAST_16));
X  
X  	if ((Tfat && cl_no != LAST_CLUSTER) || (!Tfat && cl_no != LAST_16))
X! 		print_string(TRUE, "Too many clusters allocated for file.\n");
X! 	else if (entry->d_size != 0)
X! 		print_string(TRUE, "Premature EOF: %L bytes left.\n",
X  			     entry->d_size);
X  }
X  
X--- 591,606 ----
X  		cl_no = next_cluster(cl_no);
X  		if ((Tfat && cl_no == BAD) || (!Tfat && cl_no == BAD_16)){
X  			flush();
X! 			fprintf(stderr, "Reserved cluster value encountered.\n");
X  			leave(1);
X  		}
X  	} while ((Tfat && entry->d_size && cl_no != LAST_CLUSTER) ||
X  		 (!Tfat && entry->d_size && cl_no != LAST_16));
X  
X  	if ((Tfat && cl_no != LAST_CLUSTER) || (!Tfat && cl_no != LAST_16))
X! 		fprintf(stderr, "Too many clusters allocated for file.\n");
X! 	else if (entry->d_size != 0)
X! 		fprintf(stderr, "Premature EOF: %D bytes left.\n",
X  			     entry->d_size);
X  }
X  
X***************
X*** 714,720 ****
X  
X  	while ((r = fill(buffer)) > 0) {
X  		if ((next = free_cluster(FALSE)) > total_clusters) {
X! 			print_string(TRUE, "Disk full. File truncated.\n");
X  			break;
X  		}
X  
X--- 695,701 ----
X  
X  	while ((r = fill(buffer)) > 0) {
X  		if ((next = free_cluster(FALSE)) > total_clusters) {
X! 			fprintf(stderr, "Disk full. File truncated.\n");
X  			break;
X  		}
X  
X***************
X*** 839,845 ****
X  		return 0;
X  
X  	while (buffer < last) {
X! 		if ((c = get_char()) == EOF) {
X  			eof_mark = TRUE;
X  			if (Aflag)
X  				*buffer++ = EOF_MARK;
X--- 820,826 ----
X  		return 0;
X  
X  	while (buffer < last) {
X! 		if ((c = get_char()) == EOF_1) {
X  			eof_mark = TRUE;
X  			if (Aflag)
X  				*buffer++ = EOF_MARK;
X***************
X*** 864,870 ****
X  
X  	if (index == read_chars) {
X  		if ((read_chars = read(0, input, cluster_size)) == 0)
X! 			return EOF;
X  		index = 0;
X  	}
X  
X--- 845,851 ----
X  
X  	if (index == read_chars) {
X  		if ((read_chars = read(0, input, cluster_size)) == 0)
X! 			return EOF_1;
X  		index = 0;
X  	}
X  
X***************
X*** 891,897 ****
X  modes(mode)
X  register unsigned char mode;
X  {
X! 	print_string(FALSE, "\t%c%c%c%c%c", (mode & SUB_DIR) ? 'd' : '-',
X  		     (mode & 02) ? 'h' : '-', (mode & 04) ? 's' : '-',
X  		     (mode & 01) ? '-' : 'w', (mode & 0x20) ? 'a' : '-');
X  }
X--- 872,878 ----
X  modes(mode)
X  register unsigned char mode;
X  {
X! 	printf("\t%c%c%c%c%c", (mode & SUB_DIR) ? 'd' : '-',
X  		     (mode & 02) ? 'h' : '-', (mode & 04) ? 's' : '-',
X  		     (mode & 01) ? '-' : 'w', (mode & 0x20) ? 'a' : '-');
X  }
X***************
X*** 902,908 ****
X  {
X  	register unsigned short e_date = dir_ptr->d_date;
X  	register unsigned short e_time = dir_ptr->d_time;
X! 	unsigned short next;
X  	char bname[20];
X  	short i = 0;
X  
X--- 883,889 ----
X  {
X  	register unsigned short e_date = dir_ptr->d_date;
X  	register unsigned short e_time = dir_ptr->d_time;
X! 	unsigned short next, nybble;
X  	char bname[20];
X  	short i = 0;
X  
X***************
X*** 910,933 ****
X  		bname[i++] = *name++;
X  	bname[i] = '\0';
X  	if (!Lflag) {
X! 		print_string(FALSE, "%s\n", bname);
X  		return;
X  	}
X  	modes(dir_ptr->d_attribute);
X! 	print_string(FALSE, "\t%s%s", bname, strlen(bname) < 8 ? "\t\t" : "\t");
X  	i = 1;
X  	if (is_dir(dir_ptr)) {
X  		next = dir_ptr->d_cluster;
X  		while (((next = next_cluster(next)) != LAST_CLUSTER && Tfat) ||
X  			(!Tfat && next != LAST_16))
X  			i++;
X! 		print_string(FALSE, "%L", (long) i * (long) cluster_size);
X! 	}
X! 	else
X! 		print_string(FALSE, "%L", dir_ptr->d_size);
X! 	print_string(FALSE, "\t%N:%N %P %s %d\n", ((e_time & HOUR) >> 11),
X! 		     ((e_time & MIN) >> 5), (e_date & DAY),
X! 	   month[((e_date & MONTH) >> 5) - 1], ((e_date & YEAR) >> 9) + 1980);
X  }
X  
X  free_blocks()
X--- 891,922 ----
X  		bname[i++] = *name++;
X  	bname[i] = '\0';
X  	if (!Lflag) {
X! 		printf("%s\n", bname);
X  		return;
X  	}
X  	modes(dir_ptr->d_attribute);
X! 	printf("\t%s%s", bname, strlen(bname) < 8 ? "\t\t" : "\t");
X  	i = 1;
X  	if (is_dir(dir_ptr)) {
X  		next = dir_ptr->d_cluster;
X  		while (((next = next_cluster(next)) != LAST_CLUSTER && Tfat) ||
X  			(!Tfat && next != LAST_16))
X  			i++;
X! 		printf("%5D\t", (long) i * (long) cluster_size);
X! 	}
X! 	else
X! 		printf("%5D\t", dir_ptr->d_size);
X! 	nybble = (e_time & HOUR) >> 11;
X! 	if (nybble < 10) printf("0");
X! 	printf("%d:", nybble);
X! 	nybble = (e_time & MIN) >> 5;
X! 	if (nybble < 10) printf("0");
X! 	printf("%d", nybble);
X! 	nybble = e_date & DAY;
X! 	if (nybble < 10) printf(" ");
X! 	printf(" %d", nybble);
X! 	printf(" %s", month[((e_date & MONTH) >> 5) - 1]);
X! 	printf(" %d\n", ((e_date & YEAR) >> 9) + 1980);
X  }
X  
X  free_blocks()
X***************
X*** 956,1047 ****
X  			}
X  		}
X  
X! 	print_string(FALSE, "Free space: %L bytes.\n", (long) free * (long) cluster_size);
X! 	if (bad)
X! 		print_string(FALSE, "Bad sectors: %L bytes.\n", (long) bad * (long) cluster_size);
X! }
X! 
X! char *num_out(number)
X! register long number;
X! {
X! 	static char num_buf[13];
X! 	char temp[13];
X! 	register short i = 0;
X! 	short j;
X! 
X! 	if (number == 0)
X! 		temp[i++] = '0';
X! 
X! 	while (number) {
X! 		temp[i++] = (char) (number % 10L + '0');
X! 		number /= 10L;
X! 	}
X! 
X! 	for (j = 0; j < 11; j++)
X! 		num_buf[j] = temp[i - j - 1];
X! 
X! 	num_buf[i] = '\0';
X! 	return num_buf;
X! }
X! 
X! /* VARARGS */
X! print_string(err_fl, fmt, args)
X! BOOL err_fl;
X! char *fmt;
X! int args;
X! {
X! 	char buf[200];
X! 	register char *buf_ptr = buf;
X! 	char *scan_ptr;
X! 	register int *arg_ptr = &args;
X! 	short i;
X! 
X! 	while (*fmt) {
X! 		if (*fmt == '%') {
X! 			fmt++;
X! 			if (*fmt == 'c') {
X! 				*buf_ptr++ = (char) *arg_ptr++;
X! 				fmt++;
X! 				continue;
X! 			}
X! 			if (*fmt == 'S') {
X! 				scan_ptr = (char *) *arg_ptr;
X! 				for (i = 0; i < 11; i++)
X! 					*buf_ptr++ = *scan_ptr++;
X! 				fmt++;
X! 				continue;
X! 			}
X! 			if (*fmt == 's')
X! 				scan_ptr = (char *) *arg_ptr;
X! 			else if (*fmt == 'L') {
X! 				scan_ptr = num_out(*((long *) arg_ptr));
X! 				arg_ptr++;
X! 			}
X! 			else {
X! 				scan_ptr = num_out((long) *arg_ptr);
X! 				if (*fmt == 'P' && *arg_ptr < 10)
X! 					*buf_ptr++ = ' ';
X! 				else if (*fmt == 'N' && *arg_ptr < 10)
X! 					*buf_ptr++ = '0';
X! 			}
X! 			while (*buf_ptr++ = *scan_ptr++);
X! 			buf_ptr--;
X! 			arg_ptr++;
X! 			fmt++;
X! 		}
X! 		else
X! 			*buf_ptr++ = *fmt++;
X! 	}
X! 
X! 	*buf_ptr = '\0';
X! 
X! 	if (err_fl) {
X! 		flush();
X!         write(2, buf, (int) (buf_ptr - buf));
X! 	}
X! 	else
X! 		print(STD_OUT, buf, 0);
X! flush();
X  }
X  
X  DIRECTORY *read_cluster(cluster)
X--- 945,953 ----
X  			}
X  		}
X  
X! 	printf("Free space: %D bytes.\n", (long) free * (long) cluster_size);
X! 	if (bad)
X! 		printf("Bad sectors: %D bytes.\n", (long) bad * (long) cluster_size);
X  }
X  
X  DIRECTORY *read_cluster(cluster)
X***************
X*** 1050,1057 ****
X  	register DIRECTORY *sub_dir;
X  	extern char *sbrk();
X  
X! 	if ((sub_dir = (DIRECTORY *) sbrk(cluster_size)) < 0) {
X! 		print_string(TRUE, "Cannot set break!\n");
X  		leave(1);
X  	}
X  	disk_read(clus_add(cluster), sub_dir, cluster_size);
X--- 956,964 ----
X  	register DIRECTORY *sub_dir;
X  	extern char *sbrk();
X  
X! 	if ((sub_dir = (DIRECTORY *) sbrk(cluster_size)) 
X!             == ((DIRECTORY *)-1)) {
X! 		fprintf(stderr, "Cannot set break!\n");
X  		leave(1);
X  	}
X  	disk_read(clus_add(cluster), sub_dir, cluster_size);
X***************
X*** 1073,1079 ****
X  
X  	if (leave_fl && cl_index > total_clusters) {
X  		flush();
X! 		print_string(TRUE, "Disk full. File not added.\n");
X  		leave(1);
X  	}
X  
X--- 980,986 ----
X  
X  	if (leave_fl && cl_index > total_clusters) {
X  		flush();
X! 		fprintf(stderr, "Disk full. File not added.\n");
X  		leave(1);
X  	}
X  
X***************
X*** 1164,1177 ****
X  		while (*ptr++ = *file++);
X  }
X  
X- bcopy(src, dest, bytes)
X- register char *src, *dest;
X- short bytes;
X- {
X- 	while (bytes--)
X- 		*dest++ = *src++;
X- }
X- 
X  disk_io(op, seek, address, bytes)
X  register BOOL op;
X  unsigned long seek;
X--- 1071,1076 ----
X***************
X*** 1182,1188 ****
X  
X  	if (lseek(disk, seek, 0) < 0L) {
X  		flush();
X! 		print_string(TRUE, "Bad lseek\n");
X  		leave(1);
X  	}
X  
X--- 1081,1087 ----
X  
X  	if (lseek(disk, seek, 0) < 0L) {
X  		flush();
X! 		fprintf(stderr, "Bad lseek\n");
X  		leave(1);
X  	}
X  
/