/*     
        SCOL FRONTEND . 1997 . Sylvain HUET

         mainscol.h : gestion des evenements
*/
// Modification history:
//$ FA(03/05/2001): Commented out #include "analyzer.h" (not used)
//$ FA(21/05/2001): Debugger integration. Filter READs.
//$ FA(01/06/2001): Comment MMpull() after call to SCexeccomm()
//$ FA(06/06/2001): Includes baselib.h
//$ FA(18/06/2001): Debugger integration. Filter WRITEs.
//$ FA(12/11/2001): Replace SCOL_DEBUGGER_AWARE by INCLUDE_DEBUGGER
//



#include <stdio.h>
#include <string.h>

#include "include/vscol.h"
#ifdef VERSION_WIN
#include <winsock.h>
#endif

#include "include/common.h"

#include "mmemory.h"
#include "mbytec.h"
#include "baselib.h"
#include "listlab.h"
#include "loadpak.h"
#include "scol.h"
#include "scolsys.h"
#include "scolsign.h"
#include "scolpack.h"
#include "fifo.h"
#include "include/socket.h"
#include "include/cpu_detect.h"
#include "scolobj.h"
#include "debug.h"

struct Mmachine mscol;
char scriptname[1024];
char scriptcontent[1024];
char userscript[1024*16];
int ScolMemoryLength=0;
int firstScol=0;
char autoHTTPproxy[256];
char autoSOCKSproxy[256];
char HTTPproxy[256];

int SCOLInit()
{
#ifdef OPTI_P3
	if( testP3() )		{	infoP3 = 1;		MMechostr(0,"*****  SSE1 supported !                                       *****\n" ); }
	else				{	infoP3 = 0;		MMechostr(0,"*****  SSE1 not supported                                     *****\n" ); }
#endif


#ifdef OPTI_P4
	if( testP4() )		{	infoP4 = 1;		MMechostr(0,"*****  SSE2 supported !                                       *****\n" ); }
	else				{	infoP4 = 0;		MMechostr(0,"*****  SSE2 not supported                                     *****\n" ); }
#endif

	
	return 0;
}


int SCOLNetEvent(mmachine mscol,int hSock,int NetEvent,int NetError)
{
  char buf[1024];
  int len;
  int k;
  int ip,port;

  k=0;
  if (NetError) {
      //$ FA(06/08/2001): Add the error code into the message
      MMechostr(MSKWARNING, "Error #%d on socket #%d\n", NetError, hSock);
      if (SCselectcanal(mscol, hSock) == 0)
          SCchanneldown(mscol);
      k = -1;
  } else
    switch(NetEvent)
      {
      case FD_ACCEPT :
        MMechostr(MSKDEBUG,"ACCEPT %d\n",hSock);
        if (SCgetserver(mscol,hSock)) break;
        SCaccept(mscol,hSock);
        MMechostr(MSKDEBUG,"ACCEPT_OK\n");
        break;
      case FD_READ :
//$ FA(07/12/2000): Filter debugging server messages
#if defined(INCLUDE_DEBUGGER)
        if (hSock == debug.sock) {
		      // Virtual machine should be closed here if needed
          if (DBGServiceDebugger(mscol) == MERRCLOSE)
		        SCclosemachine(mscol);
		      break;
        }
#endif
//
        MMechostr(MSKDEBUG,"READ %d\n",hSock);
        len=SCKrecv(hSock,buf,1024,&ip,&port);
        if (len<0)
          {
            if (SCselectcanal(mscol,hSock)) break;
            SCchanneldown(mscol);
            k=-1;
            MMechostr(MSKWARNING,"READ_CLOSE\n");
            break;
          }
        if (SCselectcanal(mscol,hSock)) break;
	    SCread(mscol,buf,len,ip,port);
        
        MMechostr(MSKDEBUG,"READ_OK\n");
        break;
      case FD_WRITE :
//$ FA(19/06/2001): Filter debugging server messages
#if defined(INCLUDE_DEBUGGER)
        if (hSock == debug.sock)
          break;
#endif
//
        MMechostr(MSKDEBUG,"WRITE %d\n",hSock);
        if (SCselectcanal(mscol,hSock)) break;
        if (SCwrite(mscol)==1)
	  {
            SCchanneldown(mscol);
            k=-1;
            MMechostr(MSKWARNING,"WRITE_CLOSE\n");
            break;
          }
        MMechostr(MSKDEBUG,"WRITE_OK\n");
        break;
      case FD_CLOSE :
        MMechostr(MSKDEBUG,"CLOSE %d\n",hSock);
        k=-1;
        if (SCselectcanal(mscol,hSock)) break;
        len=SCKrecv(hSock,buf,1024,&ip,&port);
        if (len>0) SCread(mscol,buf,len,ip,port);
        SCchanneldown(mscol);
        break;
      default:
        break;
      }        
  
  return k;
}

