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