/*
 * This code is part of Screws project.
 * Copylefted by pancake@phreaker.net at 2003
 */

#if 0
  %a - User Agent
  %e - Error Code
  %h - host (url to get) (local hostname)
  %i - remote_addr (IP)
  %I - remote_hostname (inversed dns resolution of %i)
  %t - time ( hex time )
  %d - human time (Wed...)
  %m - method
  %H - HTTP
  %f - file to get
  %c - argc
  %n - newline
  %r - referer
#endif

/* PIPE FD for stderr streaming */

#include "Logs.h"
#include "Fmutex.h"
#include "Modules.h"

// XXX IT ISNT A LOG ITS DEBUG
#include <sys/time.h>

#if 0
#if LOGS
char *logs_str[LOG_LASTONE]=
{
	"Integer Overflow attempt catched.",
	"Connection Timeout.",
	"HTTPLEN :?",
	"Cannot malloc.",
	"ErrPtr points to an unexistent position.",
	"Cannot open log file"
};
#endif
#endif

bool screws_logs_init(int n)
{
	int ok=true;
#if LOGS
   if (!Svr.nologs)
   {
      printf("[i] Initializing logfiles. (%s,%s)\n",
         Svr.Lis[n].S[_LOGFILE],Svr.Lis[n].S[_ERRFILE]);

      ok = fmutex_init(Svr.Lis[n].S[_LOGFILE]); // TODO sure? 
      ok*= fmutex_init(Svr.Lis[n].S[_ERRFILE]);

		if (!ok)
			return false;
   }
#endif
	return true;
}


int
screws_logs_access(n)
	int n;
{
#if LOGS
	char b[1024];

	char *str=Svr.Lis[n].S[_LOGSTR];
	loop_t i=0,i2=0,len=strlen(str);

	/* percent values */
	int l=0; char *s,sb[1024];

	if (Svr.nologs) return 0;
	#if DLOPEN
	if ( execModule(MOD_LOGS) ) return 0;
	#endif

	if (Svr.v>=V_EXEC)
	 printf("[L] Logging (%s)\n",str);

	while( (i2<len) && (i<1020) )
	{
		if (str[i2]=='%')
		{
			switch (str[++i2])
			{
			case 'a':
				s=getenv("USERAGENT");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'e':
				s=getenv("CODE");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'r':
				s=getenv("REFERER");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'i':
				s=getenv("REMOTE_ADDR");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'I':
				s=getenv("REMOTE_HOST");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'h':
				s=getenv("HOST");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'H':
				s=getenv("HTTP");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'd':
				l=time(0);
				l=sprintf(sb,"%.100s",ctime((const time_t*)&l));
				if (l>0)
				{
					memcpy(b+i,sb,l-1);
					i+=(l-2);
				}
				break;
			case 't':
				l=sprintf(sb,"0x%.12x",time(0));
				if (l>0)
				{
					memcpy(b+i,sb,l);
					i+=(l-1);
				}
				break;
			case 'f':
				s=getenv("FILE");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'm':
				s=getenv("METHOD");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'c':
				s=getenv("ARGC");
				if (s)
				{
					l=strlen(s);
					memcpy(b+i,s,l);
					i+=l-1;
				}
				break;
			case 'n':
				b[i]='\n';
				i++;
				break;
			default:
				printf("[?] Unknown percentage '%%c' :(\n",str[i2]);
				break;
			}
		} else {
			b[i]=str[i2];
		}
		/* increment */
		i++; i2++;
	}

	memcpy(b+i,"\n",2);
	screws_logs_write( Svr.Lis[n].S[_LOGFILE], b);
#endif

	return 0;
}

// TODO Evitar 2 logs seguits iguals. acumular fins a X
int
screws_logs_error(n,err,msg)
	int n,err,msg;
{
#if LOGS
	char str[1024];

	if (Svr.nologs) return 0;
	if (err>=ERROR_LASTONE) err=ERROR_POINTERR;

	sprintf(str,"0x%x - %s %s\n",time(0),SCREWS_errlist[err],msg);

	screws_logs_write( Svr.Lis[n].S[_ERRFILE], str );
#endif
	return 0;
}

#if LOGS
int
screws_logs_write(file,msg)
	const char *file,*msg;
{
	int fd,lock;
	FILE *f;

	/* CHECK FOR SYSLOG */
	if (!strcmp(file,"syslog"))
	{
		syslog(LOG_ERR,msg);
		return 0;
	}

	/* PIPED OR FILE LOG */
	if (file[0]=='|')
	{
		f=popen(file+1,"w");
		if (!f) { return -1; }
		fwrite(msg,strlen(msg),1,f);
		pclose(f);

	} else {

		/* Check for permisions and create if needed */
		if ( access(file,W_OK) <0)
		{
			if ( creat(file,S_IWUSR) <0)
			{
				printf("Cannot create logfile.\n");
				return -1;
			}
			if (Svr.v>=V_EXEC)
			 printf("[L] Log file '%s' created.\n",file);
		}
	
		/* Lock file */
		lock = fmutex_lock(file);

		/* Open/Write/Close combo */
		fd = open(file, O_APPEND|O_WRONLY); /* Open mode */

		if (fd<0) 
		{
			screws_logs_error(-1,ERROR_OPENLOG,"");
			if (Svr.v>=V_MINI)
				perror("[L] Cannot open log file: \n");
			return -1;
		}
		write(fd,msg,strlen(msg));
		close(fd);
		fmutex_unlock(file,lock);
	}

	if (Svr.v>=V_EXEC)
		printf("[L] Log wrote: [%s][%s]\n",file,msg);

	return 0;
}
#endif

/* TODO man system && man wait */
void
logSignal(status)
	int status;
{
	if (Svr.nologs) return;
}
