/************************************************************************
 *   psybnc2.2.2, src/p_log.c
 *   Copyright (C) 2001 the most psychoid  and
 *                      the cool lam3rz IRC Group, IRCnet
 *			http://www.psychoid.lam3rz.de
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 1, or (at your option)
 *   any later version.
 *
 *   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.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef lint
static char rcsid[] = "@(#)$Id: p_log.c, v 2.2.2 2001/03/25 02:02:02 psychoid Exp $";
#endif

#define P_LOG

#include <p_global.h>

/* write to log */

int __log (char *what, int usern,int level) {
  char tx [20];
  time_t tm;
  time ( &tm );
  strmncpy(tx,ctime( &tm ),sizeof(tx));
#ifndef NOLOG
  if(mainlog==NULL)
     mainlog = fopen(logfile,"a");
  if(level>=LOGLEVEL && mainlog!=NULL)
      fprintf(mainlog,"%s :%s\n",tx,what);
  if(usern==-1)
    noticeall(RI_ADMIN,"%s :%s\n",tx,what);
  else
    systemnotice(usern,"%s :%s\n",tx,what);
#endif
  return 0x0;
}

/* log with format */

int 
log(va_alist)
    va_dcl
{
    static char buf[1024];
    va_list va;
    int level;
    int usern;
    char *format;
    if(inwrite==1) return 0x0; /* if we bug here, we wont iterate */
    inwrite=1;
    va_start(va);
    level=va_arg(va,int);
    usern=va_arg(va,int);
    format=va_arg(va,char *);
    ap_vsnprintf(buf,sizeof(buf),format,va);
    __log(buf,usern,level);
    va_end(va);
    inwrite=0;
    return strlen(buf);
}

/* check for privatelog and the existance of salt.h */

int checkforlog ( int usern ) {
  char fname[40];
  FILE *salt;
  FILE *log;
  pcontext;
  strcpy(fname,"salt.h");
  if ((log = fopen(fname,"r")) != NULL) {
     fclose(log);
     /* if founder logs on, tell him to move salt.h from the bouncer to a safe place */
     if (usern==1) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :WARNING ! Move the file salt.h from the shell to a safe place\n",user(usern)->nick);
     }
  }
  ap_snprintf(fname,sizeof(fname),"USER%d.LOG",usern);
  if ((log = fopen(fname,"r")) == NULL) {
     return 0x0;
  }
  fclose(log);
  return 1;
}

/* check spam & you got message texts from bots */

int checkspam () {
    /* a bot messaging us */
    if(strstr(irccontent,"For a list")!=NULL) return 1; 
    if(strstr(irccontent,"notes waiting on")!=NULL) return 1; 
    /* spam - http://.. */
    if(strstr(irccontent,"http://")!=NULL) return 1;
    if(strstr(irccontent,"HTTP://")!=NULL) return 1;
    return 0x0; /* this was the reason it did not log on SunOs ;) */
}

/* write to privatelog */

int privatelog ( int usern ) {
  char tx [20];
  char fname[40];
  char noact='\x01';
  int uid;
  FILE *log;
  time_t tm;
  pcontext;
#ifdef NOLOG
  return 0x0;
#endif
  if(strchr(irccontent,noact)!=NULL) return 0x0; /* dont log actions, ctcps */
  if(strchr(ircfrom,'@')==NULL) return 0x0; /* dont log servermsgs/notices */
  if(checkspam()==1) return 0x0; /* we dont log spam, blah */
  uid=usern;
  if (user(uid)->parent !=0) uid=user(usern)->parent;
  if (strlen(ircnick) == strlen(user(usern)->nick)) {
     if (strstr(ircnick,user(usern)->nick)) return -1;
  }     
  time ( &tm );
  ap_snprintf(fname,sizeof(fname),"USER%d.LOG",uid);
  strmncpy(tx, ctime( &tm ), sizeof(tx));
  log = fopen(fname,"a");
  if(log!=NULL)
  {
      fprintf(log,"%s~%s :(%s) %s\n",user(usern)->network,tx,ircfrom,irccontent);
      fclose(log);
  }
  return 0x0;
}

/* play private log */

int playprivatelog ( int usern ) {
  char buf [4200];
  char *pt;
  char fname[40];
  FILE *log;
  int userp;
  pcontext;
  if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
  if (checkforlog(usern) == 0) return 0x0;
  ap_snprintf(fname,sizeof(fname),"USER%d.LOG",usern);
  if ((log = fopen(fname,"r"))==NULL) return 0x0;
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Starting playing Log\n",user(usern)->nick);
  while(fgets(buf,sizeof(buf),log)) {
      pt=buf;
      if(*pt=='~') pt++; /* stripping none-network msgs */
      ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :%s\n",user(userp)->nick,pt);
  }      
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Use ERASEPRIVATELOG to kill the log\n",user(userp)->nick);
  fclose(log);
  return 0x0;
}

