/* gccPj003_2.c */
/* = Kdo.c + gccPj003.c  */
/* Originally, 5Diff.3.c  */
/* 3Diff  -  executable file posted   */
/* History:   The same as the other;  PC -> Classic Mac -> ApGCC-3.3.  */

/*  (2005-03-29)  Now, I am getting into Kdo_0[1-4].c codes.   
 *  The file pointer "Stream" is local within OpenAnyFile 
 *  subroutine, and it is renamed in main.c as the file pointer "file".
 *
 *  It was originally, 
 *   main (int argc, char **argv){
 *       file = OpenAnyFile (agrv[1]);
 *   }
 *  to take the argv[1] as the user's input file name.   I only 
 *  need to get the user's fixed filename "HEADER.TXT" or 
 *  "header.txt" so on, thus, it becomes here, 
 *       file = OpenAnyFile ("Header.Txt");
 *  And this works well. 
 */
/*  (2005-03-30)  I finished the rearragement of Kdo codes, 
 *  main(), and two Subroutines OpenAnyFile() and strupr(),
 *  so it is the time to import the whole gccpj001.c into the 
 *  main().
 */
/* (2005-03-15)   Regarding ABSOLUTE and RELATIVE:
 *    Batch.txt          ->  ABSOLUTE is better, then I can use CD, DVD.
 *    /Erased/;  /DIFF/  ->  RELATIVE is better, because flexible.
 */
/* (2005-04-12)   I didn't see *infpOUT was used.  Instead *outfp 
 *    was used.  Probably passed down from a PC version which needed
 *    to read a different "Out-Head.txt" in addition to "Header.txt".
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>

char lineSDW [256];
char lineNET [256];

char FNToOpen [64];  /* = filenamesToOpen */
char openedFN [64];  /* = opendFilename */
char openedSDW_FNP [64], openedNET_FNP [64];   
/* = openedSDW_FilenameWithPath,  = openedNET_FilenameWithPath */
char writingFile [64];

/* Two lines are Kdo.c; One line is gccPj003.c  */
FILE *OpenAnyFile (char *FileName);
void *strupr (void *buffer);  
extern char *spacedwd (char *to, char *from);    
/* = spaced words, to capture blank-containing foldername */

