/*---------------------------------------------------------------------------
                   S I C S   T O K E N
                   
   This files implements the SICS token command. Manages the token status
   and creates the user interface.
   
   Mark Koennecke, January 1998
   
   copyright: see copyright.h
   
-----------------------------------------------------------------------------*/
#include "sics.h"
#include "token.h"
#include "status.h"

/*---------------------- token Management ----------------------------------*/
 static int iToken = 0;
 static char pTokenPassword[256];
/*--------------------------------------------------------------------------*/
 int TokenGrabActive(void)
 {
   return iToken;
 } 
/*-------------------------------------------------------------------------*/
 void TokenRelease(void)
 {
   iToken = 0;
 } 
/*-------------------------------------------------------------------------*/
  int TokenInit(SConnection *pCon, SicsInterp *pSics, void *pData,
                int argc, char *argv[])
  {
     int iRet;
  
     /* we  need a password for token forcing as a parameter */
     if(argc < 2)
     {
       SCWrite(pCon,"ERROR: I need a password for token forcing!", eError);
       return 0;
     }
     
     
     if(strlen(argv[1]) > 255)
     {
       SCWrite(pCon, "ERROR: TokenPassword to long!",eError);
       return 0;
     }
     memset(pTokenPassword,0,255);
     strcpy(pTokenPassword,argv[1]);
     
     /* create command */
     iRet = AddCommand(pSics,
                       "token",
                       TokenWrapper,
                       NULL,
                       NULL);
     if(!iRet)
     {
        SCWrite(pCon,"ERROR: token command already exixts???!!",eError);
     }
     return iRet;                  
     
  }              
/*-------------------------------------------------------------------------*/
  int TokenWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
                int argc, char *argv[])
  {
     char pBueffel[256];
    
     if(argc < 2)
     {
       SCWrite(pCon,"ERROR: expected subcommand to token",eError);
       return 0;
     }
     
     /* handle grab */
     if(strcmp(argv[1],"grab") == 0)
     {
        /* check user rights */
        if(usUser < SCGetRights(pCon))
        {
          SCWrite(pCon,"ERROR: you are not authorised to grab anything at all!",
                  eError);
          return 0;        
        }
        /* is there already a grab? */
        if(iToken)
        {
          SCWrite(pCon,"ERROR: Somebody else has already control! You are REJECTED",
                  eError);
          return 0;        
        }
        /* is somebody doing a scan ? */
        if(GetStatus() != eEager)
        {
          SCWrite(pCon,"ERROR: you cannot grab control while a scan is still running",
                  eError);
          return 0;        
        }
        /* we can do it */
        iToken = 1;
        TaskSignal(pServ->pTasker,TOKENGRAB,NULL);
        pCon->iGrab = 0; /* to enable us to do commands */
        SCSendOK(pCon);
        return 1;
     }
     else if(strcmp(argv[1],"release") == 0)
     {
       if(pCon->iGrab != 0)
       {
         SCWrite(pCon,"ERROR: you cannot release somebody elses control token!",
                 eError);
         return 0;        
       }
       iToken = 0;
       TaskSignal(pServ->pTasker,TOKENRELEASE,NULL);
       SCSendOK(pCon);
       return 1;
     }
     else if(strcmp(argv[1],"force") == 0)
     {
        /* check force password */
        if(argc < 3)
        {
           SCWrite(pCon,"ERROR: I need a password for this operation! Request REJECTED",
                   eError);
           return 0;        
        }
        if(strcmp(argv[2],pTokenPassword) == 0)
        {
          if(usMugger < SCGetRights(pCon))
          {
            SCWrite(pCon,"ERROR: Manager privilege required to force your way into a SICS server",
                    eError);
            SCWrite(pCon,"ERROR: You are REJECTED",eError);
            return 0;        
          }
          iToken = 0;
          TaskSignal(pServ->pTasker,TOKENRELEASE,0);
          SCWrite(pCon,"Token forcefully released, no grab active",eWarning);
          return 1;
        }
        else
        {
           SCWrite(pCon,"ERROR: The specified password is WRONG!",eError);
           SCWrite(pCon,"ERROR: Your request has been REJECTED",eError);
           return 0;
        }
     }
     /* default */
     sprintf(pBueffel,"ERROR: subcommand %s to token NOT understood",
                   argv[1]);
     SCWrite(pCon,pBueffel,eError);              
     return 0;        

  }          
