/*
    HTTP based News site reader by LouiSe 2002 louise@louise.amiga.hu



	HISTORY


	20020420	v0.4	TEMP filename fix (number to string)

	20020419	v0.3	not release

	20020419	v0.2	first public release

*/

#define	PROGRAMVERSION	"$VER: 0.4 (20/apr/2002)"

#define	MAXCONFIGS	100
#define	MAXFN		256
#define	CONFIGDIR	"sites"
#define	TOOLSDIR	"tools"
#define	TEMPDIR		"temp"

#include	<stdio.h>
#include	<string.h>
#include	<unistd.h>
#include	<stdlib.h>

int	VERBOSE=0;			// set verbosity with value = 1
int	CGIMODE=0;			// set CGI mode with value = 1

int	CONFIGS=0;			// the number of config files in use
char	conf_fn[MAXCONFIGS][MAXFN];	// the config file names
char	conf_gr[MAXCONFIGS][MAXFN];	// GRAB field for grab the URL
char	conf_sa[MAXCONFIGS][MAXFN];	// SAY field for speech the words
int	conf_re[MAXCONFIGS];		// RELOAD field the reload times for config file names/sites
char	conf_st[MAXCONFIGS][MAXFN];	// START field for start of searching
char	conf_so[MAXCONFIGS][MAXFN];	// STOP field for stop of searching
int	conf_counter[MAXCONFIGS];	// the counter for a site reload delay

char	currdir[MAXFN];


void	printhelp()
{
    printf("Usage: newsspeech [options] [config files]\n\n");
    
    printf("Arguments:\n");
    printf(" -h\tThis help page\n");
    printf(" -v\tVerbose mode\n");
    printf(" -c\tRun in CGI mode for web servers\n");
    printf("\n");
}


char	*getconfline(char *filename, char *field)
{
    FILE	*fh;
    char	buff[MAXFN];
    static char	fieldvalue[MAXFN];
    char	*ptr;
        
	memset(fieldvalue,0,sizeof(fieldvalue));
	
	if((fh=fopen(filename,"r"))==NULL)
	{
	    if(VERBOSE==1) printf("Config file %s NOT FOUND!\n",filename);	
	    return(NULL);
	}
	else
	    {
		while(!feof(fh))
		{
		    memset(buff,0,sizeof(buff));
		    if(!fgets(buff,sizeof(buff)-1,fh)) break;
		    if(strncasecmp(buff,field,strlen(field))==0)
		    {
			strtok(buff,"\t ");
			ptr=strtok(NULL,"\n");
			if(ptr!=NULL) strcpy(fieldvalue,ptr);
		    }
		}
		fclose(fh);
	    }		

    return(fieldvalue);
}