/* play main log */

int playmainlog ( int usern ) {
  char buf [4200];
  FILE *log;
  int userp;
  pcontext;
  if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
  if (user(userp)->rights != RI_ADMIN) {
      ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are no admin\n",user(userp)->nick);
      return 0x0;
  }
  if(mainlog!=NULL) fclose(mainlog);
  if ((log = fopen(logfile,"r")) == NULL) {
     mainlog=NULL;
     return 0x0;
  }
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Starting playing Main-Log\n",user(userp)->nick);
  while(fgets(buf,sizeof(buf),log)) {
      ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :%s\n",user(userp)->nick,buf);
  }      
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Use ERASEMAINLOG to kill the log\n",user(userp)->nick);
  fclose(log);
  mainlog=NULL;
  return 0x0;
}

#ifdef TRAFFICLOG

/* play traffic log */

int playtrafficlog ( int usern ) 
{
  char source[8192];
  char src2[8192];
  char filter[8192];
  char buf [4200];
  char fname[40];
  int last=0;
  char *apt;
  int rc;
  char *pt,*ept;
  int fyy=0,fmm=0,fdd=0,tyy=0,tmm=0,tdd=0,fh=0,fs=0,fm=0,th=0,ts=0,tm=0;
  int xyy,xmm,xdd,xh,xm,xs;
  FILE *log;
  int userp;
  pcontext;
  if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
  ap_snprintf(fname,sizeof(fname),"log/USER%d.TRL",usern);
  if(*irccontent==0) 
  {
      ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Filter defined. Use PLAYTRAFFICLOG source mm-dd-yy hh:mm:ss mm-dd-yy hh:mm:ss :text (or * for everything). You can also use PLAYTRAFFICLOG last to play.\r\n",user(userp)->nick);
      writesock(user(usern)->insock,buf);
      return 0x0;
  }
  if(strstr(irccontent,"last")==irccontent)
  {
      last=1;
  }
  pt=strchr(ircbuf,' ');
  if (pt!=NULL)
  {
      pt++;
      ept=pt;
      if(last!=1)
          rc=sscanf(pt,"%s %d-%d-%d %d:%d:%d %d-%d-%d %d:%d:%d :%s\n",
             source,&fmm,&fdd,&fyy,&fh,&fm,&fs,&tmm,&tdd,&tyy,&th,&tm,&ts,filter);
      if (rc==14 || last==1)
      {
	  if(last==1)
	  {
	      filter[0]='*';
	      filter[1]=0;
	  } else {
	      pt=strchr(filter,'\r');
	      if(pt==NULL) pt=strchr(filter,'\n');
	      if(pt!=NULL) *pt=0;
	      if(fyy<80) fyy+=2000; else fyy+=1900;
	      if(tyy<80) tyy+=2000; else tyy+=1900;
	      ucase(source);
	  }
          if(user(usern)->trafficlog!=NULL)
              fclose(user(usern)->trafficlog);
	  if ((log=fopen(fname,"r"))!=NULL) 
	  {
	      if(last==1)
	      {
	          fseek(log,user(usern)->lastlog,SEEK_SET);
	      }
	      if(last==1)
	      {
	         ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de NOTICE * :Starting playing log since last.\r\n");
	      } else {
	         ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Starting playing log (%s, from %04d-%02d-%02d %02d:%02d:%02d to %04d-%02d-%02d %02d:%02d:%02d, filter %s)\r\n",
	               source,source,fyy,fmm,fdd,fh,fm,fs,tyy,tmm,tdd,th,tm,ts,filter);
	      }
              writesock(user(usern)->insock,buf);
              while(fgets(buf,sizeof(buf),log)) {
	          if(last!=1)
	              rc=sscanf(buf,"%d-%d-%d-%d-%d-%d:%s:",&xyy,&xmm,&xdd,&xh,&xm,&xs,src2);
	          if (rc==7 || last==1)	
	          {
		    if(last!=1)
		    {
		      if(xyy<80) xyy+=2000; else xyy+=1900;
		      pt=strchr(src2,':');
		      if(pt!=NULL) *pt=0;
		      ucase(src2);
		      /* is it in range ? */
		      if(xyy>tyy) break;
		      if(xyy==tyy && xmm>tmm) break;
		      if(xyy==tyy && xmm==tmm && xdd>tdd) break;
		      if(xyy==tyy && xmm==tmm && xdd==tdd && xh>th) break;
		      if(xyy==tyy && xmm==tmm && xdd==tdd && xh==th && xm>tm) break;
		      if(xyy==tyy && xmm==tmm && xdd==tdd && xh==th && xm==tm && xs>ts) break;
		    }        
		    if(((xyy>fyy || (xyy==fyy && xmm>fmm) || (xyy==fyy && xmm==fmm && xdd>fdd) ||
		          (xyy==fyy && xmm==fmm && xdd==fdd && xh>fh) ||
		          (xyy==fyy && xmm==fmm && xdd==fdd && xh==fh && xm>fm) ||
		          (xyy==fyy && xmm==fmm && xdd==fdd && xh==fh && xm==fm && xs>=fs)) && 
		          strmcmp(source,src2)) || last==1)
		      {
		          pt=strchr(buf,':');
		          if(pt!=NULL)
		          {
		              pt++;
		              pt=strchr(pt,':');
		              if (pt!=NULL)
		              {
		                  pt++;
			          if(*filter=='*' || strstr(pt,filter)!=NULL)
                                      writesock(user(usern)->insock,pt);
		              }
		          }
		      }
	          }
              }
	      if(last==1)
	      {
	          user(usern)->lastlog=ftell(log);
	          writeuser(usern);
	      }      
	      if(last==1)
	          ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE * :End of log.\r\n");
	      else
	          ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :End of log (%s)\r\n",source,filter);
	      fclose(log);
	      user(usern)->trafficlog=fopen(fname,"a");
	      return 0x0;
	  }
      }
  }
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Wrong Syntax. Use PLAYTRAFFICLOG source mm-dd-yy hh:mm:ss mm-dd-yy hh:mm:ss :text (or * for everything)\r\n",user(userp)->nick);
  return 0x0;
}

