/*
 *  This program gives you information about the disks that you have
 *  connected to the system.
 *
 *  This program is written for the public domain and is freely
 *  distributable as long as credit is given to the author.  I would
 *  like to thank Michael L. Hitch for his "AutoTest" program which
 *  provided much insight for this program.
 *
 *  Written by: Rick Manazir
 *  Date: 01/06/89
 *
 *
 *                      MODIFICATION HISTORY
 *
 *     Date      Author                   Change Description
 *   ========   ========     ============================================
 *   01/06/89     RMM        Original issue
 *
 */

#ifndef OBSOLETE_LIBRARIES_DOS_H
#define OBSOLETE_LIBRARIES_DOS_H
#endif

#include <dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

extern struct DosLibrary *DOSBase;

char name[80];
char *disk_name_ptr;

void get_device_info();
void quit(), cleanup();

void main(argc, argv)
int argc;
char *argv[];
{
   disk_name_ptr = argv[1];
   if (argc < 2)
   {
      printf("Drive name: ");
      fgets(name, 80,stdin);
      disk_name_ptr = name;
      while (*disk_name_ptr && *disk_name_ptr != '\n')
         ++disk_name_ptr;
      *disk_name_ptr = 0;
      disk_name_ptr = name;
   }
   printf("\n\x1b[32mGetting data on disk %s\x1b[0m\n",disk_name_ptr);
   get_device_info(disk_name_ptr);
   cleanup();
}

void get_device_info(disk_drive)
char *disk_drive;
{
   struct RootNode *root;
   struct DosInfo *info;
   struct DeviceNode *device;
   struct InfoData *disk_info;
   struct FileSysStartupMsg *startup_msg;
   
   long lock;
   unsigned long *env_ptr;
   unsigned sectors_free, total_sectors, per_cent_used;
      
   /* Get the driver names from the device list. */
   root = (struct RootNode *) DOSBase -> dl_Root;
   info = (struct DosInfo *) BADDR (root -> rn_Info);
   device = (struct DeviceNode *) BADDR (info -> di_DevInfo);
   /* Find the device requested. */
   while (device)
   {
      if (device -> dn_Type == DLT_DEVICE)
      {
         if (match (disk_drive, BADDR (device -> dn_Name) + 1) == 0) break;
      }
      device = (struct DeviceNode *) BADDR (device -> dn_Next);
   }
   lock = Lock (disk_drive, ACCESS_READ);
   if (device == 0 || lock == 0)
   {
      printf("Device %s was not found.\n",disk_drive);
      quit(1);
   }
   disk_info = (struct InfoData *) malloc (sizeof (struct InfoData));
   if (disk_info != NULL)
   {
      if (Info(lock, disk_info) == 0)
      {
         UnLock(lock);
      }
   }
   printf("\x1b[33mData for drive %s is:\x1b[0m\n",disk_drive);
   printf("Unit Number: %d\n",disk_info -> id_UnitNumber);
   printf("Number of soft errors: %d\n",disk_info -> id_NumSoftErrors);
   switch (disk_info -> id_DiskState)
   {
      case ID_WRITE_PROTECTED:
         printf("Disk State: Write Protected.\n");
         break;
      case ID_VALIDATING:
         printf("Disk State: Currently being validated.\n");
	 break;
      case ID_VALIDATED:
         printf("Disk State: Disk is consistent and writeable.\n");
   }
   printf("Number of sectors: %d\n",disk_info -> id_NumBlocks);
   printf("Number of bytes per sector: %d\n",disk_info -> id_BytesPerBlock);
   startup_msg = (struct FileSysStartupMsg *) BADDR (device -> dn_Startup);
   env_ptr = (long *) BADDR (startup_msg -> fssm_Environ);
   sectors_free = disk_info -> id_NumBlocks - disk_info -> id_NumBlocksUsed;
   total_sectors = (env_ptr[DE_UPPERCYL] - env_ptr[DE_LOWCYL] + 1) * env_ptr[DE_NUMHEADS] * env_ptr[DE_BLKSPERTRACK];
   per_cent_used = ((total_sectors - sectors_free) * 100) / total_sectors;
   printf("Number of sectors used %d\n",disk_info -> id_NumBlocksUsed);
   printf("Number of free sectors: %d\n",sectors_free);
   printf("Total number of sectors: %d\n",total_sectors);
   printf("Per Cent of sectors used: %d\n",per_cent_used);
   printf("Number of heads is: %d\n",env_ptr[DE_NUMHEADS]);
   printf("Number of sectors per track: %d\n",env_ptr[DE_BLKSPERTRACK]);
   printf("Number of DOS reserved sectors: %d\n",env_ptr[DE_RESERVEDBLKS]);
   printf("Disk interleave: %d\n",env_ptr[DE_INTERLEAVE]);
   printf("Low cylinder: %d\n",env_ptr[DE_LOWCYL]);
   printf("High cylinder: %d\n",env_ptr[DE_UPPERCYL]);
   printf("Number of DOS buffers: %d\n",env_ptr[DE_NUMBUFFERS]);
   switch (env_ptr[DE_DOSTYPE])
   {
      case 0x4E952341: /* This number is incorrect in the Lattice manual. */
         printf("The old slow file system.\n\n");
	 break;
      case 0x444F5301:
         printf("The new fast file system.\n\n");
	 break;
      default:
         printf("An unknown file system.\n\n");
   }
   if (lock) UnLock(lock);
}
  
int match(string1, string2)
register char *string1, *string2;
{
   register char c;
   
   while ((c = toupper (*string1++)) == toupper (*string2++))
      if (c == 0) return(0);
   if (c == ':' && !*--string2) return(0);
   return(1);
}

void cleanup()
{
   rbrk();
}

void quit(code)
int code;
{
   exit(code);
}