int	buildconf(char *filename, int confnum)
{
    int		configz=0;
    int		creload=0;
    char	*ptr;
            
	if(confnum!=-1)
	{
	    // config reload...
	    configz=CONFIGS;
	    CONFIGS=confnum;
	}

	ptr=getconfline(filename,"RELOAD:");
	if(ptr!=NULL)
	{
	    strcpy(conf_fn[CONFIGS],filename);
	    if(VERBOSE==1) printf("%.2d Config file is '%s'\n",CONFIGS,conf_fn[CONFIGS]);
	}
	else return(-1);

	if(ptr!=NULL)
	{
	    creload=atoi(ptr);
	    if(creload>0)
	    {
		conf_re[CONFIGS]=creload;
		if(VERBOSE==1) printf("\tRELOAD=%d\n",conf_re[CONFIGS]);
	    }
	    else if(VERBOSE==1) printf("\tInvalid RELOAD value in Config file '%s' !\n",filename);
	}

	ptr=getconfline(filename,"GRAB:");
	if(ptr!=NULL)
	{
	    strcpy(conf_gr[CONFIGS],ptr);
	    if(VERBOSE==1) printf("\tGRAB=%s\n",conf_gr[CONFIGS]);
	}
	else if(VERBOSE==1) printf("Invalid GRAB value in Config file '%s' !\n",filename);

	ptr=getconfline(filename,"SAY:");
	if(ptr!=NULL)
	{
	    strcpy(conf_sa[CONFIGS],ptr);
	    if(VERBOSE==1) printf("\tSAY=%s\n",conf_sa[CONFIGS]);
	}
	else if(VERBOSE==1) printf("Invalid SAY value in Config file '%s' !\n",filename);

	ptr=getconfline(filename,"START:");
	if(ptr!=NULL)
	{
	    strcpy(conf_st[CONFIGS],ptr);
	    if(VERBOSE==1) printf("\tSTART=%s\n",conf_st[CONFIGS]);
	}
	else if(VERBOSE==1) printf("Invalid START value in Config file '%s' !\n",filename);

	ptr=getconfline(filename,"STOP:");
	if(ptr!=NULL)
	{
	    strcpy(conf_so[CONFIGS],ptr);
	    if(VERBOSE==1) printf("\tSTOP=%s\n",conf_so[CONFIGS]);
	}
	else if(VERBOSE==1) printf("Invalid STOP value in Config file '%s' !\n",filename);

	if(confnum!=-1)
	{
	    // config resetting
	    CONFIGS=configz;
	}

	CONFIGS++;
	if(CONFIGS>=MAXCONFIGS)
	{
	    if(VERBOSE==1) printf("Sorry maximum number of config file stack %d is exceed\n",MAXCONFIGS);
	}



    return(configz);
}


int	getlines(char *filename, char *starts, char *stops, char *speech, int confnum)
{
    FILE	*fh,*fh2;
    char	filenameout[MAXFN];
    char	buff[MAXFN*4],newsline[MAXFN*2];
    int		skipped=0,ret=0;
    char	*ss;
    char	execute[MAXFN*2];
    
    memset(filenameout,0,sizeof(filenameout));
    sprintf(filenameout,"%s.out",filename);
    
    if((fh=fopen(filename,"r"))==NULL)
    {
	if(VERBOSE==1) printf("Couldn't open temp file '%s' for read !\n",filename);
	return(-1);
    }
    else
	{
	    if((fh2=fopen(filenameout,"r+"))==NULL)
	    {
		if((fh2=fopen(filenameout,"w+"))==NULL) printf("Couldn't open temp file '%s' for read+write !\n",filenameout);
		fclose(fh2);
	    }
	    else fclose(fh2);

	    if((fh2=fopen(filenameout,"r+"))==NULL)
	    {
		if(VERBOSE==1) printf("Couldn't open temp file '%s' for read+write !\n",filenameout);
		
		return(-1);
	    }
	    else
		{
	    	    // start to read from temp file, and write the analyzed lines to output file
		
		    while(!feof(fh))
		    {
			memset(buff,0,sizeof(buff));
			if(!fgets(buff,sizeof(buff)-1,fh)) break;
			if((ss=strstr(buff,starts))!=NULL)
			{
			    // found the starting mask
			    memset(newsline,0,sizeof(newsline));
			    strcpy(newsline,ss+strlen(starts));
			    // printf("[%s][%s]\n",newsline,stops);
			    ss=strstr(newsline,stops);
			    if(ss!=NULL)
			    {
				// printf("[%s] %d %d ",newsline,strlen(newsline),strlen(ss));
				newsline[strlen(newsline)-strlen(ss)]=0;
				// printf("[%s]\n",newsline);
				
				fseek(fh2,0L,SEEK_SET);
				skipped=0;
				while(!feof(fh2))
				{
				    memset(buff,0,sizeof(buff));
				    if(!fgets(buff,sizeof(buff)-1,fh2)) break;
				    strtok(buff,"\n");
				    if(strcmp(buff,newsline)==0)
				    {
					// already on the database, skipping
					// printf("SKIPPED [%s]\n",newsline);
					skipped=1;
					break;
				    }
				}
				
				if(skipped==0)
				{
				    fseek(fh2,0L,SEEK_END);
				    fprintf(fh2,"%s\n",newsline);
				    printf("%s [%s]\n",conf_fn[confnum]+strlen(currdir)+strlen(CONFIGDIR)+2,newsline);
				    // need to speech...
				    
				    memset(execute,0,sizeof(execute));
				    sprintf(execute,speech,currdir,TOOLSDIR,newsline);
    
				    if(VERBOSE==1) printf("Execute '%s'\n",execute);
				    ret=system(execute);    
				    if(VERBOSE==1) printf("Execute OK (%d).\n",ret);
				}				
			    }
			}
			
		    
		    
		    }
		
		    fclose(fh2);
		}
	
	    fclose(fh);	
	}

    return(ret);
}


