Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. /*
  4.  * This is implementation of getmntent() and friends for DJGPP v2.x.
  5.  *
  6.  * Copyright (c) 1995-96 Eli Zaretskii <eliz@is.elta.co.il>
  7.  *
  8.  * This software may be used freely so long as this copyright notice is
  9.  * left intact.  There is no warranty on this software.
  10.  *
  11.  * ---------------------------------------------------------------------
  12.  *
  13.  * The primary motivation for these functions was the GNU df program,
  14.  * which lists all the mounted filesystems with a summary of the disk
  15.  * space available on each one of them.  However, they are also useful
  16.  * on their own right.
  17.  *
  18.  * Unlike Unix, where all mountable filesystems can be found on special
  19.  * file (and thus implementing these function boils down to reading that
  20.  * file), with MS-DOS it's a mess.  Every type of drive has its own
  21.  * interface; there are JOINed and SUBSTed pseudo-drives and RAM disks;
  22.  * different network redirectors hook DOS in a plethora of incompatible
  23.  * ways; a single drive A: can be mapped to either A: or B:, etc.  That
  24.  * is why this implementation uses almost every trick in the book to get
  25.  * at the intimate details of every drive.  Some places where you might
  26.  * find these tricks are: ``Undocumented DOS, 2nd ed.'' by Schulman et al
  27.  * and Ralf Brown's Interrupt List.
  28.  *
  29.  */
  30. #include <libc/stubs.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <errno.h>
  35. #include <sys/stat.h>
  36. #include <mntent.h>
  37. #include <dir.h>
  38. #include <libc/farptrgs.h>
  39. #include <sys/movedata.h>
  40. #include <libc/unconst.h>
  41. #include <assert.h>
  42.  
  43. /* Macro to convert a segment and an offset to a "far offset" suitable
  44.    for _farxxx() functions of DJGPP.  */
  45. #ifndef MK_FOFF
  46. #define MK_FOFF(s,o) ((int)((((unsigned long)(s)) << 4) + (unsigned short)(o)))
  47. #endif
  48.  
  49. #define CDS_JOIN     0x2000
  50. #define CDS_VALID    0xc000
  51. #define REMOVABLE    0
  52. #define FIXED        1
  53.  
  54. /* Static variables.  */
  55.  
  56. static char          drive_number = -1;
  57. static char          skip_drive_b = 0;
  58. static char          drive_a_mapping = 0;
  59. static char          cds_drives   = 0;
  60. static unsigned long cds_address;
  61. static int           cds_elsize;
  62. static unsigned short dos_mem_base, our_mem_base;
  63. static struct mntent mntent;
  64. static unsigned char drive_string[128];
  65. static char          *mnt_type;
  66. static unsigned char mnt_dir[128];
  67. static unsigned char mnt_fsname[128];
  68. static          char dev_opts[] = "r ,dev=  ";
  69.  
  70. static char NAME_dblsp[] = "dblsp";
  71. static char NAME_stac[] = "stac";
  72. static char NAME_ram[] = "ram";
  73. static char NAME_cdrom[] = "cdrom";
  74. static char NAME_net[] = "net";
  75. static char NAME_fd[] = "fd";
  76. static char NAME_hd[] = "hd";
  77. static char NAME_subst[] = "subst";
  78. static char NAME_join[] = "join";
  79.  
  80. int _is_remote_drive(int);
  81.  
  82. /* Static helper functions.  */
  83.  
  84. /*
  85.  * Get the entry for this disk in the DOS Current Directory Structure
  86.  * (CDS).  In case of success, return this drive's attribute word; or
  87.  * 0 in case of failure.  Fill the buffer at CURRDIR with the current
  88.  * directory on that drive.
  89.  * The pointer to the CDS array and the size of the array element
  90.  * (which are DOS version-dependent) are computed when setmntent() is
  91.  * called.
  92.  */
  93. static int
  94. get_cds_entry(int drive_num, char *currdir)
  95. {
  96.   unsigned long  cds_entry_address;
  97.   if (!cds_address)
  98.     {
  99.       *currdir = '\0';
  100.       return 0;
  101.     }
  102.  
  103.   /* The address of the CDS element for this drive.  */
  104.   cds_entry_address = cds_address + (drive_num - 1)*cds_elsize;
  105.  
  106.   /* The current directory: 67-byte ASCIIZ string at the beginning
  107.      of the CDS structure for our drive.  */
  108.   movedata(dos_mem_base, (cds_entry_address & 0xfffff),
  109.            our_mem_base, (unsigned int)currdir, 0x43);
  110.  
  111.   /* The drive attribute word is at the offset 43h, right after the
  112.      current directory string.  */
  113.   return _farpeekw(dos_mem_base, cds_entry_address + 0x43);
  114. }
  115.  
  116. /*
  117.  * For a PC with a single floppy drive, that drive can be referenced
  118.  * as both A: and B:.  This function returns the logical drive number
  119.  * which was last used to reference a physical drive, or 0 if the
  120.  * drive has only one logical drive assigned to it (which means there
  121.  * are two floppies in this system).
  122.  */
  123. static int assigned_to(int drive_num)
  124. {
  125.  return drive_num;
  126. }
  127.  
  128. /*
  129.  * Check if the drive is compressed with DoubleSpace.  If it is,
  130.  * get the host drive on which the Compressed Volume File (CVF)
  131.  * resides, put the name of that CVF into MNT_FSNAME[] and return
  132.  * non-zero.
  133.  */
  134. static int get_doublespace_info(int drive_num)
  135. {
  136.  return 0;
  137. }
  138.  
  139. static int get_stacker_info(int drive_num)
  140. {
  141.  return 0;
  142. }
  143.  
  144. /*
  145.  * Get the network name which corresponds to a drive DRIVE_NUM.
  146.  * Ideally, _truename() (Int 21h/AH=60h) should return the same
  147.  * string, but some network redirectors don't put a full UNC
  148.  * name into the CDS, and others bypass the CDS altogether.
  149.  */
  150. static int get_netredir_entry(int drive_num)
  151. {
  152.  return 0;
  153. }
  154.  
  155. /*
  156.  * Return 1 if this drive is a CD-ROM drive, 0 otherwise.  Works
  157.  * with MSCDEX 2.x, but what about other CD-ROM device drivers?
  158.  */
  159. static int is_cdrom_drive(int drive_num)
  160. {
  161.   return 0;
  162. }
  163.  
  164. /*
  165.  * Return 1 if a CD-ROM drive DRIVE_NUM is ready, i.e. there is a
  166.  * disk in the drive and that disk is a data (not AUDIO) disk.
  167.  */
  168. static int cdrom_drive_ready(int drive_num)
  169. {
  170.   return 0;
  171. }
  172.  
  173. /*
  174.  * Detect a RAM disk.  We do this by checking if the number of FAT
  175.  * copies (in the Device Parameter Block) is 1, which is typical of
  176.  * RAM disks.  [This doesn't _have_ to be so, but if it's good
  177.  * enough for Andrew Schulman et al (Undocumented DOS, 2nd edition),
  178.  * we can use this as well.]
  179.  */
  180. static int is_ram_drive(int drive_num)
  181. {
  182.  return -1;
  183. }
  184.  
  185. /*
  186.  * Check if the media in this disk drive is fixed or removable.
  187.  * Should only be called after we're sure this ain't CD-ROM or
  188.  * RAM disk, since these might fool you with this call.
  189.  */
  190. static int media_type(int drive_num)
  191. {
  192.  return 0;
  193. }
  194.  
  195. /* Exported library functions.  */
  196.  
  197. FILE * setmntent(char *filename, char *type)
  198. {
  199.  return NULL;
  200. }
  201.  
  202. static char NAME_unknown[] = "???";
  203. struct mntent * getmntent(FILE *filep)
  204. {
  205.  mntent.mnt_fsname = "FAT";
  206.  mntent.mnt_dir    = "/";
  207.  mntent.mnt_freq   = -1;
  208.  mntent.mnt_passno = -1;
  209.  mntent.mnt_time   = -1;
  210. }
  211.  
  212. int addmntent(FILE *filep, struct mntent *mnt)
  213. {
  214.  unimpl();
  215. }
  216.  
  217. char * hasmntopt(struct mntent *mnt, char *opt)
  218. {
  219.   return strstr(mnt->mnt_opts, opt);
  220. }
  221.  
  222. int endmntent(FILE *filep)
  223. {
  224.   if (filep != (FILE *)1)
  225.     {
  226.       errno = EBADF;    /* fake errno for invalid handle */
  227.       return NULL;
  228.     }
  229.   drive_number = 0;
  230.   skip_drive_b = 0;
  231.   return 1;
  232. }
  233.