[comp.sources.misc] v13i079: MS-Shell 1.6 - Patch 1. Part 01 of 02

istewart@datlog.co.uk (07/03/90)

Posting-number: Volume 13, Issue 79
Submitted-by: istewart@datlog.co.uk
Archive-name: ms_sh-1.6/patch01

This is the FIRST patch to the MS-DOS Bourne Shell release 1.6.  However,
it changes the release from 1.6 to 1.6.2.  Release 1.6.1 never successfully
made it out of Data Logic - transmission corruption.

The patch fixes a number of minor problems in 1.6 and changes the way
swap files are written.  After the first write, only the data and stack
are written to the file - reducing the I/O overhead I hope.  There are
also some fixes and enhancements to the directory and raw I/O functions to
support Unix format directory names (ones ending in a / which DOS doesn't
like).

The changes are marked in the diffs for Notes1.6.

There are two shar files in this patch.  Unshar them (they check the order
so you should be OK there) to generate Patch1.6.2.  Then apply the patch
in the top level source directory for the shell.

    patch -p <Patch1.6.2

In passing, this version has been tested on PC-NFS 3.0 with no problems.

Regards,

Ian Stewartson
Data Logic Ltd, Queens House, Greenhill Way, Harrow, Middlesex, HA1 1YR, UK.
(Phone) +44 81 863 0383 (Telex) 888103 (Fax) +44 81 861 2010
(Network) istewart@datlog.co.uk or ukc!datlog!istewart
--------------------
#!/bin/sh
# This is MS-Shell, Patch 1.6.2, a shell archive (shar 3.21)
# made 06/26/1990 19:18 UTC by istewart@dlvax2
# Source directory /usr/proj1/ssd/istewart/src/shell
#
# existing files WILL be overwritten
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#  65254 -rw-r--r-- Patch1.6.2
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test -r @shar_seq_.tmp; then
	echo "Must unpack archives in sequence!"
	next=`cat @shar_seq_.tmp`; echo "Please unpack part $next next"
	exit 1
