/*--------------------------------------------------
 * AVACL - Anti Virus Access Control List
 *
 * A program, initially designed for functionality over
 * speed.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "strlower.h"
#include "blocks.h"
#include "usersdb.h"
#include "avacl.h"

#define _VERSION "AVAcl - version 0.1.0 - By Paul L Daniels - http://www.pldaniels.com/avacl\n"

#define _USAGE "\
AVAcl usage:\n\
	-s <sender> (email address of sender)\n\
	-r <receiver> (email address of recipient)\n\
	-n <filename> (name of file we're testing)\n\
	-t <filetype> (the type as returned by 'file' of the file)\n\
	[-c <AVAcl configuration file> (default is /usr/local/avacl/avacl.conf)]\n\
	[-v Be verbose about results]\n\
	[-V (get the version)]\n\
	[-h (help)]\n\
	\n"
	
#define _MAX_CVAR_SIZE 512

#define _TYPE_BLOCK 1
#define _NAME_BLOCK 2
#define _TEXT_BLOCK 4
#define _SIZE_BLOCK 8
#define _USER_BLOCK 16
 
char _default_conf[]="/usr/local/avacl/avacl.conf";
char _default_userdb[]="/usr/local/avacl/users.db";
int _verbose = 0;
/* Globals */

char typeblockfile[_MAX_CVAR_SIZE];
char nameblockfile[_MAX_CVAR_SIZE];
char textblockfile[_MAX_CVAR_SIZE];
char userdbfile[_MAX_CVAR_SIZE];
int maxfilesize=1000;

/*---------------------------------------------------------
 * parse_conf
 *
 * Read in the configuration file
 */
 
int parse_conf( char *conffile ){
	
	FILE *f = fopen(conffile,"r");
	char line[1024];
	char *token;
	char *value;
	if (!f) {
		fprintf(stderr,"Error: cannot open conf file %s\n",conffile);
		exit(1);
		}
	
	/* for every line in our configuration file */	
	while (fgets(line,1024,f)){
		
		/* check it has a token=value format AND doesn't start with a '#' */
		if (strchr(line,'=')&&(line[0] != '#')){
			
			/* get the first part of the token=value pair */
			token = strtok(line,"=");
			
			/* if we actually got something (and not NULL) */
			if (token) {
				
				/* try get the 2nd part of the token=value pair */
				value = strtok(NULL,"\n\r");
				
				/* if we got that successfully...*/
				if (value){

					/* now that we have both a token and a value... 
					 * lets try match up to our conf requirements */
					 
					if (strcmp(token,"typeblockfile")==0) {
						strncpy(typeblockfile, value, _MAX_CVAR_SIZE);
						}
					else
					if (strcmp(token,"nameblockfile")==0) {
						strncpy(nameblockfile, value, _MAX_CVAR_SIZE);
						}
					else
					if (strcmp(token,"textblockfile")==0) {
						strncpy(textblockfile, value, _MAX_CVAR_SIZE);
						}
					else
					if (strcmp(token,"userdbfile")==0) {
						strncpy(userdbfile, value, _MAX_CVAR_SIZE);
						}
					else
					if (strcmp(token,"maxfilesize")==0) {
						maxfilesize=atoi(value);
						}
					} /* if value */
				} /* if token */
			} /* if valid line */
		} /* while reading file */
	
	/* if the file is genuinely open, then close it */
	if (f) fclose(f);	
	return 0;
	}








	
	
int main( int argc, char **argv ){

	int i;
	int result = 0;
	int typeblocked=0, nameblocked=0, textblocked=0, sizeblocked=0, userblocked=0;
	
	char *conffile = _default_conf;
	char *sender=NULL, *receiver=NULL, *filename=NULL, *filetype=NULL;
			
	/* for every argument on our command line... */
	for (i = 1; i < argc; i++){
		
		/* if the 1st char is a hyphen, then our next must be
		 * the parameter's value */
		if (argv[i][0] == '-') {	
			switch (argv[i][1]){
				case 'c': conffile = argv[++i]; break;
				case 's': sender = argv[++i]; break;
				case 'r': receiver = argv[++i]; break;
				case 'n': filename = argv[++i]; break;
				case 't': filetype = argv[++i]; break;
				case 'v': _verbose = 1; break;
				case 'V': fprintf(stderr,"%s",_VERSION); exit(1); break;
				case 'h': fprintf(stderr,"%s\n%s",_VERSION,_USAGE); exit(1); break;
				default: fprintf(stderr,"Error: unknown option '%s'\n%s",argv[i],_USAGE); exit(1); break;
				} /* switch */
			} /* if argv[i] */
		} /* for all params */

#ifdef DEBUG
	fprintf(stderr,"\n---------INPUT PARAMS-----------\n\
		conf=%s\n\
		sender=%s\n\
		receiver=%s\n\
		filename=%s\n\
		filetype=%s\n\
		",conffile, sender, receiver,filename, filetype);
#endif

	/* now, check that we have got all the required parameters!
	   drop out if we dont have them all. */
	if (!sender){
		fprintf(stderr,"Error: Sender required, use '-s <sender>'\n");
		exit(1);
		}
		
	if (!receiver){
		fprintf(stderr,"Error: Receiver required, use '-r <receiver>'\n");
		exit(1);
		}
		
	if (!filename){
		fprintf(stderr,"Error: Filename required, use '-n <filename>'\n");
		exit(1);
		}
		
	if (!filetype){
		fprintf(stderr,"Error: Filetype required, use '-t <filetype>'\n");
		exit(1);
		}


	/* setup the default userdb file */
	strcpy(userdbfile,_default_userdb);		
		
	/* read in our configuration file */
	parse_conf(conffile);

#ifdef DEBUG
	fprintf(stderr,"\n---------CONF FILE PARAMS-------\n\
		NameBlock file: %s\n\
		TypeBlock file: %s\n\
		TextBlock file: %s\n\
		UserDB file   : %s\n\
		MaxEmail Size : %d\n"\
		,nameblockfile, typeblockfile, textblockfile, userdbfile, maxfilesize);
	fprintf(stderr,"----------------------------------\n\n");
	
#endif

	/* load up our _default_ blocking lists */				
	LOAD_nameblock( nameblockfile );
	LOAD_textblock( textblockfile );
	LOAD_typeblock( typeblockfile );
	
	/* apply the user specific adjustments */
	UDB_setmaxemailsize(maxfilesize);
	UDB_search( userdbfile, sender, receiver );

	/* now, test things out.... */
	nameblocked = TEST_nameblock( filename );
	typeblocked = TEST_typeblock( filetype );
	textblocked = TEST_textblock( filename );
	sizeblocked = TEST_sizeblock( filename, UDB_getmaxemailsize() );
	userblocked = UDB_userblock();	
	/* clear up our memory */
	SHUTDOWN_cleanup();

	/* OR' up the results */
	if (typeblocked) result |= _TYPE_BLOCK;
	if (nameblocked) result |= _NAME_BLOCK;
	if (textblocked) result |= _TEXT_BLOCK;
	if (sizeblocked) result |= _SIZE_BLOCK;
	if (userblocked) result |= _USER_BLOCK;
	
	if (_verbose) {
		fprintf(stdout,"type=%d:name=%d:text=%d:size=%d:user=%d\n",\
			typeblocked, nameblocked, textblocked, sizeblocked, userblocked);	
		}
	return result;
	}