/*
BOIL (Brunni's Own Interpreter Language)
(c) 1998 netEstate (http://www.netestate.de/, info@netestate.de),
Michael Brunnbauer & Markus Hendel, Gesellschaft fuer Netzwerkkommunikation bR
Am Bluetenanger 8, 80995 Muenchen, Germany

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 2 of the License, or
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "general.h"
#include "handles.cc"
#include "boil.h"
#include "boil.tab.h"
#include "libs.h"
 
int args_printf[]= { TYPE_VALUE_STRING,
                     0 };

flowctrl func_printf(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_ULONG;
  back.returnval.val.ulongval=0;

  if (!defined((*args)[0].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","printf: string not defined");
      return back;
    };

  
  back.returnval.val.ulongval=
    (unsigned long) fwrite((void*) (*args)[0].stringval.zgr,1,
                           strlen((*args)[0].stringval),outstream);
  fflush(outstream);
  return back;
};

int args_sleep[]= { TYPE_VALUE_ULONG,
                    0 };

flowctrl func_sleep(type_block* aktblock,opt* options,
                    joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_VOID;

  sleep((*args)[0].val.ulongval);
  return back;
};

int args_getenv[]= { TYPE_VALUE_STRING,
                     0 };

flowctrl func_getenv(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_STRING;

  if (!defined((*args)[0].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","getenv: string not defined");
      return back;
    };

  back.returnval.stringval=getenv((*args)[0].stringval);

  if (!defined(back.returnval.stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","no such environment-variable");
    };
  return back;
};

int args_setenv[]= { TYPE_VALUE_STRING,
                     TYPE_VALUE_STRING,
                     TYPE_VALUE_ULONG,
                     0 };

flowctrl func_setenv(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_ULONG;
  back.returnval.val.ulongval=0;

  if (!defined((*args)[0].stringval) ||
      !defined((*args)[1].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","setenv: string not defined");
      return back;
    };
  
  if (!setenv((*args)[0].stringval,
              (*args)[1].stringval,
              (*args)[2].val.ulongval))
    {
      back.returnval.val.ulongval=1;
    }
  else
    {
      setvarulong("error",1);
      setvarstring("perror","setenv: setenv() failed");
    };
  
  return back;
}

int args_srandom[]= { TYPE_VALUE_ULONG,
                      0 };

flowctrl func_srandom(type_block* aktblock,opt* options,
                      joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_VOID;

  srandom((unsigned int) (*args)[0].val.ulongval);
  return back;
};

int args_random[]= { 0 };

flowctrl func_random(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_LONG;
  back.returnval.val.longval=random();
  return back;
}

int args_crypt[]= { TYPE_VALUE_STRING,
                    0 };

flowctrl func_crypt(type_block* aktblock,opt* options,
                    joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_STRING;
  back.returnval.stringval=0;

  if (!defined((*args)[0].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","crypt: string not defined");
      return back;
    };

  char salt[3];
  salt[2]=0;
  char rand;
  
  rand=(char) ( random() % 128 );
  while (!((rand>=46 && rand<=57) ||
           (rand>=65 && rand<=90) ||
           (rand>=97 && rand<=122))) { rand++; };
  salt[0]=rand;

  rand=(char) ( random() % 128 );
  while (!((rand>=46 && rand<=57) ||
           (rand>=65 && rand<=90) ||
           (rand>=97 && rand<=122))) { rand++; };
  salt[1]=rand;

  back.returnval.stringval=crypt((*args)[0].stringval,salt);
  if (!defined(back.returnval.stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","crypt: crypt() failed");
    };

  return back;
}

int args_waitpid[] = { 0 };

flowctrl func_waitpid(type_block* aktblock,opt* options,
                      joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_LONG;
  back.returnval.val.longval=-1;

  back.returnval.val.longval=(long) waitpid(-1,0,WNOHANG|WUNTRACED);
  if (back.returnval.val.longval==-1)
    {
      setvarulong("error",1);
      setvarstring("perror","waitpid: waitpid() failed");
    };
  return back;
}

int args_sigcld[] = { TYPE_VALUE_ULONG,
                      0 };

flowctrl func_sigcld(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_VOID;

  if ((*args)[0].val.ulongval)
    {
      if (signal(SIGCHLD,&cldhandler)==SIG_ERR)
	{
	  setvarulong("error",1);
	  setvarstring("perror","sigcld: signal() failed");
	};
    }
  else
    {
      if (signal(SIGCHLD,SIG_IGN)==SIG_ERR)
        {
          setvarulong("error",1);
          setvarstring("perror","sigcld: signal() failed");
        };
    };
  
  return back;
}

int args_getpid[] = { 0 };

flowctrl func_getpid(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_LONG;
  back.returnval.val.longval=-1;

  back.returnval.val.longval=(long) getpid();
  return back;
}

int args_system[] = { TYPE_VALUE_STRING,
                      0 };

flowctrl func_system(type_block* aktblock,opt* options,
                     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_LONG;
  back.returnval.val.longval=-1;

  if (!defined((*args)[0].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","system: string not defined");
      return back;
    };

  back.returnval.val.longval=system((*args)[0].stringval);
  if (back.returnval.val.longval==127) { back.returnval.val.longval=-1; };
  if (back.returnval.val.longval==-1)
    {
      setvarulong("error",1);
      setvarstring("perror","system: system() failed");
    };
  return back;
}

