#include <stdio.h>
#include <dos.h>

#define DOS 0x21
#define READ 2
#define CLEAR 0
#define CORRUPT 1
#define DONE 2

main(argc,argv)
int argc;
char *argv[];
   {

   int logged_drive, com1_drive, com2_drive, ret_code;
   int i, j, sector, flag, count1, count2;
   char com1_ver[9], com2_ver[9], buffer1[528], buffer2[528];
   FILE *com1_fp, *com2_fp;

/* if two  args are not specified, print message and quit */
   if(argc != 3) {
      printf("usage: novirus [drive][path]com1 [drive][path]com2\n");
      printf("   where com1 is command processor to be checked\n");
      printf("   com2 is known good command processor\n");
      exit(0);
      }

/* maybe later find out how big sectors are */
   sector = 512;

/* find what drive we're logged to */
   _AH = 0x19;
   geninterrupt(DOS);
   logged_drive = _AL;

   printf("logged drive: %d\n",logged_drive);

/* are drives specified on command line? */
   if(*(argv[1]+1) == ':') com1_drive = *(argv[1]) & 0xDF - 'A' + 1;
   else com1_drive = logged_drive;

   if(*(argv[2]+1) == ':') com2_drive = *(argv[2]) & 0xDF - 'A' + 1;
   else com2_drive = logged_drive;

   printf("drive 1: %d\n",com1_drive);
   printf("drive 2: %d\n",com2_drive);

/* are both drives formatted with same DOS version? */
   if(com1_drive != com2_drive) {
      get_form_ver(com1_drive,com1_ver);
      get_form_ver(com2_drive,com2_ver);
      if(strcmp(com1_ver, com2_ver) != 0) {
         printf("cannot compare two different verions: %s and %s\n",
            com1_ver, com2_ver);
         exit(1);
         }
      }

   com1_fp = fopen(argv[1],"r");
   com2_fp = fopen(argv[2],"r");

   if(com1_fp == 0 || com2_fp == 0) {
      printf("cannot find command processors as specified:\n1: %s\n2: %s\n",
         argv[1],argv[2]);
      exit(3);
      }

   flag = CLEAR;
   j = 0;
   while(flag == CLEAR) {
      j++;
      count2 = fread((void *)buffer1,1,sector,com2_fp);
      count1 = fread((void *)buffer2,1,sector,com1_fp);
      if(count1 != count2) flag = CORRUPT;
      else {
         if(count2 < sector) flag = DONE;
         for(i = 0; i < count2; i++) 
            if(buffer1[i] != buffer2[i]) flag = CORRUPT;
         }
      }

   printf("flag: %d; j: %d\n",flag,j);

   fclose(com2_fp);
   fclose(com1_fp);

   if(flag == CORRUPT) {
      fopen(argv[1],"w");
      fopen(argv[2],"r");
      while((count2 = fread((void *)buffer1,1,sector,com2_fp)) != 0)
         fwrite((void *)buffer1,1,count2,com1_fp);
      fclose(com2_fp);
      fclose(com1_fp);
      printf("%s corrupted, corrected from %s\n",argv[1],argv[2]);
      printf("reboot your computer now\n");
      }
   }

get_form_ver(drive,version)
int drive;
char *version;
   {
   char buffer[528];
   union REGS regs;

   regs.x.ax = drive + 0xff;
   regs.x.cx = 1;
   regs.x.dx = 0;
   regs.x.bx = (int)(&buffer);
   int86(0x25,&regs,&regs);
   _SP += 2;
   if(regs.x.cflag != 0) {
      printf("error accessing drive %c: INT 25h error %xh",
         'A'-1+drive,_doserrno);
      exit(2);
      }
   strncpy(version,buffer+3,8);
   version[8] = 0;
   }