fi
# ============= Patch1.6.2 ==============
echo "x - extracting Patch1.6.2 (Text)"
sed 's/^X//' << 'SHAR_EOF' > Patch1.6.2 &&
XIndex: Notes1.6
X*** ../sh16/Notes1.6	Mon Apr 30 21:43:13 1990
X--- Notes1.6	Tue Jun 26 19:46:22 1990
X***************
X*** 1,7 ****
X! Version 1.6 Release Notes:
X  
X! The following problems have been fixed in 1.6
X  
X     1.   Traps did now work correctly (as far as possible for DOS) la System
X  	V.3
X     2.   File descriptor duplication closed standard input.
X--- 1,12 ----
X! Version 1.6.2 Release Notes:
X  
X! Note: Release 1.6.1 did occur to comp.ibm.pc.binaries.  However, the
X! transmission was corrupt and by the time I was notified (the moderator having
X! been in hospital), release 1.6.2 was ready.  So the source patches for
X! 1.6.1 where not released.
X  
X+ The following problems have been fixed in 1.6.2 (including 1.6).
X+ 
X     1.   Traps did now work correctly (as far as possible for DOS) la System
X  	V.3
X     2.   File descriptor duplication closed standard input.
X***************
X*** 18,23 ****
X--- 23,40 ----
X     9.   exec >filename did not work
X    10.   Some temporary files were not deleted.
X    11.   The swapper failed to check for disk full errors
X+   12.   The full path name is provided to the DOS spawn interrupt so that
X+ 	the PICNIX utilities now work.
X+   13.   Certain areas of code are now protected against interruption which
X+ 	would cause hanging.
X+   14.	The original directory is restored on exit.
X+   15.	A couple of missing setarea having been added to stop hangs
X+   16.	The input buffer is correctly initialised and nulls are added so
X+ 	that the correct command is saved when an interrupt occurs.
X+   17.	An error in the reloading of buffers from files has been fixed.
X+   18.	The directory routines have been modified to correctly handle
X+ 	all valid Unix format directory names (ie a Unix directory name
X+ 	can end in /.  However, DOS does not think this is a directory).
X  
X  The following enhancements have been made:
X  
X***************
X*** 48,53 ****
X--- 65,74 ----
X     16.  Quoting of arugments with white space in them to MSDOS commands
X  	has been added.
X     17.  Full internal Interrup 24 support is provided.
X+    18.  The amount of data written to swap file by only dumping the
X+ 	data and stack space after the first write.
X+    19.	The ms_dio function have been enhanced to support raw and block
X+ 	devices (well not really - just the stat and fstat functions).
X  
X  The following enhancements/bugs remain outstanding:
X  
X***************
X*** 62,70 ****
X      2.  8 Bit character are not supported.  This is tied in with the
X  	processing of escape characters.  The shell uses the 8-bit to
X  	mark escaped characters (Release 1.7).
X-     
X-     3.  Reduce the amount of data written to swap file by only dumping the
X- 	data and stack space after the first write (Release 1.7+).
X      
X  Thanks are due to
X  
X--- 83,88 ----
XIndex: lib/ms_dio.c
X*** ../sh16/lib/ms_dio.c	Fri Mar  2 11:32:52 1990
X--- lib/ms_dio.c	Fri Jun 22 09:15:57 1990
X***************
X*** 11,18 ****
X   * The devices supported are:
X   *
X   *	/dev/hdxy	- Hard disk drive x parition y (x = 0 to 9, y =
X!  *			  0 to 9, where 0 is the whole disk).
X!  *	/dev/fdx	- Floppy drive x (x = 0 to 9).
X   *	/dev/kmem	- Memory driver
X   *
X   * It does its best to determine what type of disk you are reading.
X--- 11,21 ----
X   * The devices supported are:
X   *
X   *	/dev/hdxy	- Hard disk drive x parition y (x = 0 to 9, y =
X!  *			  0 to 9, where 0 is the whole disk) as a block
X!  *			  device
X!  *	/dev/fdx	- Floppy drive x (x = 0 to 9) as a block device
X!  *	/dev/rhdxy	- Hard disk drive as a character device
X!  *	/dev/rfdx	- Floppy drive as a character device
X   *	/dev/kmem	- Memory driver
X   *
X   * It does its best to determine what type of disk you are reading.
X***************
X*** 20,25 ****
X--- 23,30 ----
X   * Redistribution and use in source and binary forms are permitted
X   * provided that the above copyright notice is duplicated in the
X   * source form.
X+  *
X+  * Version 1.2, 22 June 90
X   */
X  
X  #include <sys/types.h>
X***************
X*** 33,38 ****
X--- 38,44 ----
X  #include <ctype.h>
X  #include <unistd.h>
X  #include <time.h>
X+ #include <stdarg.h>
X  #include <ms_dio.h>
X  
X  #undef open
X***************
X*** 49,74 ****
X  #undef isatty
X  #undef tell
X  
X! #define SECSIZ		512
X  #define	MS_MODIFIER	30000
X! #define BIOS_READ	0x2
X  #define BIOS_WRITE	0x3
X  #define HD_FLAG		0x80		/* Hard disk flag		*/
X  #define MEGABYTE	1048576L
X! #define DRIVE_RAM	20
X  
X- #ifdef __STDC__
X  static int		dio_do (int, struct fs *, char *, long, unsigned int);
X  static struct fs	*dio_fpcheck (int);
X! static int		dio_fncheck (char *);
X! #else
X! static int		dio_do ();
X! static struct fs	*dio_fpcheck ();
X! static int		dio_fncheck ();
X! #endif
X  
X  static struct fs {
X      int		mode;			/* Open mode			*/
X      int		drive;
X      int		partition;		/* Hard disk partition number	*/
X      off_t	location;		/* Current offset		*/
X--- 55,77 ----
X  #undef isatty
X  #undef tell
X  
X! #define SECSIZ		512		/* Sector size			*/
X  #define	MS_MODIFIER	30000
X! #define BIOS_READ	0x2		/* BIOS functions		*/
X  #define BIOS_WRITE	0x3
X  #define HD_FLAG		0x80		/* Hard disk flag		*/
X  #define MEGABYTE	1048576L
X! #define DRIVE_RAM	20		/* RAM drive value		*/
X  
X  static int		dio_do (int, struct fs *, char *, long, unsigned int);
X  static struct fs	*dio_fpcheck (int);
X! static int		dio_fncheck (char *, mode_t *);
X  
X+ /* Our internal file handler table */
X+ 
X  static struct fs {
X      int		mode;			/* Open mode			*/
X+     mode_t	st_mode;		/* File mode for stat		*/
X      int		drive;
X      int		partition;		/* Hard disk partition number	*/
X      off_t	location;		/* Current offset		*/
X***************
X*** 79,84 ****
X--- 82,89 ----
X      long	m_scount;		/* Total sectors per disk	*/
X  } *MS_io_fs[_NFILE];
X  
X+ /* MSDOS Partition table */
X+ 
X  struct partition {
X      long	f_type;			/* Type flags			*/
X      long	f_status;		/* Status flags			*/
X***************
X*** 86,93 ****
X      long	size;			/* Size in sectors		*/
X  };
X  
X! static int	fs_init = 0;
X  
X  /* Do the actual read/write to the disk.  This function is not used
X   * for the RAM drive
X   */
X--- 91,125 ----
X      long	size;			/* Size in sectors		*/
X  };
X  
X! static int	fs_init = 0;		/* Initialisation complete	*/
X! static int	DIO_Error_Code;		/* Last do_dio Error Code	*/
X  
X+ #define DEC_BADC	0x01		/* Bad command			*/
X+ #define DEC_AMNF	0x02		/* Address mark not found	*/
X+ #define DEC_WRITEP	0x03		/* Write protected		*/
X+ #define DEC_SECNF	0x04		/* Sector not found		*/
X+ #define DEC_RESET	0x05		/* Reset failed			*/
X+ #define DEC_CHANGE	0x06		/* Diskette remove/changed	*/
X+ #define DEC_PARAMETER	0x07		/* Bad parameter table		*/
X+ #define DEC_DMAOVER	0x08		/* DMA overrun			*/
X+ #define DEC_DMACROSS	0x09		/* DMA across 64K boundary	*/
X+ #define DEC_BADSECTOR	0x0a		/* Bad sector detected		*/
X+ #define DEC_BADTRACK	0x0b		/* Bad track detected		*/
X+ #define DEC_UNSUPTRK	0x0c		/* Unsupported track		*/
X+ #define DEC_INVSEC	0x0d		/* Invalid number of sectors	*/
X+ #define DEC_CDAMD	0x0e		/* Control data address mark	*/
X+ #define DEC_DMAARB	0x0f		/* DMA arbitration error	*/
X+ #define DEC_CRC		0x10		/* bad CRC/ECC on read		*/
X+ #define DEC_ECC		0x11		/* Data ECC corrected		*/
X+ #define DEC_CONTROL	0x20		/* Controller failed		*/
X+ #define DEC_SEEK	0x40		/* Seek failed			*/
X+ #define DEC_TIMEOUT	0x80		/* Timeout			*/
X+ #define DEC_NOTREADY	0xaa		/* Drive not ready		*/
X+ #define DEC_UNDEF	0xbb		/* Undefined error		*/
X+ #define DEC_WRITEF	0xcc		/* Write fault			*/
X+ #define DEC_STATUS	0xe0		/* Status error			*/
X+ #define DEC_SENSE	0xff		/* Sense operation failed	*/
X+ 
X  /* Do the actual read/write to the disk.  This function is not used
X   * for the RAM drive
X   */
X***************
X*** 107,112 ****
X--- 139,146 ----
X      struct SREGS	sreg;
X  #endif
X  
X+     DIO_Error_Code = 0;
X+ 
X      for (j = 0; j < secknt; j += nsec, buf += (nsec * SECSIZ), secnum += nsec)
X      {
X  
X***************
X*** 154,165 ****
X  
X  	    if (!reg.x.cflag)
X  		break;
X- 	}
X  
X  /* Check for failure */
X  
X  	if (i == 3)
X  	{
X  	    errno = EIO;
X  	    return -1;
X  	}
X--- 188,210 ----
X  
X  	    if (!reg.x.cflag)
X  		break;
X  
X+ /* If we are reading more than one sector - reduce the number of sectors by
X+  * two
X+  */
X+ 
X+ 	    else if (nsec > 1)
X+ 	    {
X+ 		--i;
X+ 		nsec /= 2;
X+ 	    }
X+ 	}
X+ 
X  /* Check for failure */
X  
X  	if (i == 3)
X  	{
X+ 	    DIO_Error_Code = (int)reg.h.ah;
X  	    errno = EIO;
X  	    return -1;
X  	}
X***************
X*** 168,174 ****
X      return secknt * SECSIZ;
X  }
X  
X! /* Write function */
X  
X  int		dio_write (fp, from_buf, from_cnt)
X  int		fp;			/* File handler			*/
X--- 213,221 ----
X      return secknt * SECSIZ;
X  }
X  
X! /*
X!  * write - Write function
X!  */
X  
X  int		dio_write (fp, from_buf, from_cnt)
X  int		fp;			/* File handler			*/
X***************
X*** 290,296 ****
X      return amt;
X  }
X  
X! /* Read function */
X  
X  int		dio_read (fp, to_buf, to_cnt)
X  int		fp;			/* File handler			*/
X--- 337,345 ----
X      return amt;
X  }
X  
X! /*
X!  * read - Read function
X!  */
X  
X  int		dio_read (fp, to_buf, to_cnt)
X  int		fp;			/* File handler			*/
X***************
X*** 334,339 ****
X--- 383,390 ----
X  	return to_cnt;
X      }
X  
X+ /* Get the last part of the first sector required */
X+ 
X      fquo = FP->location / SECSIZ;
X      frem = (unsigned int) (FP->location % SECSIZ);
X  
X***************
X*** 355,360 ****
X--- 406,413 ----
X  	to_cnt -= amt;
X      }
X  
X+ /* Get the middle sectors required */
X+ 
X      cquo = to_cnt / SECSIZ;
X      crem = to_cnt % SECSIZ;
X  
X***************
X*** 391,415 ****
X      return (amt);
X  }
X  
X! int	dio_open (name, mode, permissions)
X  char	*name;
X  int	mode;
X- mode_t	permissions;
X  {
X      struct fs	*FP;
X      int		fp, i, j;
X      int		drive, ndrive;
X      union REGS	iregs;
X      char	buf[SECSIZ];
X  
X! /* Check for initialisation */
X  
X      if (!(fs_init++))
X  	memset (MS_io_fs, 0, sizeof (struct fs *) * _NFILE);
X  
X  /* Direct I/o file name */
X  
X!     if ((drive = dio_fncheck (name)) != -1)
X      {
X  	for (fp = 0; (fp < _NFILE) && (MS_io_fs[fp] != (struct fs *)NULL); fp++)
X  	    ;
X--- 444,480 ----
X      return (amt);
X  }
X  
X! /*
X!  * open - Open a file
X!  */
X! 
X! int	dio_open (name, mode)
X  char	*name;
X  int	mode;
X  {
X      struct fs	*FP;
X      int		fp, i, j;
X      int		drive, ndrive;
X      union REGS	iregs;
X      char	buf[SECSIZ];
X+     va_list	ap;
X+     int		permissions;
X+     mode_t	dmode;
X  
X! /* Check the permission mask if it exists */
X  
X+     va_start (ap, mode);
X+     permissions = va_arg (ap, int);
X+     va_end (ap);
X+ 
X+ /* Check for initialisation */
X+ 
X      if (!(fs_init++))
X  	memset (MS_io_fs, 0, sizeof (struct fs *) * _NFILE);
X  
X  /* Direct I/o file name */
X  
X!     if ((drive = dio_fncheck (name, &dmode)) != -1)
X      {
X  	for (fp = 0; (fp < _NFILE) && (MS_io_fs[fp] != (struct fs *)NULL); fp++)
X  	    ;
X***************
X*** 424,430 ****
X  	}
X  
X  	FP->location = 0L;
X! 	FP->mode = mode;
X  
X  /* RAM access ? */
X  
X--- 489,496 ----
X  	}
X  
X  	FP->location = 0L;
X! 	FP->mode     = mode;
X! 	FP->st_mode  = dmode;
X  
X  /* RAM access ? */
X  
X***************
X*** 585,592 ****
X  
X  		if (dio_do (BIOS_READ, FP, buf, 0L, 1) == -1)
X  		{
X- 		    FP->m_sector = (iregs.h.bl == 0x02) ? 15 : 9;
X  
X  		    iregs.h.ah   = 0x17;
X  		    iregs.h.dl   = (unsigned char)FP->drive;
X  		    iregs.h.al   = (unsigned char)(5 - iregs.h.bl);
X--- 651,672 ----
X  
X  		if (dio_do (BIOS_READ, FP, buf, 0L, 1) == -1)
X  		{
X  
X+ /* If not a sector not found error - abort */
X+ 
X+ 		    if ((DIO_Error_Code != DEC_SECNF) &&
X+ 			(DIO_Error_Code != DEC_UNSUPTRK) &&
X+ 			(DIO_Error_Code != DEC_INVSEC))
X+ 		    {
X+ 			free (FP);
X+ 			errno = EIO;
X+ 			return -1;
X+ 		    }
X+ 
X+ /* Otherwise, switch type */
X+ 
X+ 		    FP->m_sector = (iregs.h.bl == 0x02) ? 15 : 9;
X+ 
X  		    iregs.h.ah   = 0x17;
X  		    iregs.h.dl   = (unsigned char)FP->drive;
X  		    iregs.h.al   = (unsigned char)(5 - iregs.h.bl);
X***************
X*** 604,615 ****
X  /* Check to see if sector 8 exists */
X  
X  		if (dio_do (BIOS_READ, FP, buf, 8L, 1) == -1)
X! 		    FP->m_sector = 8;
X  
X  /* Check to see if sector 380 exists */
X  
X  		if (dio_do (BIOS_READ, FP, buf, 380L, 1) == -1)
X  		    FP->m_head = 1;
X  	    }
X  
X  /* 720K drive - read sector 15 to see if 1.4M */
X--- 684,723 ----
X  /* Check to see if sector 8 exists */
X  
X  		if (dio_do (BIOS_READ, FP, buf, 8L, 1) == -1)
X! 		{
X  
X+ /* If not a sector not found error - abort */
X+ 
X+ 		    if ((DIO_Error_Code != DEC_SECNF) &&
X+ 			(DIO_Error_Code != DEC_UNSUPTRK) &&
X+ 			(DIO_Error_Code != DEC_INVSEC))
X+ 		    {
X+ 			free (FP);
X+ 			errno = EIO;
X+ 			return -1;
X+ 		    }
X+ 
X+ 		    FP->m_sector = 8;
X+ 		}
X+ 
X  /* Check to see if sector 380 exists */
X  
X  		if (dio_do (BIOS_READ, FP, buf, 380L, 1) == -1)
X+ 		{
X+ 
X+ /* If not a sector not found error - abort */
X+ 
X+ 		    if ((DIO_Error_Code != DEC_SECNF) &&
X+ 			(DIO_Error_Code != DEC_UNSUPTRK) &&
X+ 			(DIO_Error_Code != DEC_INVSEC))
X+ 		    {
X+ 			free (FP);
X+ 			errno = EIO;
X+ 			return -1;
X+ 		    }
X+ 
X  		    FP->m_head = 1;
X+ 		}
X  	    }
X  
X  /* 720K drive - read sector 15 to see if 1.4M */
X***************
X*** 619,625 ****
X--- 727,747 ----
X  		FP->m_scount = FP->m_cyl * FP->m_head * FP->m_sector;
X  
X  		if (dio_do (BIOS_READ, FP, buf, 17L, 1) == -1)
X+ 		{
X+ 
X+ /* If not a sector not found error - abort */
X+ 
X+ 		    if ((DIO_Error_Code != DEC_SECNF) &&
X+ 			(DIO_Error_Code != DEC_UNSUPTRK) &&
X+ 			(DIO_Error_Code != DEC_INVSEC))
X+ 		    {
X+ 			free (FP);
X+ 			errno = EIO;
X+ 			return -1;
X+ 		    }
X+ 
X  		    FP->m_sector = 9;
X+ 		}
X  	    }
X  
X  	    FP->m_scount = FP->m_cyl * FP->m_head * FP->m_sector;
X***************
X*** 635,641 ****
X  	return open (name, mode, permissions);
X  }
X  
X! /* fstat function */
X  
X  int		dio_fstat (fp, St)
X  int		fp;
X--- 757,765 ----
X  	return open (name, mode, permissions);
X  }
X  
X! /* 
X!  * fstat - fstat function
X!  */
X  
X  int		dio_fstat (fp, St)
X  int		fp;
X***************
X*** 652,658 ****
X  /* Dummy values */
X  
X      memset (St, 0, sizeof (struct stat));
X!     St->st_mode = 0x61b6;
X      St->st_nlink = 1;
X  
X      if (FP->drive == DRIVE_RAM)
X--- 776,782 ----
X  /* Dummy values */
X  
X      memset (St, 0, sizeof (struct stat));
X!     St->st_mode = FP->st_mode;
X      St->st_nlink = 1;
X  
X      if (FP->drive == DRIVE_RAM)
X***************
X*** 675,681 ****
X  }
X  
X  /*
X!  * Close function
X   */
X  
X  int	dio_close (fp)
X--- 799,805 ----
X  }
X  
X  /*
X!  * close - Close function
X   */
X  
X  int	dio_close (fp)
X***************
X*** 695,701 ****
X  }
X  
X  /*
X!  * Seek function
X   */
X  
X  long	dio_lseek (fp, off, type)
X--- 819,825 ----
X  }
X  
X  /*
X!  * lseek - Seek function
X   */
X  
X  long	dio_lseek (fp, off, type)
X***************
X*** 737,743 ****
X      return (FP->location = check);
X  }
X  
X! /* Check for a valid file pointer */
X  
X  static struct fs	*dio_fpcheck (fp)
X  int			fp;
X--- 861,870 ----
X      return (FP->location = check);
X  }
X  
X! /*
X!  * Check for a valid file pointer.  Look up the file handler in the table
X!  * of our file handlers
X!  */
X  
X  static struct fs	*dio_fpcheck (fp)
X  int			fp;
X***************
X*** 754,800 ****
X      return FP;
X  }
X  
X! /* Check for a valid file name */
X  
X! static int	dio_fncheck (name)
X  char		*name;
X  {
X  
X! /* Check for hard disk */
X  
X!     if (isdigit(name[7]) && isdigit(name[8]) && (strlen (name) == 9) &&
X! 	(!strnicmp (name, "/dev/hd", 6)))
X      {
X  	int	i = atoi (&name[7]);
X  
X  	return ((i % 10) > 4) ? -1 : i | HD_FLAG;
X      }
X  
X! /* Check for floppy disk */
X  
X!     else if (isdigit(name[7]) && (strlen (name) == 8) &&
X! 	(!strnicmp (name, "/dev/fd", 6)))
X  	return name[7] - '0';
X  
X      else if (!stricmp (name, "/dev/kmem"))
X  	return DRIVE_RAM;
X  
X      return -1;
X  }
X  
X! /* Get file status */
X  
X  int		dio_stat (name, St)
X  char		*name;
X  struct stat	*St;
X  {
X      int		drive;
X  
X!     if ((drive = dio_fncheck (name)) == -1)
X  	return stat (name, St);
X  
X      memset (St, 0, sizeof (struct stat));
X!     St->st_mode = 0x61b6;
X      St->st_nlink = 1;
X      St->st_atime = time ((time_t *)NULL);
X      St->st_ctime = St->st_ctime;
X--- 881,959 ----
X      return FP;
X  }
X  
X! /*
X!  * Check for a valid file name.  We are looking for one of 'our' file names
X!  * /dev/hd??, /dev/fd? or /dev/mem.  The device number is returned.
X!  */
X  
X! static int	dio_fncheck (name, dmode)
X  char		*name;
X+ mode_t		*dmode;
X  {
X  
X! /* Set up default mode */
X  
X!     if (dmode != (mode_t *)NULL)
X! 	*dmode = 0x61b6;
X! 
X! /* Check for hard disk */
X! 
X!     if (isdigit (name[7]) && isdigit (name[8]) && (strlen (name) == 9) &&
X! 	(strnicmp (name, "/dev/hd", 7) == 0))
X      {
X  	int	i = atoi (&name[7]);
X  
X  	return ((i % 10) > 4) ? -1 : i | HD_FLAG;
X      }
X  
X!     else if (isdigit (name[8]) && isdigit (name[9]) && (strlen (name) == 10) &&
X! 	     (strnicmp (name, "/dev/rhd", 8) == 0))
X!     {
X! 	int	i = atoi (&name[8]);
X  
X! 	if (dmode != (mode_t *)NULL)
X! 	    *dmode = 0x21b6;
X! 
X! 	return ((i % 10) > 4) ? -1 : i | HD_FLAG;
X!     }
X! 
X! /* Check for floppy disk */
X! 
X!     else if (isdigit (name[7]) && (strlen (name) == 8) &&
X! 	(!strnicmp (name, "/dev/fd", 7)))
X  	return name[7] - '0';
X  
X+     else if (isdigit(name[8]) && (strlen (name) == 9) &&
X+ 	(!strnicmp (name, "/dev/rfd", 8)))
X+     {
X+ 	if (dmode != (mode_t *)NULL)
X+ 	    *dmode = 0x21b6;
X+ 
X+ 	return name[8] - '0';
X+     }
X+ 
X      else if (!stricmp (name, "/dev/kmem"))
X  	return DRIVE_RAM;
X  
X      return -1;
X  }
X  
X! /*
X!  * stat - Get file status
X!  */
X  
X  int		dio_stat (name, St)
X  char		*name;
X  struct stat	*St;
X  {
X      int		drive;
X+     mode_t	dmode;
X  
X!     if ((drive = dio_fncheck (name, &dmode)) == -1)
X  	return stat (name, St);
X  
X      memset (St, 0, sizeof (struct stat));
X!     St->st_mode  = dmode;
X      St->st_nlink = 1;
X      St->st_atime = time ((time_t *)NULL);
X      St->st_ctime = St->st_ctime;
X***************
X*** 816,828 ****
X      return 0;
X  }
X  
X! /* Check file access */
X  
X  int	dio_access (name, mode)
X  char	*name;
X  int	mode;
X  {
X!     if (dio_fncheck (name) == -1)
X  	return access (name, mode);
X  
X      else if (mode & 1)
X--- 975,989 ----
X      return 0;
X  }
X  
X! /*
X!  * access - Check file access
X!  */
X  
X  int	dio_access (name, mode)
X  char	*name;
X  int	mode;
X  {
X!     if (dio_fncheck (name, (mode_t *)NULL) == -1)
X  	return access (name, mode);
X  
X      else if (mode & 1)
X***************
X*** 834,859 ****
X      return 0;
X  }
X  
X! /* Change file permissions */
X  
X  int	dio_chmod (name, mode)
X  char	*name;
X  int	mode;
X  {
X!     return (dio_fncheck (name) == -1) ? chmod (name, mode) : 0;
X  }
X  
X! /* Create file */
X  
X  int	dio_creat (name, mode)
X  char	*name;
X  int	mode;
X  {
X!     return (dio_fncheck (name) == -1) ? creat (name, mode)
X  				      : dio_open (name, O_WRONLY, mode);
X  }
X  
X! /* Duplicate handler */
X  
X  int	dio_dup (fp)
X  int	fp;
X--- 995,1026 ----
X      return 0;
X  }
X  
X! /*
X!  * chmod - Change file permissions
X!  */
X  
X  int	dio_chmod (name, mode)
X  char	*name;
X  int	mode;
X  {
X!     return (dio_fncheck (name, (mode_t *)NULL) == -1) ? chmod (name, mode) : 0;
X  }
X  
X! /*
X!  * create - Create file
X!  */
X  
X  int	dio_creat (name, mode)
X  char	*name;
X  int	mode;
X  {
X!     return (dio_fncheck (name, (mode_t *)NULL) == -1) ? creat (name, mode)
X  				      : dio_open (name, O_WRONLY, mode);
X  }
X  
X! /*
X!  * dup - Duplicate handler
X!  */
X  
X  int	dio_dup (fp)
X  int	fp;
X***************
X*** 864,872 ****
X--- 1031,1043 ----
X      if (fp < MS_MODIFIER)
X  	return dup (fp);
X  
X+ /* Check valid */
X+ 
X      if ((FP1 = dio_fpcheck (fp)) == (struct fs *)NULL)
X  	return -1;
X  
X+ /* Create a new entry */
X+ 
X      for (fp = 0; (fp < _NFILE) && (MS_io_fs[fp] != (struct fs *)NULL); fp++)
X  	;
X  
X***************
X*** 877,888 ****
X  	return -1;
X      }
X  
X      MS_io_fs[fp] = FP;
X      *FP = *FP1;
X      return fp;
X  }
X  
X! /* Check if tty */
X  
X  int	dio_isatty (fp)
X  int	fp;
X--- 1048,1063 ----
X  	return -1;
X      }
X  
X+ /* Duplicate it */
X+ 
X      MS_io_fs[fp] = FP;
X      *FP = *FP1;
X      return fp;
X  }
X  
X! /*
X!  * isatty - Check if tty
X!  */
X  
X  int	dio_isatty (fp)
X  int	fp;
X***************
X*** 893,899 ****
X      return 0;
X  }
X  
X! /* Tell location */
X  
X  long	dio_tell (fp)
X  int	fp;
X--- 1068,1076 ----
X      return 0;
X  }
X  
X! /*
X!  * tell - Tell location
X!  */
X  
X  long	dio_tell (fp)
X  int	fp;
XIndex: lib/director.c
X*** ../sh16/lib/director.c	Fri Mar  2 11:33:41 1990
X--- lib/director.c	Fri Jun 22 09:18:24 1990
X***************
X*** 4,9 ****
X--- 4,11 ----
X   *  A public domain implementation of BSD directory routines for
X   *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
X   *  August 1897
X+  *
X+  *  Modified by Ian Stewartson, Data Logic.
X   */
X  
X  #include <sys/types.h>
X***************
X*** 27,70 ****
X  {
X      struct stat		statb;
X      DIR			*dirp;
X!     char		c;
X      struct _dircontents	*dp;
X!     char		nbuf[PATH_MAX + NAME_MAX + 2];
X      struct find_t	dtabuf;
X      
X!     if (stat (name, &statb) < 0)
X! 	return (DIR *) NULL;
X  
X!     if (!S_ISDIR(statb.st_mode))
X      {
X  	errno = ENOTDIR;
X  	return (DIR *)NULL;
X      }
X  
X      if ((dirp = (DIR *) malloc (sizeof (DIR))) == (DIR *) NULL)
X  	return (DIR *) NULL;
X  
X!     if (*name && (c = name[strlen (name) - 1]) != '\\' && c != '/')
X! 	(void) strcat (strcpy (nbuf, name), "\\*.*");
X  
X!     else
X! 	(void) strcat (strcpy (nbuf, name), "*.*");
X  
X      dirp->dd_loc      = 0;
X      dirp->dd_cp       = (struct _dircontents *) NULL;
X      dirp->dd_contents = (struct _dircontents *) NULL;
X  
X      if (_dos_findfirst (nbuf, ATTRIBUTES, &dtabuf) != 0)
X  	return dirp;
X  
X      do 
X      {
X! 	if (((dp = (struct _dircontents *) malloc(sizeof(struct _dircontents))) == (struct _dircontents *) NULL) ||
X  	    ((dp->_d_entry = strdup (dtabuf.name)) == (char *) NULL))
X  	{
X  	    if (dp != (char *)NULL)
X  		free ((char *) dp);
X  
X  	    free_dircontents (dirp->dd_contents);
X  	    return (DIR *) NULL;
X  	}
X--- 29,113 ----
X  {
X      struct stat		statb;
X      DIR			*dirp;
X!     char		*last;
X      struct _dircontents	*dp;
X!     char		*nbuf;
X      struct find_t	dtabuf;
X+     int			len = strlen (name);
X      
X!     if (!len)
X!     {
X! 	errno = ENOTDIR;
X! 	return (DIR *)NULL;
X!     }
X  
X!     if ((nbuf = malloc (len + 4)) == (char *)NULL)
X! 	return (DIR *) NULL;
X! 
X!     strcpy (nbuf, name);
X!     last = &nbuf[len - 1];
X! 
X! /* Ok, DOS is very picky about its directory names.  The following are
X!  * valid.
X!  *
X!  *  c:/
X!  *  c:.
X!  *  c:name/name1
X!  *
X!  *  c:name/ is not valid
X!  */
X! 
X!     if (((*last == '\\') || (*last == '/')) && (len > 1) &&
X! 	(!((len == 3) && (name[1] == ':'))))
X! 	*(last--) = 0;
X! 
X! /* Check its a directory */    
X! 
X!     if (stat (nbuf, &statb) < 0)
X      {
X+ 	free (nbuf);
X+ 	return (DIR *) NULL;
X+     }
X+ 
X+     if (!S_ISDIR (statb.st_mode))
X+     {
X+ 	free (nbuf);
X  	errno = ENOTDIR;
X  	return (DIR *)NULL;
X      }
X  
X      if ((dirp = (DIR *) malloc (sizeof (DIR))) == (DIR *) NULL)
X+     {
X+ 	free (nbuf);
X  	return (DIR *) NULL;
X+     }
X  
X! /* Set up to find everything */
X  
X!     if ((*last != '\\') && (*last != '/'))
X! 	strcat (last, "/");
X  
X+     strcat (last, "*.*");
X+ 
X      dirp->dd_loc      = 0;
X      dirp->dd_cp       = (struct _dircontents *) NULL;
X      dirp->dd_contents = (struct _dircontents *) NULL;
X  
X      if (_dos_findfirst (nbuf, ATTRIBUTES, &dtabuf) != 0)
X+     {
X+ 	free (nbuf);
X  	return dirp;
X+     }
X  
X      do 
X      {
X! 	if (((dp = (struct _dircontents *) malloc (sizeof (struct _dircontents))) == (struct _dircontents *) NULL) ||
X  	    ((dp->_d_entry = strdup (dtabuf.name)) == (char *) NULL))
X  	{
X  	    if (dp != (char *)NULL)
X  		free ((char *) dp);
X  
X+ 	    free (nbuf);
X  	    free_dircontents (dirp->dd_contents);
X  	    return (DIR *) NULL;
X  	}
X***************
X*** 80,90 ****
X      } while (_dos_findnext (&dtabuf) == 0);
X  
X      dirp->dd_cp = dirp->dd_contents;
X  
X      return dirp;
X  }
X  
X! int	closedir(dirp)
X  DIR	*dirp;
X  {
X      free_dircontents (dirp->dd_contents);
X--- 123,134 ----
X      } while (_dos_findnext (&dtabuf) == 0);
X  
X      dirp->dd_cp = dirp->dd_contents;
X+     free (nbuf);
X  
X      return dirp;
X  }
X  
X! int	closedir (dirp)
X  DIR	*dirp;
X  {
X      free_dircontents (dirp->dd_contents);
X***************
X*** 92,98 ****
X      return 0;
X  }
X  
X! struct dirent	*readdir(dirp)
X  DIR		*dirp;
X  {
X      static struct dirent	dp;
X--- 136,142 ----
X      return 0;
X  }
X  
X! struct dirent	*readdir (dirp)
X  DIR		*dirp;
X  {
X      static struct dirent	dp;
XIndex: shell/sh.h
XPrereq: 1.17
X*** ../sh16/shell/sh.h	Tue May  1 20:01:03 1990
X--- shell/sh.h	Thu Jun 21 21:43:37 1990
X***************
X*** 13,21 ****
X   * 2.  The sources (or parts thereof) or objects generated from the sources
X   *     (or parts of sources) cannot be sold under any circumstances.
X   *
X!  *    $Header: sh.h 1.17 90/05/01 19:58:18 MS_user Exp $
X   *
X   *    $Log:	sh.h $
X   * Revision 1.17  90/05/01  19:58:18  MS_user
X   * Change Patchlevel
X   * 
X--- 13,30 ----
X   * 2.  The sources (or parts thereof) or objects generated from the sources
X   *     (or parts of sources) cannot be sold under any circumstances.
X   *
X!  *    $Header: sh.h 1.20 90/05/31 09:47:41 MS_user Exp $
X   *
X   *    $Log:	sh.h $
X+  * Revision 1.20  90/05/31  09:47:41  MS_user
X+  * Implement partial write when swapping to disk
X+  * 
X+  * Revision 1.19  90/05/15  21:08:41  MS_user
X+  * Release 1.6.2
X+  * 
X+  * Revision 1.18  90/05/09  20:36:22  MS_user
X+  * Patchlvel for 1.6.1
X+  * 
X   * Revision 1.17  90/05/01  19:58:18  MS_user
X   * Change Patchlevel
X   * 
X***************
X*** 71,77 ****
X   * 
X   */
X  
X! #define PATCHLEVEL	4
X  #define	LINE_MAX	1000	/* Command line length			*/
X  #define HISTORY_MAX	100	/* History array length			*/
X  				/* Space for full file name		*/
X--- 80,86 ----
X   * 
X   */
X  
X! #define PATCHLEVEL	6
X  #define	LINE_MAX	1000	/* Command line length			*/
X  #define HISTORY_MAX	100	/* History array length			*/
X  				/* Space for full file name		*/
X***************
X*** 101,106 ****
X--- 110,116 ----
X  #define O_PMASK		(O_RDWR | O_CREAT | O_TRUNC | O_TEXT)
X  				/* Open in create mode for swap file	*/
X  #define O_SMASK		(O_RDWR | O_CREAT | O_TRUNC | O_BINARY)
X+ #define O_SaMASK	(O_RDWR | O_BINARY)
X  #define O_RMASK		(O_RDONLY | O_NOINHERIT | O_TEXT)
X  
X  /*
X***************
X*** 180,186 ****
X--- 190,199 ----
X  extern char		path_line[];	/* Process path			*/
X  extern unsigned int	SW_intr;	/* interrupt pending		*/
X  extern unsigned int	SW_Blocks;	/* Number of blocks to read	*/
X+ extern unsigned int	SW_SBlocks;	/* Short Number of blocks to	*/
X+ 					/* read				*/
X  extern int		SW_fp;		/* File or EMS Handler		*/
X+ extern int		SW_Pwrite;	/* Partial write to disk?	*/
X  extern unsigned long	SW_EMstart;	/* Start addr of extend mem	*/
X  extern unsigned int	SW_Mode;	/* Type of swapping to do	*/
X  					/* 1 - disk			*/
X***************
X*** 189,194 ****
X--- 202,208 ----
X  					/* 4 - XMS Driver		*/
X  extern unsigned int	SW_EMSFrame;	/* EMS Frame segment		*/
X  
X+ extern unsigned int	etext;		/* End of text segment		*/
X  extern int		Swap_Mode;	/* Swapping mode		*/
X  
X  /* If you change these values, change sh7, swap_device as well */
X***************
X*** 590,596 ****
X  extern int	getn (char *);
X  extern int	Create_NG_VL (void);
X  extern void	Delete_G_VL (void);
X! extern void	Restore_Dir (void);
X  extern void	Restore_Environment (int, int);
X  extern int	sort_compare (char **, char **);
X  extern int	Check_Script (char *, char **, int *);
X--- 604,610 ----
X  extern int	getn (char *);
X  extern int	Create_NG_VL (void);
X  extern void	Delete_G_VL (void);
X! extern void	Restore_Dir (char *);
X  extern void	Restore_Environment (int, int);
X  extern int	sort_compare (char **, char **);
X  extern int	Check_Script (char *, char **, int *);
X***************
X*** 607,612 ****
X--- 621,627 ----
X  extern void	Clear_Extended_File (void);
X  extern void	Print_Version (int);
X  extern bool	anys (char *, char *);
X+ extern void	Clear_Swap_File (void);
X  
X  /*
X   * Interrupt handling
XIndex: shell/sh0.asm
XPrereq: 1.8
X*** ../sh16/shell/sh0.asm	Tue May  1 19:50:48 1990
X--- shell/sh0.asm	Thu Jun 21 21:45:35 1990
X***************
X*** 16,24 ****
X  ; 2.  The sources (or parts thereof) or objects generated from the sources
X  ;     (or parts of sources) cannot be sold under any circumstances.
X  ;
X! ;    $Header: sh0.asm 1.8 90/04/25 22:32:31 MS_user Exp $
X  ;
X  ;    $Log:	sh0.asm $
X  ;	Revision 1.8  90/04/25  22:32:31  MS_user
X  ;	Fix missing disk full check on writing swap file
X  ;	
X--- 16,30 ----
X  ; 2.  The sources (or parts thereof) or objects generated from the sources
X  ;     (or parts of sources) cannot be sold under any circumstances.
X  ;
X! ;    $Header: sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $
X  ;
X  ;    $Log:	sh0.asm $
X+ ;	Revision 1.10  90/05/31  17:46:31  MS_user
X+ ;	Enasure that correct block zero is written for partial write
X+ ;	
X+ ;	Revision 1.9  90/05/31  10:04:56  MS_user
X+ ;	Implement partial write on disk swapping
X+ ;	
X  ;	Revision 1.8  90/04/25  22:32:31  MS_user
X  ;	Fix missing disk full check on writing swap file
X  ;	
X***************
X*** 63,68 ****
X--- 69,77 ----
X  
X  DGROUP		group	CONST, _BSS, _DATA
X  
X+ C_ETEXT		segment word public 'ENDCODE' 
X+ C_ETEXT		ends 
X+ 
X  ;
X  ; Declare external functions and data
X  ;
X***************
X*** 72,80 ****
X  	extrn	__psp:word
X  
X  ;
X! ; Start of the spawn function
X  ;
X  
X  SH0_TEXT	segment
X  		assume  cs: SH0_TEXT, ds: NOTHING, ss: DGROUP
X  
X--- 81,99 ----
X  	extrn	__psp:word
X  
X  ;
X! ; Declare end of text variable.  The ENDCODE segment appears to be the last
X! ; code segment loaded by the Microsoft loader
X  ;
X  
X+ C_ETEXT		segment word public 'ENDCODE' 
X+ 		public	cetext
X+ cetext		equ	$
X+ C_ETEXT		ends 
X+ 
X+ ;
X+ ; Start of the spawn function
X+ ;
X+ 
X  SH0_TEXT	segment
X  		assume  cs: SH0_TEXT, ds: NOTHING, ss: DGROUP
X  
X***************
X*** 85,90 ****
X--- 104,110 ----
X  		public	_path_line
X  		public	_SW_intr
X  		public	_SW_Blocks
X+ 		public	_SW_SBlocks
X  		public	_SW_fp
X  		public	_SW_I0_V
X  		public	_SW_I23_V
X***************
X*** 96,107 ****
X--- 116,132 ----
X  		public	_SW_XMS_Gversion
X  		public	_SW_XMS_Allocate
X  		public	_SW_XMS_Free
X+ 		public	_etext
X+ 		public	_SW_Pwrite
X  
X  
X  _cmd_line	db	129 dup (?)	; Command line
X  _path_line	db	80 dup (?)	; Path line
X+ _etext		dw	seg cetext	; End of text segment
X  _SW_Blocks	dw	0		; Number of blocks to read/write
X+ _SW_SBlocks	dw	0		; Short Number of blocks to read/write
X  _SW_fp		dw	0		; File ID
X+ _SW_Pwrite	dw	0		; Partial write to disk?
X  _SW_I0_V	dd	0		; Our Interrupt Zero address
X  _SW_I23_V	dd	0		; Our Interrupt 23 address
X  _SW_EMstart	dd	0100000H	; Default Extended Mem start
X***************
X*** 303,313 ****
X  ; Copy out to the swap file
X  ;
X  
X- 	mov	si, word ptr cs:_SW_Blocks	; Load Number of blocks to read
X  	mov	bx, word ptr cs:_SW_fp		; Load file handler
X  
X! ; load up extended memory GDT for destination
X  
X  	mov	ax, word ptr cs:_SW_EMstart
X  	mov	dl, byte ptr cs:_SW_EMstart + 2
X  	call	$GDT_dest_load
X--- 328,354 ----
X  ; Copy out to the swap file
X  ;
X  
X  	mov	bx, word ptr cs:_SW_fp		; Load file handler
X+ 	mov	si, word ptr cs:_SW_Blocks	; Load Number of blocks to read
X+ 	mov	ax, word ptr cs:N_mcb		; Load the start address
X  
X! ;
X! ;  Check for Partial write on disk swap file
X! ;
X  
X+ 	cmp	word ptr cs: _SW_Mode, 1	; Partial disk write ?
X+ 	jnz	SPart_Write
X+ 	cmp	word ptr cs: _SW_Pwrite, 0
X+ 	jz	SPart_Write
X+ 
X+ 	mov	si, word ptr cs:_SW_SBlocks	; Load Number of blocks to read
X+ 	mov	ax, word ptr cs:_etext		; Load the start address
X+ 
X+ SPart_Write:
X+ 	push	ax
X+ 
X+ ; load up extended memory GDT for destination
X+ 
X  	mov	ax, word ptr cs:_SW_EMstart
X  	mov	dl, byte ptr cs:_SW_EMstart + 2
X  	call	$GDT_dest_load
X***************
X*** 316,324 ****
X  ; set up DS register with start of start copy
X  ;
X  
X! 	mov	ax, word ptr cs:N_mcb		; Load the start address
X  	mov	ds, ax
X- 
X  	mov	ax, word ptr cs:SW_LMstart 	; Load Full start address
X  	mov	dl, byte ptr cs:SW_LMstart + 2
X  	call	$GDT_src_load
X--- 357,364 ----
X  ; set up DS register with start of start copy
X  ;
X  
X! 	pop	ax
X  	mov	ds, ax
X  	mov	ax, word ptr cs:SW_LMstart 	; Load Full start address
X  	mov	dl, byte ptr cs:SW_LMstart + 2
X  	call	$GDT_src_load
X***************
X*** 337,343 ****
X  $Write_L1:
X  	mov	ax, word ptr cs: _SW_Mode
X  	dec	ax
X! 	jz	$Write_disk
X  	dec	ax
X  	jnz	$Write_L2
X  	jmp	$W_extend
X--- 377,383 ----
X  $Write_L1:
X  	mov	ax, word ptr cs: _SW_Mode
X  	dec	ax
X! 	jz	$W_disk
X  	dec	ax
X  	jnz	$Write_L2
X  	jmp	$W_extend
X***************
X*** 391,425 ****
X  ;
X  ; Write to disk
X  ;
X! $Write_disk:
X! 	mov	ax, 04000H		; Set up to write
X! 	mov	cx, ax			; Load count
X! 	xor	dx, dx			; Clear start address
X! 	push	bx			; Save FP
X! 	push	si			; Save count and Data Segment
X  
X! 	int	021H			; Write the data
X  
X- 	pop	si			; Restore Regs
X- 	pop	bx
X- 	jnc	$Write_disk1		; NO error - continue
X- 
X- ;
X- ; Error - abort
X- ;
X- 	mov	ds, word ptr cs:S_ds	; Restore DS
X- 	mov	ah, al
X- 	call	far ptr __maperror	; Map the error
X- 	jmp	$Write_Error1
X- 
X- ; Check for 16K write
X- 
X- $Write_disk1:
X- 	cmp	ax, 04000H
X- 	jz	$Write_Incr
X- 	mov	ax,01c1cH		; Set disk full
X- 	jmp	$Write_error		; NO - abort
X- 
X  $Write_Incr:
X  	dec	si			; Decrement block count
X  	mov	ax, ds			; Increment offset
X--- 431,441 ----
X  ;
X  ; Write to disk
X  ;
X! $W_disk:
X! 	call	$Write_disk
X  
X! ; Increment counter
X  
X  $Write_Incr:
X  	dec	si			; Decrement block count
X  	mov	ax, ds			; Increment offset
X***************
X*** 469,482 ****
X  	mov	al, ah
X  	xor	ah, ah
X  	mov	word ptr ds:_errno, ax	; Save error code
X  $Write_Error1:
X  	mov	ax, 0FFFEH
X  	jmp	$SA_spawn_Exit		; Exit
X  
X  ;
X! ; Swap file is now written, set up environment
X  ;
X  $Write_Complete:
X  	mov	ds, word ptr cs:exec_env	; Load Env seg.
X  	xor	si, si				; Clear start offset
X  
X--- 485,519 ----
X  	mov	al, ah
X  	xor	ah, ah
X  	mov	word ptr ds:_errno, ax	; Save error code
X+ 
X  $Write_Error1:
X  	mov	ax, 0FFFEH
X  	jmp	$SA_spawn_Exit		; Exit
X  
X  ;
X! ; Swap file is now written, set up environment.  If this was a partial
X! ; write, we need to write the first 4K.
X  ;
X+ 
X  $Write_Complete:
X+ 	cmp	word ptr cs: _SW_Mode, 1	; Partial disk write ?
X+ 	jnz	S1Part_Write
X+ 	cmp	word ptr cs: _SW_Pwrite, 0
X+ 	jz	S1Part_Write
X+ 
X+ 	mov	ax, 04200H			; Set seek
X+ 	xor	dx, dx
X+ 	xor	cx, cx
X+ 	int	021H
X+ 	jnc	$Write_C1			; Abort - swap file error
X+ 	jmp	$Map_error
X+ 
X+ $Write_C1:
X+ 	mov	ax, word ptr cs:N_mcb		; Load the start address
X+ 	mov	ds, ax
X+ 	call	$Write_disk
X+ 
X+ S1Part_Write:
X  	mov	ds, word ptr cs:exec_env	; Load Env seg.
X  	xor	si, si				; Clear start offset
X  
X***************
X*** 660,665 ****
X--- 697,704 ----
X  ;
X  ; Error
X  ;
X+ 
X+ $Map_error:
X  	mov	ds, word ptr cs:S_ds	; Restore DS
X  	mov	ah, al
X  	call	far ptr __maperror	; Map the error
X***************
X*** 927,932 ****
X--- 966,1014 ----
X  	ret
X  
X  $Read_XMS	endp
X+ 
X+ ;
X+ ; WRITE DISK FUNCTION
X+ ;
X+ ;	BX - file handler
X+ ;	SI - Block count
X+ ;	DS - Output data segement
X+ ;
X+ 
X+ $Write_disk	proc	near
X+ 
X+ 	mov	ax, 04000H		; Set up to write
X+ 	mov	cx, ax			; Load count
X+ 	xor	dx, dx			; Clear start address
X+ 	push	bx			; Save FP
X+ 	push	si			; Save count and Data Segment
X+ 
X+ 	int	021H			; Write the data
X+ 
X+ 	pop	si			; Restore Regs
X+ 	pop	bx
X+ 	jnc	$Write_disk1		; NO error - continue
X+ 
X+ ;
X+ ; Error - abort
X+ ;
X+ 	mov	ds, word ptr cs:S_ds	; Restore DS
X+ 	mov	ah, al
X+ 	call	far ptr __maperror	; Map the error
X+ 	jmp	$Write_Error1
X+ 
X+ ; Check for 16K write
X+ 
X+ $Write_disk1:
X+ 	cmp	ax, 04000H
X+ 	jnz	$Write_disk2
X+ 	ret
X+ 
X+ $Write_disk2:
X+ 	mov	ax,01c1cH		; Set disk full
X+ 	jmp	$Write_error		; NO - abort
X+ 
X+ $Write_disk	endp
X  
X  ;
X  ; READ DISK FUNCTION
XIndex: shell/sh1.c
XPrereq: 1.14
X*** ../sh16/shell/sh1.c	Tue May  1 19:48:00 1990
X--- shell/sh1.c	Thu Jun 21 21:46:25 1990
X***************
X*** 13,21 ****
X   * 2.  The sources (or parts thereof) or objects generated from the sources
X   *     (or parts of sources) cannot be sold under any circumstances.
X   *
X!  *    $Header: sh1.c 1.14 90/04/25 22:33:28 MS_user Exp $
X   *
X   *    $Log:	sh1.c $
X   * Revision 1.14  90/04/25  22:33:28  MS_user
X   * Fix rsh check for PATH
X   * 
X--- 13,28 ----
X   * 2.  The sources (or parts thereof) or objects generated from the sources
X   *     (or parts of sources) cannot be sold under any circumstances.
SHAR_EOF
echo "File Patch1.6.2 is continued in part 2"
echo "2" > @shar_seq_.tmp
exit 0