/* CheckDrive 1.6 © Johan Eliasson 1992             *
 * To be compiled with SAS C (any version, I think) *
 * > lc -L CheckDrive.c will do.                    */

#include <stdio.h>
#include <stdlib.h> 
#include <string.h>
#include <ctype.h>
#include <devices/trackdisk.h>

#include <BBBF.h>
#include <BBBF_pragmas.h>
#include <BBBF_protos.h>

#include "CheckDrive_protos.h"

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>

#define VERNO   "1.6"
#define VERDATE "(25.04.93)"

#define HELLO   "CheckDrive "VERNO" © Johan Eliasson 1992,1993\n"
#define USAGE   "Usage: CheckDrive <drive>\ndrive = the drive you want to check\n"

UBYTE *VersionString = "$VER: CheckDrive "VERNO" "VERDATE;

extern struct DOSBase *DOSBase;

struct Library *BootblockBase = NULL;

struct Bootblock *BB;

ULONG chip boot[256];   /* Must be in CHIP if OS 1.3  */
ULONG      drive;       /* unit number of drive       */
USHORT     virus;       /* amount of recognized virii */
char       string[80];  /* general string for output  */
char       version[30]; /* brainfile version string   */
long       retcode;     /* for CheckBoot()            */
long       readerror;

/* ****************************** main() ****************** */

void main(int argc,char *argv[])
{
  if ((argc == 1) || (argv[1][0] == '?'))
    die(USAGE);

  out(HELLO);

  /* ***************** Open Bootblock.library ************* */

  if (!(BootblockBase = (struct Library *) OpenLibrary("Bootblock.library",1)))
    die("\nCheckDrive needs the bootblock.library v1.0+ !");

  /* ****************** Read brainfile ******************* */

  out("Reading Bootblock.brainfile...");

  readerror = ReadBBBF("L:Bootblock.brainfile");

  if (readerror == ERROR_OBJECT_NOT_FOUND) readerror = ReadBBBF("Bootblock.brainfile");

  /* ****************** Check result************************** */

  switch (readerror)
  {
    case BBBF_LOADED            : out("Ok!\n\n"); break;
    case BBBF_ALREADY_LOADED    : out("\n\nThe brainfile was already loaded!\n"); break;

    case BBBF_NOT_BBBF          : die("\n\nIt is not a Bootblock.brainfile!\n");
    case BBBF_CHECKSUM_ERROR    : die("\n\nThe Bootblock.brainfile is corrupted!\n");
    case BBBF_OUT_OF_MEMORY     : die("\n\nNo memory for brainfile!\n");
    case ERROR_OBJECT_NOT_FOUND : die("\n\nCan't find the Bootblock.brainfile!\n");
    default                     : die("\n\nSomething went wrong...\n");
  };

  /* ***************** Get additional info **************** */

  if (GetBBBFInfo(&virus,version) == BBBF_NOT_LOADED)
    die("The brainfile is not loaded!");

  /* ************************ Output info ********************** */

  sprintf(string,"Brainfile version %s.\nKnows %d viruses.\n\n",version,virus);
  out(string);

  /* ************************ Prepare for boot-read ***************** */

  if ((toupper(argv[1][0]) == 'D') && (toupper(argv[1][1]) == 'F'))
    drive = atol((char *) &argv[1][2]); /* CheckDrive dfx: */
  else drive = atol(argv[1]);           /* CheckDrive x    */

  /* ********************** Read boot ***************************** */

  if (readerror = ReadBoot(drive,(char *) boot))
    tderror(readerror);

  /* ********************** Check boot ************************** */

  BB = (struct Bootblock *) CheckBoot(boot,&retcode);

  switch (retcode)
  {
    case BBBF_NOT_LOADED : die("Brainfile is not loaded!");
    case BOOT_VIRUS      : sprintf(string,"WARNING! The disk in DF%d: is infected with the \'%s\' virus!\n",drive,BB->bootname);
                           die(string);
    case BOOT_UNKNOWN    : sprintf(string,"The disk in DF%d: is not infected with any known bootvirus!\n",drive);
                           die(string);
    case BOOT_NOT_BOOT   : sprintf(string,"The disk in DF%d: is not bootable!\n");
                           die(string);
  }

  die(USAGE);
}

void tderror(long error)
{
  switch (error)
  {
    case TDERR_WriteProt    : die("The disk is writeprotected!\n");
    case TDERR_DiskChanged  : die("There's no disk in the drive!\n");
    case TDERR_BadDriveType : die("That drive is not available!\n");
    case TDERR_BadUnitNum   : die("There's no drive with that number!\n");
    case TDERR_DriveInUse   : die("The drive is busy!\n");
  }

  Fault(error,"Error",string,81);
  die(string);
}

void out(char *string)
{
  Write(Output(),string,strlen(string));
}

void die(char *message)
{
  out(message);
  if (BootblockBase) CloseLibrary(BootblockBase);
  exit(0);
}

