/*
             CREATOR: DAn williams
                DATE: apr 10 2001
         DESCRIPTION: equivilent of the perl "file processor" skel
            FILENAME: fileprocessor-incl.c
             STARTED: apr 10 2001
           PLATFORMS: windows
1st VERSION FINISHED:

*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <dirent.h> // opendir, readdir, closedir
#include <sys/stat.h> // stat

#include "CRC32.c" // code for calcing crc's 

//global variables

void usage(int argc, char** argv);
int file_search(char * filldir);
int process_init();
int process_cleanup ();
int file_op (char * long_filename);
int pre_enter_dir_op (char * long_filename);
int post_enter_dir_op (char * long_filename);

FILE *OUTPUT;
unsigned long fileCount;

//char * dir_sep = "\\"; // windows
//char * dir_sep = ":";  // mac
char * dir_sep = "/";    // GNU

char * work_dir;
int verbosity = 0; // how much to talk about whats going on

int main (int argc, char** argv) {
  //int example_main (int argc, char** argv) {

  if (argc < 2) {
   usage(argc, argv);
   return 1;
  }

  work_dir = argv[1];  

  // initialize data stuff
  process_init();
  // do work
  file_search(work_dir);
  // clean up
  process_cleanup();

  return 0;
}

//------------------------------- SUBROUTINES ----------------------------------

int file_search (char * filldir) {
  
  DIR *ACTDIR;
  struct dirent *filetmp;
  struct stat statbuf;
  char * file;

  file = NULL;

  if (verbosity > 0) { 
    printf ("searching %s \n", filldir);
  }

  if (ACTDIR = opendir(filldir)) {
    if (verbosity > 1) { printf ("Opendir successfull...\n"); }
    while ((filetmp = readdir(ACTDIR)) != NULL) {
    
      if ((strcmp(".", filetmp->d_name)!=0) && (strcmp("..", filetmp->d_name)!=0)) { 
	// append the 3 strings
	if (file != NULL) { free(file); }
	if ((file = malloc ((6+strlen(filldir)+strlen(dir_sep)+strlen(filetmp->d_name))*sizeof(char))) != NULL) {
	  sprintf( file, "%s%s%s", filldir, dir_sep, filetmp->d_name);
	} else {
	  printf ("A really bad thing happened.(out of memmory)\n");
	  return; // dont exit, this is recursive
	}
	
	if (stat(file, &statbuf) != (-1)) {
	  if (statbuf.st_mode & S_IFDIR) {
	    // its a directory
	    if (verbosity > 0) { printf ("seeing directory %s \n", file); }
	    pre_enter_dir_op(file);
	    file_search(file);
	    post_enter_dir_op(file);
	  } else {
	    // its a file
	    if (verbosity > 0) { printf ("seeing file      %s \n", file); }
	    file_op(file);
	  } // end of IFDIR
	}   // end of if stat <> -1
      }     // end of not . or ..
    }     // end of while
  } else {
    if (verbosity > 0) { printf ("opendir failed\n"); }
  }       // end of opendir
  
  closedir(ACTDIR);
 
}


//------------------------------- USER DEFINED ROUTINES ------------------------


/****
 *
 * Give the user usage assistance
 *
 ***/
void usage(int argc, char** argv) {

 printf ("Usage: %s target-dir\n", argv[0]);
 printf (" Example: %s c:\\windows\n", argv[0]);

}


/****
 *
 * called before start of recursing
 *
 ***/
int process_init() {
 
  if ((OUTPUT = fopen("CRC.txt", "wt")) == NULL) {  //open text file 'param 1' w/ err chk
    printf("Unable to open CRC.txt for output.\n");
    exit (-1);
  }
  
  fprintf( OUTPUT, "Basis Applied Technology, apr 12 2001\n\n");
  fprintf( OUTPUT, "   CRC            path/filename\n");
  fprintf( OUTPUT, "---------         ----------------\n");
  
  fileCount = 0;

 return 0;
}

/****
 *
 * called after recurse is finished
 *
 ***/
int process_cleanup () {
 
 fprintf( OUTPUT, "\n %u files checked.\n", fileCount);

 fclose( OUTPUT );

 return 0;
}

/****
 *
 * This function is called for the files that are found
 * 
 ***/
int file_op (char * long_filename) {

  FILE *input;
  unsigned long crc;
  unsigned char * sadBuffer;
  unsigned int byteCount;

  crc = 0;

  // push a file through the crc code
  // init crc machine
  updcrc(NULL, 0);
  if ((input = fopen(long_filename, "rb")) == NULL) { 
    fprintf(OUTPUT, "Unable to open %s for input.\n", long_filename);
    return -1;
  }

  if ((sadBuffer = malloc ( 65535 )) == NULL) {
    fprintf( OUTPUT, "Out of memmory checking file %s \n", long_filename);
    return -2;
  }
  
  while ((byteCount = fread(sadBuffer, 1, 65535, input)) != 0 ) {
   crc = updcrc(sadBuffer, byteCount);
  }

  free (sadBuffer);
  fprintf( OUTPUT, "%08X %s\n", crc, long_filename );
  fclose( input );

  fileCount ++;

 return 0;
}

/****
 *
 * This subroutine is called before the recursing into a directory
 * a paramiter is passed naming the directory that about to be entered
 *
 ***/
int pre_enter_dir_op (char * long_filename) {

 return 0;
}

/****
 *
 * This Subroutine is called after a recursion out of a directory
 * long_filename is the name of the directory that we came out of
 *
 ****/
int post_enter_dir_op (char * long_filename) {

 return 0;
}







