/* foremost.h
 *
 * This is a work of the US Government. In accordance with 17 USC 105, 
 * copyright protection is not available for any work of the US Government.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#ifndef FOREMOST_H
#define FOREMOST_H
#define FOREMOST_VERSION    "0.69"

#define _USE_LARGEFILE              1
#define _USE_FILEOFFSET64           1
#define _USE_LARGEFILE64            1
#define _LARGEFILE_SOURCE           1
#define _LARGEFILE64_SOURCE         1
#define _FILE_OFFSET_BITS           64

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <limits.h>
#include <dirent.h>
#include <stdarg.h>

#ifdef __OPENBSD
#define __UNIX
#define  strtoull   strtoul
#include <sys/ttycom.h>
#include <sys/param.h>
#endif  /* ifdef __OPENBSD */

#ifdef __LINUX
#define __UNIX
#include <linux/hdreg.h>
#include <libgen.h>
#include <error.h>
#endif  /* ifdef __LINUX */

#ifdef __WIN32
#include <windows.h>
#include <sys/timeb.h>
#define gettimeofday(A,B) QueryPerformanceCounter(A)
#define  strtoull   strtoul
#define ftello   ftell
#define fseeko   fseek
#define sleep    Sleep
#define  snprintf         _snprintf
#define  DIR_TRAIL_CHAR   '\\'
#define  u_int32_t        unsigned long
/* We create macros for the Windows equivalent UNIX functions.
   No worries about lstat to stat; Windows doesn't have symbolic links */
#define lstat(A,B)      stat(A,B)
char *basename(char *path);
extern char *optarg;
extern int optind;
int getopt(int argc, char *const argv[], const char *optstring);

#ifdef __MINGW32__
#define realpath(A,B)    _fullpath(B,A,PATH_MAX)
#endif

#ifdef __CYGWIN32__
#define realpath(A,B) \
  (getenv ("CYGWIN_USE_WIN32_PATHS") \
   ? (cygwin_conv_to_full_win32_path ((A), (B)), B) \
   : realpath ((A), (B)))
#endif
#endif    /* ifdef __WIN32 */

/* For non-glibc systems we need to compute the __progname variable */
#ifdef __GLIBC__
char *__progname;
#else
char *__progname;
void setProgramName(char *s);
#endif  /* ifdef __GLIBC__ */

#ifndef __WIN32
#include <sys/mount.h>
#endif 


#define TRUE   1
#define FALSE  0

#define SEARCHTYPE_FORWARD      0
#define SEARCHTYPE_REVERSE      1
#define SEARCHTYPE_FORWARD_NEXT 2

#define KILOBYTE                  1024
#define MEGABYTE                  1024 * KILOBYTE
#define GIGABYTE                  1024 * MEGABYTE
#define TERABYTE                  1024 * GIGABYTE
#define PETABYTE                  1024 * TERABYTE
#define EXABYTE                   1024 * PETABYTE

/* SIZE_OF_BUFFER represents how much data we read from an image file
   at a time. This value must be divisible by FOREMOST_BLOCK_SIZE for 
   quick mode to work. If it's not, the program will abort with the 
   error message that follows.     */
#define SIZE_OF_BUFFER            10 * MEGABYTE

#define FOREMOST_SIZEOFBUFFER_PANIC_STRING \
"PANIC: There is a serious problem with this copy of foremost.\n"\
"       Please obtain a clean version of this program and try again.\n"\
"       (For programmers, the constant SIZE_OF_BUFFER must be divisible\n"\
"       by FOREMOST_BLOCK_SIZE for quick mode to work correctly.\n"


#define FOREMOST_BLOCK_SIZE           512
#define MAX_STRING_LENGTH            4096
#define MAX_NEEDLES                   254
#define NUM_SEARCH_SPEC_ELEMENTS        6
#define MAX_SUFFIX_LENGTH               8
#define MAX_FILE_TYPES                100


#define FOREMOST_OK                     0
#define FOREMOST_ERROR_NO_SEARCH_SPEC   1

/* When we can't open an image file */
#define FOREMOST_ERROR_FILE_OPEN        2

/* When we can't read an image file */
#define FOREMOST_ERROR_FILE_READ        3

/* When we can't write to the output directory */
#define FOREMOST_ERROR_FILE_WRITE       4

/*  When we can't close a file */
#define FOREMOST_ERROR_FILE_CLOSE       5

/* Too many file types in the configuration file */
#define FOREMOST_ERROR_TOO_MANY_TYPES   6


/* These are used when displaying how much of the file we've read
   (Never let it be said we didn't plan for the future!)              */
#define UNITS_BYTES                     0
#define UNITS_KILOB                     1
#define UNITS_MEGAB                     2
#define UNITS_GIGAB                     3
#define UNITS_TERAB                     4
#define UNITS_PETAB                     5
#define UNITS_EXAB                      6


/* signal_caught can't go in the state because the signal handler 
   can't take arguments and can only modify global variables...      */
int signal_caught; 