main ()
{
  int lengthSDW, iFlag, iSDW, iNET;           
  /* iFlag is counting output lines in a file to see which folders */ 
  /*   doesn't change. */

  FILE *file;
  FILE *infpSDW;      /* These Pointers read fileNames list */
  FILE *infp1, *infp2, *outfp, *outfp2;   
  /* infp1->SDW_files;     infp2->NET_files;                        */
  /* outfp->Diff_Output;   outfp2->Grand_Summary                    */
  /* infpSDW reads Foldernames at 'HEADER.TXT' to compare the two   */
  /*   files contents                                               */


  infpSDW = OpenAnyFile ("header.txt");
  if (infpSDW)
     printf ("\nReading Header.txt...\n");
  else{
       exit (0);
    }


  outfp2=fopen("Grand_Summary.txt", "w");


/* ************ Start Import ********** */

    
    printf("\n\n\nMaking final reports at each folder level at /DIFF/.\n");
    printf("From the size of each report file, you can estimate which folder \n");
    printf("likely have a big change.  No change folder appears as 2 lines.\n");
    printf("Any file change should appear.\n\n");
    printf("The mechanism of this \'diff\' report is based on reading two files \n");
    printf("at the same time from top of both files.  So, in case there is a \n");
    printf("line shift near the top, then all lines followed are reported. \n");
    printf("So, in a sense, this is not a sophisticated program, but just to \n");
    printf("quickly review whether any change is there at given folders. \n");
    printf("The good thing is that you always have the Master NET disk safely.\n");
    printf("And this dual way is somehow different from backup-&-restoration. \n\n");
    printf("\"Grand_Summary.txt\" is included for a quick review.\n\n\n");
    
    iFlag=iSDW=iNET=0;

/*  Read all lines in "Header.txt" as filenames to be opened.  */
	while( (fgets(FNToOpen, 64, infpSDW))!=NULL )
	{
	    spacedwd (openedFN, &FNToOpen[0]);    
             /* Opening filename, one-by-one */
	    
	    sprintf (openedSDW_FNP, "./SDW/Erased/%s.txt", openedFN);
	    sprintf (openedNET_FNP, "./NET/Erased/%s.txt", openedFN);
	    sprintf (writingFile,   "DIFF/%s.txt",       openedFN);
	   
	    infp1=fopen(openedSDW_FNP, "r");
	    infp2=fopen(openedNET_FNP, "r");
	    outfp=fopen(writingFile, "w");
	    lengthSDW=iFlag=0;
	
	    /* Reading both lines from two files simultaneously, the pair */
		while( (fgets(lineSDW, 256, infp1))!=NULL && (fgets(lineNET, 256, infp2))!=NULL ){     
		   lengthSDW = strlen(lineSDW);
		   if ( strncmp(lineSDW, lineNET, (lengthSDW-1) )==0 )
		      ;
		   else{     /* reporting difference */
		       fprintf (outfp, "SDW:%s", lineSDW);
		       fprintf (outfp, "NET:%s", lineNET);
		       iFlag++;          /* Counter for Grand_Summary.Txt */
           }
        }     /* closing Two Lines Comparison WHILE-LOOP */
        
        /* In case NET Catalog is longer */
        if(infp2!=NULL){
           while( (fgets(lineNET, 256, infp2))!=NULL ){
              fprintf(outfp, "NET: %s", lineNET);
		      iFlag++; iNET++;
           }
        }
        *lineNET=0;
           
        /* In case SDW Catalog is longer */
        if(infp1!=NULL){
           while( (fgets(lineSDW, 256, infp1))!=NULL ){
              fprintf(outfp, "SDW: %s", lineSDW);
		      iFlag++; iSDW++;
           }
        }
        *lineSDW=0;

        /* Since iFlag counter is still counting up when either catalog */
        /*   is longer, so, the following Grand_Sum.Txt must be after   */
        /*   them.                      */
        /* The Grand Summary report only needs to know iFlag count for  */
        /*   each one set of comparison. */
        if (iFlag==1) 
           fprintf (outfp2, "  No change at :  %s\n", openedFN);
        else if ( iFlag>=1 && iSDW==0 && iNET==0 ){    
           fprintf (outfp2, "  May be O.K.  :  - %s\n", openedFN);
        }else 
           fprintf (outfp2, "  Watch out at :  ****  %s\n", openedFN);
        
        iFlag=iSDW=iNET=0;  /* Reset, in case */

        *FNToOpen=*openedFN=0;   /* Reset, in case */
        *openedSDW_FNP=0;
        *openedNET_FNP=0;
        fclose (infp1);
        fclose (infp2);
        fclose (outfp);
    }   /* closing, filenames opened by While-loop */
    fclose (infpSDW);
}


/* ************ END Import *********** */



/* Here are two SUBROUTINEs by Kdo. */
/* ******************************** */

// FILE *OpenAnyFile (char *FileName);
// void *strupr (void *buffer);   

/* Find any file with same spelling regardless of capitalization */
/* Return a stream to the file, opened for read access           */

FILE *OpenAnyFile (char *FileName) 
{
  DIR *Dir;
  struct dirent *DirEnt;
  char *Target;
  char *Temp;
  FILE *Stream = NULL;

  Target = strdup (FileName);   // make an upper case version of the name.
  strupr (Target);

   Dir = opendir (".");  /* any suitable directory name  */

  while (DirEnt = readdir (Dir))
  {
    Temp = strdup (DirEnt->d_name);
    strupr (Temp); // convert the found name to upper case
    if (strcmp (Temp, Target) == 0)  // names match
    {
      Stream = fopen (DirEnt->d_name, "r");   // open the file for read

      free (Temp);
      break;
    }
    free (Temp);
  }
  free (Target);
  closedir (Dir);
  return (Stream);
}


/*  strupr() isn't universal.  You can make one very easily. */
/*  Pass void so you can pass either char or unsigned char  */
/*    void *strupr (void *buffer);    */  


void *strupr (void *Buffer)
{
  unsigned char *ptr;

  ptr = (unsigned char *)Buffer;
  while (*ptr)
  {
    if (*ptr >= 'a' && *ptr <= 'z')
      *(ptr++) = (*ptr) - 'a' + 'A';
    else
      ptr++;
  }
  return (Buffer);
}