extern int activeChannel;

int SCOLsend(mmachine m,char *buf)
{
	int k;
MMechostr(MSKDEBUG,"receive message : %s\n",buf);
    MMpush(m,MMgetglobal(m,OFFSCCUR));
	if (SCselectcanal(m,activeChannel)) return 0;
    if (k=SCexeccomm(m,buf)) return 0;
//    MMpull(m);
	MMsetglobal(m,OFFSCCUR,MMpull(m));
	return 0;
}

int StartQuotaThread (char *path,int size);

extern int fstart;

int tstscoldead(int i)
{
	int k;

	if (fstart!=1) return 0;

    if (k=SCisdead(&mscol))
    {
        MMechostr(MSKRUNTIME,"Dead Scol Machine %d (%d)\n",k,i);
		Mprinterror(k);
		if ((k<0)&&(k!=MERRCLOSE))
		{
//			_asm { int 3};
			EndScolMachine(-1);}
        else EndScolMachine(0);
    }
    return 0;
}

char *ScolGetName(char *name)
{
    int i,k;

    i=k=0;
    while(name[i])
    {
        if ((name[i]=='\\')||(name[i]=='/')) k=i+1;
        i++;
    }
	return &name[k];
}
int ScolGetPath(char *path, char *name)
{
  int i,k;

  k=0;
  i=0;
  while(name[i])
    {
      if ((name[i]=='\\')||(name[i]=='/')) k=i;
      i++;
    }
  strcpy(path,name);
  path[k]=0;
  return 0;
}

int mainscol()
{
    char script[1024*15];
    int n;
    FILE *f;
    char *p;
            
	ScolMemoryLength=1024*256;
    MMechostr(MSKTRACE,"initialisation %d\n",ScolMemoryLength);
//	if (!ScolMemoryLength) ScolMemoryLength=1024*1024;
    if (SCinit(&mscol,ScolMemoryLength)) return -1;

	if (scriptname[0]==0)
	{
		ScolSuper=1;
		strcpy(scriptname,"scol.scol");
		strcpy(scriptcontent,"$");
		script[0]=0;
		userscript[0]=0;
#ifdef VERSION_WIN
		if (Cachepack) StartQuotaThread(Cachepack->path,Cachepack->quota);
#endif
		strcpy(script,"_load \"locked/lib/stdlib.pkg\"\n");
		strcat(script,"_load \"locked/lib/loc.pkg\"\n");
		strcat(script,"_load \"locked/lib/treeedit.pkg\"\n");
		strcat(script,"_load \"locked/lib/textedit.pkg\"\n");
		strcat(script,"_load \"locked/master.pkg\"\n");
		sprintf(script,"%smain %x\n",script,STDPORT);
	}
    else
	{

		if (scriptcontent[0]=='$')
		{
			sprintf(script,
			"_load \"locked/slv.pkg\"\nmain \":%d\" \"%s\"",STDPORT,ScolGetName(scriptname));
			MMechostr(MSKTRACE,"ouverture script %s\n",scriptname);
	        f=fopen(scriptname,"rb");
		    if (f==NULL) return -1;
			n=fread(userscript,1,1024*15-1,f);
	        userscript[n]=0;
		    fclose(f);
	    }
		else if (!strncmp(scriptcontent,"scol://",7))
	    {
			sprintf(script,
			"_load \"locked/slv.pkg\"\nmain \":%d\" \"%s\"",STDPORT,scriptname);
			MMechostr(MSKTRACE,"std user\n");
	        sprintf(userscript,"_load \"locked/stduser.pkg\"\nmain \"%s\" NIL NIL",
				scriptcontent);
	    }
		else
	    {
			sprintf(script,
			"_load \"locked/slv.pkg\"\nmain \":%d\" \"%s\"",STDPORT,scriptname);
			MMechostr(MSKTRACE,"script en parametre\n");
	        if (Mpushstrbloc(&mscol,scriptcontent)) return -1;
		    if (MBwebtostr(&mscol)) return -1;
			p=MMstartstr(&mscol,MMpull(&mscol)>>1);
			strcpy(userscript,p);
	    }
	}
    
    mscol.err=SCcreateappli(&mscol,NULL,script);
    tstscoldead(34);
	if ((ScolRights&M_RIGHTS)==0) /* la machine doit-elle activer le cache d'office ? */
	{
		SCcacheActivate(&mscol); /* oui */
		strcpy(cookies,"__");    /* forcer le cookies à une valeur par défaut */
	}
    
    return 0;
}
