delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/09/14/14:54:09

Date: Sun, 14 Sep 1997 20:02:14 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: DJ Delorie <dj AT delorie DOT com>
cc: djgpp-workers AT delorie DOT com
Subject: mntent in 970831
Message-ID: <Pine.SUN.3.91.970914200035.20461C-100000@is>
MIME-Version: 1.0

A patch for `mntent' that clears some bugs which only show on NT:

diff -c src/libc/compat/mntent/mntent.c~0 src/libc/compat/mntent/mntent.c
*** src/libc/compat/mntent/mntent.c~0	Tue Aug 13 03:14:46 1996
--- src/libc/compat/mntent/mntent.c	Sat Apr 12 12:21:06 1997
***************
*** 1,9 ****
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  /*
   * This is implementation of getmntent() and friends for DJGPP v2.x.
   *
!  * Copyright (c) 1995-96 Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
   *
   * This software may be used freely so long as this copyright notice is
   * left intact.  There is no warranty on this software.
--- 1,10 ----
+ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  /*
   * This is implementation of getmntent() and friends for DJGPP v2.x.
   *
!  * Copyright (c) 1995-97 Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
   *
   * This software may be used freely so long as this copyright notice is
   * left intact.  There is no warranty on this software.
***************
*** 41,47 ****
  #include <go32.h>
  #include <libc/farptrgs.h>
  #include <sys/movedata.h>
! #include <libc/unconst.h>
  
  /* Macro to convert a segment and an offset to a "far offset" suitable
     for _farxxx() functions of DJGPP.  */
--- 42,48 ----
  #include <go32.h>
  #include <libc/farptrgs.h>
  #include <sys/movedata.h>
! #include <libc/dosio.h>
  
  /* Macro to convert a segment and an offset to a "far offset" suitable
     for _farxxx() functions of DJGPP.  */
***************
*** 114,121 ****
             our_mem_base, (unsigned int)currdir, 0x43);
  
    /* The drive attribute word is at the offset 43h, right after the
!      current directory string.  */
!   return _farpeekw(dos_mem_base, cds_entry_address + 0x43);
  }
  
  /*
--- 115,123 ----
             our_mem_base, (unsigned int)currdir, 0x43);
  
    /* The drive attribute word is at the offset 43h, right after the
!      current directory string.  NT doesn't support this.  */
!   return
!     cds_elsize == 0x47 ? 0 : _farpeekw(dos_mem_base, cds_entry_address + 0x43);
  }
  
  /*
***************
*** 368,398 ****
  }
  
  /*
!  * Return 1 if a CD-ROM drive DRIVE_NUM is ready, i.e. there is a
!  * disk in the drive and that disk is a data (not AUDIO) disk.
   */
  static int
  cdrom_drive_ready(int drive_num)
  {
    __dpmi_regs r;
-   int i = 2;
  
!   /* Int 2Fh/AX=1505h (Read Volume Table Of Contents) will return
!      with error for empty drives or if the disk is an AUDIO disk.  */
!   r.x.es = __tb >> 4;
!   r.x.bx = __tb & 15;
!   r.x.cx = drive_num - 1;   /* 0 = A: */
!   r.x.dx = 0;   /* get the 1st descriptor (usually, the only one) */
! 
!   /* First time after the door is closed the call might fail.
!      Therefore try twice before giving up.  */
!   do
!     {
!       r.x.ax = 0x1505;
!       __dpmi_int(0x2f, &r);
!     } while (--i && (r.x.flags & 1));
! 
!   if ((r.x.flags & 1) == 0 && (r.x.ax == 0 || r.x.ax == 1))
      return 1;
    return 0;
  }
--- 370,428 ----
  }
  
  /*
!  * Return 1 if a CD-ROM drive DRIVE_NUM is ready, i.e. there
!  * is a disk in the drive and the tray door is closed.
   */
  static int
  cdrom_drive_ready(int drive_num)
  {
    __dpmi_regs r;
  
!   /* We need to avoid reading any information off the CD-ROM,
!      because then the driver will dupe MSCDEX into thinking the
!      disk isn't ever changed, and DOS calls get stale info after
!      you change the disk.  (We cannot use DOS calls *before* this
!      function, because QDPMI will crash the program if we issue
!      a DOS call that hits the disk when the drive is empty or the
!      disk is an audio disk.)
! 
!      So we use the Read Device Status command and look for the
!      door open and drive empty bits (seems like door locked bit
!      is not universally supported).  This still leaves an unsolved
!      problem: an audio disk will be reported as a ready drive, and
!      under QDPMI will crash the program when we access the drive.
!      I don't see any way out of this mess (anybody?).  Well, at
!      least with data disks we don't screw up DOS operations anymore.
! 
!      Gosh, why is it always so tricky with Microsoft software??  */
! 
!   unsigned char request_header[0x14];
!   int status;
!   unsigned dev_status;
! 
!   /* Construct the request header for the CD-ROM device driver.  */
!   memset(request_header, 0, sizeof request_header);
!   request_header[0] = sizeof request_header;
!   request_header[2] = 3;	/* IOCTL READ command */
!   *(unsigned short *)&request_header[0xe]  = __tb_offset;
!   *(unsigned short *)&request_header[0x10] = __tb_segment;
!   request_header[0x12] = 5;	/* number of bytes to transfer */
! 
!   /* Put control block into the transfer buffer.  */
!   _farpokeb(_dos_ds, __tb, 6);	/* read device status */
!   _farpokel(_dos_ds, __tb + 1, 0);	/* zero out the result field */
! 
!   /* Put request header into the transfer buffer and call the driver.  */
!   dosmemput(request_header, sizeof (request_header), __tb + 5);
!   r.x.ax = 0x1510;
!   r.x.cx = drive_num - 1;
!   r.x.es = __tb_segment;
!   r.x.bx = __tb_offset + 5;
!   __dpmi_int(0x2f, &r);
!   status = _farpeekw(_dos_ds, __tb + 5 + 3);
!   dev_status = _farpeekl(_dos_ds, __tb + 1);
!   if (status == 0x100 && _farpeekw (_dos_ds, __tb + 5 + 0x12) == 5
!       && (dev_status & 0x801) == 0) /* door open and drive empty bits */
      return 1;
    return 0;
  }
***************
*** 473,478 ****
--- 503,513 ----
        cds_address_offset = 0x17;
        cds_elsize = 0x51;
      }
+   else if (true_dos_version == 0x0332) /* NT */
+     {
+       cds_address_offset = 0x16;
+       cds_elsize = 0x47;
+     }
    else
      {
        cds_address_offset = 0x16;
***************
*** 597,609 ****
           These are used in the above order.  */
  
        /* See what 2160 can tell us.  If it fails, there ain't no such
!          drive, as far as DOS is concerned.  */
        truename_result = _truename(drive_string, mnt_fsname);
  
        /* Get some info from the DOS Current Directory Structure (CDS).
!          We've already hit the disk with _truename(), so CDS now
!          contains valid and up to date data.  */
!       if (drive_number <= cds_drives)
          cds_flags = get_cds_entry(drive_number, cds_path);
  
        if (truename_result != NULL)
--- 632,651 ----
           These are used in the above order.  */
  
        /* See what 2160 can tell us.  If it fails, there ain't no such
!          drive, as far as DOS is concerned.  Some DOS clones, like NT,
! 	 don't always upcase the drive letter, so we must do that here.  */
        truename_result = _truename(drive_string, mnt_fsname);
+       if (truename_result && mnt_fsname[0]
+ 	  && mnt_fsname[1] == ':' && islower(mnt_fsname[0]))
+ 	mnt_fsname[0] = toupper(mnt_fsname[0]);
  
        /* Get some info from the DOS Current Directory Structure (CDS).
! 	 We've already hit the disk with _truename(), so CDS now
! 	 contains valid and up to date data.  Don't look at the CDS
! 	 for remote drives: they can't be JOINed anyway, and some
! 	 DOS clones, such as NT, don't put them into the CDS.  */
!       if (drive_number <= cds_drives
! 	  && !_is_remote_drive (drive_number - 1))
          cds_flags = get_cds_entry(drive_number, cds_path);
  
        if (truename_result != NULL)
***************
*** 631,644 ****
                if (is_ram_drive(drive_number))
                  mnt_type = NAME_ram;
                else if (is_cdrom_drive(drive_number))
!                 {
!                   /* Empty CD-ROM drives do NOT fail _truename(),
!                      so we must see if there is a disk in the drive.  */
!                   if (cdrom_drive_ready(drive_number))
!                     mnt_type = NAME_cdrom;
!                   else
!                     continue;           /* don't report this drive */
!                 }
                /* _is_remote_drive() needs zero-based disk number  */
                else if (_is_remote_drive(drive_number - 1) == 1)
                  mnt_type = NAME_net;
--- 673,686 ----
                if (is_ram_drive(drive_number))
                  mnt_type = NAME_ram;
                else if (is_cdrom_drive(drive_number))
! 		{
! 		  /* Empty CD-ROM drives do NOT fail _truename(),
! 		     so we must see if there is a disk in the drive.  */
! 		  if (cdrom_drive_ready(drive_number))
! 		    mnt_type = NAME_cdrom;
! 		  else
! 		    continue;
! 		}
                /* _is_remote_drive() needs zero-based disk number  */
                else if (_is_remote_drive(drive_number - 1) == 1)
                  mnt_type = NAME_net;
***************
*** 696,706 ****
  
        /* Some network redirectors don't set a UNC path to be
           returned by _truename().  See if 215F02 can help.  */
!       if ((!got_fsname || mnt_fsname[0] != '\\') &&
!            strcmp(mnt_type, "net") == 0)
          if (get_netredir_entry(drive_number))
            got_fsname = 1;
!       if (!got_fsname || strcmp(mnt_type, "cdrom") == 0)
          {
            /* Look for the volume label.  */
            int e = errno;
--- 738,749 ----
  
        /* Some network redirectors don't set a UNC path to be
           returned by _truename().  See if 215F02 can help.  */
!       if ((!got_fsname || mnt_fsname[0] != '\\') && mnt_type == NAME_net)
          if (get_netredir_entry(drive_number))
            got_fsname = 1;
!       /* MSCDEX makes `_truename' return a dull "\\X.\A.", so
! 	 try to get the label anyway.  */
!       if (!got_fsname || mnt_type == NAME_cdrom)
          {
            /* Look for the volume label.  */
            int e = errno;
***************
*** 724,732 ****
  
                got_fsname = 1;
              }