int	analyzesite(int confnum)
{
    char	tempf[MAXFN];
    char	execute[MAXFN*2];
    int		ret=0;
    
    if(VERBOSE==1) printf("Reloading config values from file '%s' \n",conf_fn[confnum]);
    buildconf(conf_fn[confnum],confnum);	// reload the values from config file (for changes too)

    memset(tempf,0,sizeof(tempf));
    // sprintf(tempf,"%s/%s/%d",currdir,TEMPDIR,confnum);
    sprintf(tempf,"%s/%s/%s",currdir,TEMPDIR,conf_fn[confnum]+strlen(currdir)+strlen(CONFIGDIR)+2);
    unlink(tempf);

    memset(execute,0,sizeof(execute));
    sprintf(execute,conf_gr[confnum],currdir,TOOLSDIR,tempf);
    
    if(VERBOSE==1) printf("Execute '%s'\n",execute);
    ret=system(execute);    
    if(VERBOSE==1) printf("Execute OK (%d).\n",ret);
    if(ret!=0) return(ret);
    
    getlines(tempf,conf_st[confnum],conf_so[confnum],conf_sa[confnum],confnum);
        
    return(0);
}


int	main(int argc, char *argv[])
{
    int		i=0,argok=0;
    char	cfile[MAXFN];

	
    printf("NewsSpeech %s by LouiSe (louise@louise.amiga.hu)\n\n",PROGRAMVERSION);
        
    if(argc>1)
    {
	getcwd(currdir, sizeof(currdir));
	if(VERBOSE==1) printf("Current working directory is '%s'\n",currdir);

	if(VERBOSE==0) printf("Configuration files:\n");
	
	for(i=0;i<argc;i++)
	{
	    argok=0;
	    // printf("%s\n",argv[i]);
	    if(strcasecmp(argv[i],"-h")==0) { printhelp(); argok=1; };
	    if(strcasecmp(argv[i],"-v")==0) { VERBOSE=1; argok=1; };
	    if(strcasecmp(argv[i],"-c")==0) { CGIMODE=1; argok=1; };
	    if(argok==0)
	    {
		// the argument seems to a config file name...
		memset(cfile,0,sizeof(cfile));
		sprintf(cfile,"%s/%s/%s",currdir,CONFIGDIR,argv[i]);
		buildconf(cfile,-1);
		printf("%s\n",conf_fn[CONFIGS-1]+strlen(currdir)+strlen(CONFIGDIR)+2);
	    }
	}	    
    
    }
    else
	{
	    printhelp();
	
	}


    if(CONFIGS>0)
    {
	// going to the work...
	printf("\nNewsSpeech is running with %d preloaded config file(s)...\n",CONFIGS);
	for(i=0;i<CONFIGS;i++) conf_counter[i]=conf_re[i];	// setting up the counters...
	
	while(1)
	{
	    sleep(1);
	
	    for(i=0;i<CONFIGS;i++)
	    {
		conf_counter[i]--;				// decrease the counters...
		if(conf_counter[i]==0)
		{
		    // start the GRAB, analyze and the speech...		
		    if(VERBOSE==1) printf("Starting with '%s' (RELOAD=%d second(s))...\n",conf_fn[i]+strlen(currdir)+strlen(CONFIGDIR)+2,conf_re[i]);
		    analyzesite(i);


		    conf_counter[i]=conf_re[i];			// resetting counter value
		}	
	    }
	    
	    
	
	
	}
    }
    else
	{
	    printf("There is no config files to run, exiting.\n");
	
	}



    return(0);
}
