/*
    Logger.c  Magma
    Log file management
    by seb 13/01/97 15:50
*/

#include "include/vscol.h"
#ifdef VERSION_WIN
#include <windows.h>
#endif
#if defined(VERSION_X11) || defined(VERSION_NOX)
#include <netinet/in.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "include/kernel.h"

/* decoupage d'une chaine en mots (retourne le nombre de mots) */
int strdecoupe(char *comm, char **argv)
{
  int i,j,argc,inword;

  i=j=argc=0;
  inword=0;

  while(comm[i])
    {
      if ((comm[i]=='"')&&(j!=0x5c)) /* reconnaissance de \" */
	{
	  inword=1-inword;
	  comm[i]=0;
	}
      if ((comm[i]<=32)&&(inword==0)) comm[i]=0;
      if ((j==0)&&(comm[i])) argv[argc++]=&comm[i];
      j=comm[i++];
    }
  return argc;
}

/* Cree un fichier de log
  2: signature du fichier (son petit nom)
  1: le masque de logging originel
  0: le time out d'indication de l'heure
  retour : un pointeur vers une variable de type LogFile
*/
int LOGcreate(mmachine m)
{
   char* name;
   int mask;
   int ps;
   int pn;
   int timeout,Name;
   char* pc;
   time_t t;
   FILE * f;
   char bufdat[256],buf[256];
   char* mots[128];
   int  nbmots;

   timeout=MMpull(m)>>1;
   mask=MMpull(m)>>1;
   Name=MMget(m,0)>>1;

   if (timeout==NIL || mask==NIL || Name==NIL)
   {
     MMset(m,0,NIL);
     return 0;
   }

   name=MMstartstr(m,Name);
   time(&t);
   strcpy(bufdat,ctime(&t));
   nbmots=strdecoupe(bufdat,mots);
   sprintf(buf,"%s.%s%s",name,mots[1],mots[2]);
   SPaddfile(Firstpack,buf,0,bufdat);
   strcpy(buf,bufdat);
   f=fopen(buf,"a");
   if (f==NULL)
   {
      MMset(m,0,0);
      return 0;
   }

   fprintf(f,"************ STARTED\n");
   fclose(f);
   strcpy(buf,name);
   name=buf;
   pn=MMmalloc(m,(((strlen(name)+4)>>2)+1),TYPEBUF);
   if (pn==NIL) return MERRMEM;

   MMstore(m,pn,0,strlen(name)+1);
   pc=MMstartstr(m,pn);
   strcpy(pc,name);

   if (MMpush(m,(pn<<1)+1)) return MERRMEM;
   ps=MMmalloc (m,4,TYPETAB);
   pn=MMpull(m)>>1;
   if (ps==NIL) return MERRMEM;

   MMstore(m,ps,0,(pn<<1)|1);
   MMstore(m,ps,1,(mask<<1));
   MMstore(m,ps,2,timeout<<1);
   MMstore(m,ps,3,t<<1);

   MMset(m,0,(ps<<1)|1);
   return 0;
}

/* Ajourne le masque de logging
   1: LogFile (renvoye par la fonction LOGcreate
   0: Nouveau masque.
*/
int LOGsetmask(mmachine m)
{
    int p;

    p=MMget(m,1);
    if (p==NIL)
    {
      MMpull(m);
      return 0;
    }
    MMstore(m,p,1,MMpull(m));

    return 0;
}

/* Retourne le masque de logging
   0: LogFile ...
*/
int LOGgetmask(mmachine m)
{
    int p;

    p=MMpull(m);
    if (p==NIL) 
    {
      MMset(m,0,NIL);
      return 0;
    }
    MMset(m,0,MMfetch(m,p,1));

    return 0;
}

/* Ajoute une phrase (ligne) dans le fichier de log
   2: LogFile
   1: Une chaine de caracteres a ajouter dans le fichier de log
   0: le mask de priorite de cette chaine
*/
int LOGsentence(mmachine m)
{
    int ps;
    int pn;
    int mask1,mask2;
    int string;
    char* str;
    char* fn;
    FILE* f;
    char bufdat[256],buf[256],buf2[256];
    char* mots[128];
    int  nbmots;
    time_t t,timeout,otime;

    mask1=MMpull(m)>>1;
    string=MMpull(m)>>1;
    ps=MMget(m,0)>>1;

    if (mask1==NIL || string==NIL || ps==NIL)
    {
      MMset(m,0,NIL);
      return 0;
    }

    str=MMstartstr(m,string);
    if (str==NULL) 
    {
      MMset(m,0,NIL);
      return 0;
    }
    pn=MMfetch(m,ps,0)>>1;
    if (pn==NIL) 
    {
      MMset(m,0,NIL);
      return 0;
    }
    fn=MMstartstr(m,pn);
    if (fn==NULL) 
    {
      MMset(m,0,NIL);
      return 0;
    }
    mask2=MMfetch(m,ps,1)>>1;
    if (mask2==NIL) 
    {
      MMset(m,0,NIL);
      return 0;
    }
    timeout=MMfetch(m,ps,2)>>1;
    if (timeout==NIL) 
    {
      MMset(m,0,NIL);
      return 0;
    }
    otime=MMfetch(m,ps,3)>>1;
    if (otime==NIL) 
    {
      MMset(m,0,NIL);
      return 0;
    }

    if (!(mask2 & mask1))
    {
      MMset(m,0,4);
      return 0;
    }

    time(&t);
    strcpy(bufdat,ctime(&t));
    nbmots=strdecoupe(bufdat,mots);
    sprintf(buf,"%s.%s%s",fn,mots[1],mots[2]);
    SPaddfile(Firstpack,buf,0,buf2);
 
	f=fopen(buf2,"a");
    if (f==NULL)
    {
       MMset(m,0,0);
       return 0;
    }

    if (t>otime+timeout)
    {
      fprintf(f,"%s %s %s\n",mots[1],mots[2],mots[3]);
      MMstore(m,ps,3,t<<1);
	}
    fprintf(f,"%s\n",str);

    fclose(f);

    MMset(m,0,2);

    return 0;
}

#define NLOGGERPKG 5

char* loggername[NLOGGERPKG]={"_openlog","_setlogmask","_getlogmask","_logsentence","Logfile"};
int (*loggerfun[NLOGGERPKG])(mmachine m)={LOGcreate,LOGsetmask,LOGgetmask,LOGsentence,NULL};
int loggernarg[NLOGGERPKG]={3,2,1,3,TYPTYPE}; 
char* loggertype[NLOGGERPKG]={"fun [S I I] Logfile","fun [Logfile I] Logfile",
                              "fun [Logfile] I",  "fun [Logfile S I] I",
                               NULL};

int SCOLloadlogger(mmachine m)
{
  int k;
  if ((k=PKhardpak(m,"logger.pkg",NLOGGERPKG,loggername,loggerfun
		   ,loggernarg,loggertype))) 
    return k;                                          
  return 0;
}