! 
            else if (errno == ENMFILE || errno == ENOENT)
              {
                /* Valid drive, but no label.  Construct default
                   filesystem name.  If drive A: is mapped to B:,
                   call it ``Drive A:''.  */
--- 767,795 ----
  
                got_fsname = 1;
              }
! 	  /* CD-ROM without a label is taken as an empty CD drive or an
! 	     audio disk, and not reported.  This is because MSCDEX doesn't
! 	     fail `_truename' for these cases and some DOS clones, such as
! 	     NT, don't even emulate the drive empty bit reliably.
! 	     I have never seen a CD-ROM without a label.  Anybody?  */
! 	  else if (mnt_type == NAME_cdrom)
! 	    got_fsname = 0;
            else if (errno == ENMFILE || errno == ENOENT)
              {
+ 	      /* Some device drivers for removable media (like JAZ on NT DOS
+ 		 box) pass all above tests when the drive is empty.  Force
+ 		 them to hit the disk with DOS Get Free Disk Space function,
+ 		 and if that fails, treat that drive as non-existing.  */
+ 	      if (mnt_type == NAME_fd)
+ 		{
+ 		  __dpmi_regs r;
+ 
+ 		  r.h.ah = 0x36;
+ 		  r.h.dl = drive_number;
+ 		  __dpmi_int(0x21, &r);
+ 		  if ( (r.x.ax & 0xffff) == 0xffff ) /* aha! an impostor! */
+ 		    continue;
+ 		}
                /* Valid drive, but no label.  Construct default
                   filesystem name.  If drive A: is mapped to B:,
                   call it ``Drive A:''.  */
***************
*** 763,776 ****
            mntent.mnt_opts   = dev_opts;
  
            /* Make CD-ROM drives read-only, others read-write.  */
!           if (strcmp(mnt_type, "cdrom") == 0)
              dev_opts[1] = 'o';
            else
              dev_opts[1] = 'w';
  
            /* Include "dev=XX" in the mnt_opts field, where XX should
               be consistent with what stat() returns in st_dev.  */
!           sprintf(xdrive, "%02x", strcmp(mnt_type, "subst")
                                    ? drive_number - 1
                                    : mnt_fsname[0] - 'A');
            dev_opts[7] = xdrive[0];
--- 826,839 ----
            mntent.mnt_opts   = dev_opts;
  
            /* Make CD-ROM drives read-only, others read-write.  */
!           if (mnt_type == NAME_cdrom)
              dev_opts[1] = 'o';
            else
              dev_opts[1] = 'w';
  
            /* Include "dev=XX" in the mnt_opts field, where XX should
               be consistent with what stat() returns in st_dev.  */
!           sprintf(xdrive, "%02x", mnt_type != NAME_subst
                                    ? drive_number - 1
                                    : mnt_fsname[0] - 'A');
            dev_opts[7] = xdrive[0];


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019