/* 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);
}