/* Wildcard is a global variable because it's used by very simple
   functions that don't need the whole state passed to them */
char wildcard;

/* We keep track of the current width for our progress bar */
int ttywidth;


extern char *__progname;
extern int  errno;


#define FOREMOST_NOEXTENSION_SUFFIX "NONE"
#define FOREMOST_NOEXTENSION '\xFF'

#define FOREMOST_DEFAULT_WILDCARD       '?'
#define FOREMOST_DEFAULT_CONFIG_FILE    "foremost.conf"

#define FOREMOST_DEFAULT_OUTPUT_DIR     "foremost-output"

#define FOREMOST_BANNER_STRING \
"foremost version %s\n"\
"Written by Kris Kendall and Jesse Kornblum.\n\n", FOREMOST_VERSION

#define FOREMOST_COPYRIGHT_STRING \
"This program is a work of the US Government. In accordance with 17 USC 105,\n"\
"copyright protection is not available for any work of the US Government.\n"\
"This is free software; see the source for copying conditions. There is NO\n"\
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"

#define FOREMOST_USAGE_STRING \
"Digs through an image file to find files within using header information."\
"\n\nUsage: %s [-h|V] [-qv] [-s num] [-i <file>] [-o <outputdir>] \\\n"\
"           [-c <config file>] <imgfile> [<imgfile>] ...\n\n"\
"-h  Print this help message and exit\n"\
"-V  Print copyright information and exit\n"\
"-v  Verbose mode. Highly recommended\n"\
"-q  Quick mode. Only searches the beginning of each sector. While\n"\
"      this is faster, you may miss some files. See man page for \n"\
"      details.\n"\
"-i  Read names of files to dig from a file\n"\
"-o  Set output directory for recovered files\n"\
"-c  Set configuration file to use. See man page for format.\n"\
"-s  Skip n bytes in the input file before digging\n"\
"-n  Extract files WITHOUT adding extensions (eg:.txt) to the \n"\
"      filename. \n", __progname

#define NONEMPTYDIR_ERROR_MSG  \
"ERROR: You have attempted to use a non-empty output directory. In order\n"\
"       to maintain forensic soundness, this action is not allowed.\n"




/* The fields for SearchSpecLine, CharBucket and 
   are in a specific order for the constructors in foremost.c. 
   Don't change them, or you'll break foremost.c! */

struct SearchSpecLine 
{
  char* suffix;
  int casesensitive;
  int length;
  char* begin;
  int beginlength;
  size_t begin_bm_table[UCHAR_MAX+1];
  char* end;
  int endlength;
  size_t end_bm_table[UCHAR_MAX+1];
  int searchtype; //Search for footer from back of file flag....
};

struct CharBucket
{
   long length;
   char *str;
};

struct foremostState {
  char* imagefile; 
  char* conffile; 
  char* outputdirectory;

  int specLines;
  struct SearchSpecLine* SearchSpec;
  int fileswritten;
  int modeVerbose;
  int modeNoSuffix;
  FILE *auditFile;
  char* invocation;
  unsigned long long skip;
  int modeQuick;
  
  int useInputFileList;
  char* inputFileList; 

};

/* From dig.c */
int digImageFile(struct foremostState* state);


/* These are functions defined in helpers.c */

int skipInFile(struct foremostState *state, FILE *infile);

void foremostLog(struct foremostState *state, char *format, ...);

void handleError(struct foremostState *s, int error);

int memwildcardcmp(const void* s1, const void* s2, 
		   size_t n, int caseSensitive);

void init_bm_table(char *needle, size_t table[UCHAR_MAX + 1], 
		   size_t len, int casesensitive,
		   int searchtype);

int writeToDisk(char* suffix, 
		int length,
		struct foremostState* state, 
		struct CharBucket* text,
		unsigned long long offset);

struct CharBucket* extractString (struct CharBucket* extractbuf,
				  unsigned long long  fileoffset,
				  FILE* infile,
				  char *foundat,
				  char *buf,
				  unsigned long long lengthofbuf,
				  struct SearchSpecLine needle);


//int findShortestNeedle (struct SearchSpecLine* SearchSpec);
int findLongestLength  (struct SearchSpecLine* SearchSpec);
int findLongestNeedle  (struct SearchSpecLine* SearchSpec);

char *bm_needleinhaystack(char *needle, size_t needle_len,
                          char *haystack, size_t haystack_len,
                          size_t table[UCHAR_MAX + 1], int casesensitive,
                          int searchtype);


unsigned long long measureOpenFile(FILE *f);
						
int openAuditFile(struct foremostState* state);
int closeFile(FILE* f);

int translate(char *str);
char *skipWhiteSpace(char *str);
void setttywidth();

/* Declare the functions we use from strings.h instead of implicitly 
   declaring them */

#ifdef __WIN32
extern const char *strsignal(int sig);
#else
extern char *strsignal(int sig);
#endif  /*  ifdef __WIN32 */

#endif   /* ifndef FOREMOST_H */

