/********** MIRROR.C **********/				/* :ts=8 */


/* This simple tool changes the directory worked in:
   It searches for the same directory on 'the' alternate drive.
   This way, two drives can be used where one holds programs and the
   other holds data, but always in the same tree structure.
   Normally, if a part of the structure misses, the closest available
   parent is chosen. In CREATEive mode, the program will act differently 
   by creating the directory on the destination side.
*/



#include <stdio.h>
#include <exec/types.h>
#include <libraries/dos.h>
#include <pragmas/dos_lib.h>
#include <clib/dos_protos.h>


typedef BPTR LOCK;


int Bstrcmp (char *b1, char *b2)
 {
   int i=1+*b1;
   while (i--)
      if (*b1++ != *b2++)
         return 1;
   return 0;
 }

int Mirror (LOCK fl, LOCK from, LOCK to, int crea)
 {
   LOCK pl=(fl==0L)? 0L: ParentDir (fl);

   if (pl==0L)	/* Recursion ends, and fl is volume name */
    {
      UnLock (CurrentDir (to));
      UnLock (from);
      UnLock (fl);
      return 0;		/* Still exactly the same */
    }
   else
    {
      static struct FileInfoBlock fib;

      if (Mirror (pl, from, to, crea))
         return 1;	/* Not the same anymore */
      Examine (fl, &fib);
      UnLock (fl);
      if (fl=Lock (fib.fib_FileName, ACCESS_READ))
       {
         UnLock (CurrentDir (fl));
	 return 0;	/* Still exactly the same */
       }
      else
         if (crea)
	  {
	    fl=CreateDir (fib.fib_FileName);
	    if (fl)
	     {
	       UnLock (fl);	/* It's exclusive */
	       if (fl=Lock (fib.fib_FileName, ACCESS_READ))
	        {
		  UnLock (CurrentDir (fl));
		  return 0;	/* Still exactly the same */
		}
	       else
	        {
		  fputs ("Mirror: New directory disappeared\n", stderr);
		  exit (1);
		}
	     }
	    else
	     {
	       fputs ("Mirror: Failed to create directory\n", stderr);
	       exit (1);
	     }
	  }
	 else
	  {
	    return 1;	/* Difference came up */
	  }
    }
 }

void main (int argc, char *argv [])
 {
   int crea=(argc==4), err=0;

   if (argc<3)
    {
      fputs ("Mirror: Enter two arguments for disknames.\n"
      "\tA third word being CREATE on the line causes creative mode.\n", stderr);
      err=1;
    }
   if (argc>4)
    {
      fputs ("Mirror: Too many arguments: Enter two disks and "
      		"optional CREATE\n", stderr);
      err=1;
    }
   if (!err)
    {
      LOCK fl, fl1, fl2, from, to;
      static struct InfoData id, id1;

      if (fl=Lock ("", ACCESS_READ))
       {
         if (fl1=Lock (argv [1], ACCESS_READ))
	  {
	    if (fl2=Lock (argv [2], ACCESS_READ))
	     {
	       Info (fl,  &id );
	       Info (fl1, &id1);
/*	       if (Bstrcmp (BADDR(id.id_VolumeNode), BADDR(id1.id_VolumeNode)))
*/
	       if (id.id_VolumeNode!=id1.id_VolumeNode)
	       				/* if TRUE: CurDrv!=FirstDrv */
		{ from=fl2; to=fl1; }	/* GOTO FirstDrv */
	       else
	        { from=fl1; to=fl2; }	/* GOTO SecondDrv */
	       if (Mirror (fl, from, to, crea))
	          fputs ("Mirror: No exact matching of directories\n",
		  				stderr);
	       fl=fl1=fl2=0L;
	     }
	    else fputs ("Cannot Lock second drive\n", stderr);
	    if (fl1) UnLock (fl1);
	  }
	 else fputs ("Cannot Lock first drive\n", stderr);
	 if (fl) UnLock (fl);
       }
      else fputs ("Cannot Lock current directory\n", stderr);
    }
 }