#endif

/* creating backup file */

int oldfile(char *fname)
{
  char oldf[100];
  pcontext;
  ap_snprintf(oldf,sizeof(oldf),"%s.old",fname);
  rename (fname,oldf);
  return 0x0;
}

/* backup private log */

int eraseprivatelog ( int usern ) {
  char fname[40];
  int userp;
  pcontext;
  if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
  ap_snprintf(fname,sizeof(fname),"USER%d.LOG",usern);
  oldfile(fname);
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Log erased\n",user(userp)->nick);
  return 0x0;
}

/* backup main log */

int erasemainlog ( int usern ) {
  char fname[40];
  int userp;
  pcontext;
  if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
  if (user(userp)->rights != RI_ADMIN) {
      ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are no admin\n",user(userp)->nick);
      return 0x0;
  }
  if(mainlog!=NULL) fclose(mainlog);
  mainlog=NULL;
  oldfile(logfile);
  ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Main-Log erased\n",user(usern)->nick);
  return 0x0;
}

#ifdef TRAFFICLOG

/* erase traffic log */

int erasetrafficlog ( int usern ) {
  char fname[40];
  int userp;
  pcontext;
  if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
  if(user(usern)->trafficlog!=NULL)
  {
      fclose(user(usern)->trafficlog);
      ap_snprintf(fname,sizeof(fname),"log/USER%d.TRL",usern);
      unlink(fname);
      user(usern)->lastlog=0;
      user(usern)->trafficlog=fopen(fname,"a");
      ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Traffic-Log erased\n",user(usern)->nick);
  } else {
      ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Traffic logging open\n",user(usern)->nick);
  }    
  return 0x0;
}

/* checks, if an entry has to be logged and does, if */

int checklogging(int usern)
{
    static char buf[400];
    char *dest;
    char *filter;
    char *somp;
    int entry=0;
    int tried=0;
    static char fname[40];
    struct tm *xtm;
    time_t tm;
    int iyear;
    struct stringarray *th;
    pcontext;
    time( &tm );
    xtm=gmtime(&tm);
    while(1)
    {
	th=user(usern)->logs;
	if(th==NULL) return 0x0;
	somp=getstring(entry,th);
	if(somp==NULL) return 0x0;
	strmncpy(buf,somp,sizeof(buf));
	dest=strchr(buf,';');
	if(dest!=NULL)
	{
	    *dest++=0;
	    filter=buf;
	    ucase(dest);
	    ucase(ircto);
	    if(strmcmp(dest,ircto))
	    {
		    if (*filter=='*' || strstr(ircbuf,filter)!=NULL)
		    {
			iyear=xtm->tm_year;
			if(iyear<80) iyear=iyear+2000; /* from 00-79 = 2000-2079 */
			if(iyear<1900) iyear=iyear+1900; /* 100 = 2000, 99 = 1999 */
			if(user(usern)->trafficlog==NULL && tried!=1)
			{
			    ap_snprintf(fname,sizeof(fname),"log/USER%d.TRL",usern);
			    user(usern)->trafficlog=fopen(fname,"a");
			    tried=1;
			}
			if(user(usern)->trafficlog!=NULL)
			    fprintf(user(usern)->trafficlog,"%02d-%02d-%02d-%02d-%02d-%02d:%s:%s\n",iyear,xtm->tm_mon,xtm->tm_mday,xtm->tm_hour,xtm->tm_min,xtm->tm_sec,ircto,ircbuf);
			return 0x0;
		    }
	    }
	}
	entry++;
    }
}

#endif
