lpc4/lib/
lpc4/lib/doc/efun/
lpc4/lib/doc/lfun/
lpc4/lib/doc/operators/
lpc4/lib/doc/simul_efuns/
lpc4/lib/doc/types/
lpc4/lib/etc/
lpc4/lib/include/
lpc4/lib/include/arpa/
lpc4/lib/obj/d/
lpc4/lib/save/
lpc4/lib/secure/
lpc4/lib/std/
lpc4/lib/std/living/
#include "efuns.h"
#include <signal.h>
#include <sys/param.h>
#include "main.h"
#include "dynamic_buffer.h"
#include "simulate.h"
#include "stralloc.h"

/* fixa: simplify_path(), asynkron input */

#ifdef F_SLEEP
void f_sleep(int num_arg,struct svalue *argp)
{
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function sleep() only supported in batchmode\n");
  sleep(sp->u.number);
  pop_stack();
}
#endif

#ifdef F_GETCHAR
void f_getchar(int num_arg,struct svalue *argp)
{
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function getchar() only supported in batchmode\n");
  push_number(getchar());
}
#endif

#ifdef F_EXIT
void f_exit(int num_arg,struct svalue *argp)
{
  extern do_sync_database();
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function exit() only supported in batchmode\n");
  do_sync_database();
  exit(sp->u.number);
}
#endif

#ifdef F_GETS
void f_gets(int num_arg,struct svalue *argp)
{
  char buffer[READ_FILE_MAX_SIZE],*c;
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function gets() only supported in batchmode\n");
  c=fgets(buffer,READ_FILE_MAX_SIZE,stdin);
  if(!c)
  {
    push_number(0);
  }else{
    push_new_shared_string(c);
  }
}
#endif

#ifdef F_POPEN
void f_popen(int num_arg,struct svalue *argp)
{
  char foo[1000];
  void sig_child(int s);
  FILE *fooo;
  int c;

  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function popen() only supported in batchmode\n");
  init_buf();
  signal(SIGCHLD, SIG_DFL);
  fooo=popen(strptr(argp),"r");
  
  pop_stack();
  if(fooo)
  {
    do{
      c=fread(foo,1,sizeof(foo),fooo);
      my_binary_strcat(foo,c);
    }while(!feof(fooo));
    pclose(fooo);
    push_shared_string(free_buf());
  }else{
    push_zero();
  }
  signal(SIGCHLD, sig_child);
}
#endif

#ifdef F_PERROR
void f_perror(int num_arg,struct svalue *argp)
{
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function perror() only supported in batchmode\n");
  fprintf(stderr,"%s",strptr(argp));
  pop_stack();
}
#endif

#ifdef F_GETENV
void f_getenv(int num_arg,struct svalue *argp)
{
  char *fuu;
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function getenv() only supported in batchmode\n");
  fuu=getenv(strptr(argp));
  pop_stack();
  if(fuu)
  {
    push_new_shared_string(fuu);
  }else{
    push_zero();
  }
}
#endif

#ifdef F_CD
void f_cd(int num_arg,struct svalue *argp)
{
  int e;
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function cd() only supported in batchmode\n");
  e=chdir(strptr(argp+0));
  pop_stack();
  push_number(e);
}
#endif

#ifdef F_GETCWD
void f_getcwd(int num_arg,struct svalue *argp)
{
  char *e;
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function getcwd() only supported in batchmode\n");
#ifdef HAVE_GETCWD
  e=(char *)getcwd(0,1000); 
#else
  e=(char *)getwd((char *)malloc(MAXPATHLEN+1));
  if(!e)
    fatal("Couldn't fetch current path.\n");
#endif
  push_new_shared_string(e);
  free(e);
}
#endif

#ifdef F_PUTENV
void f_putenv(int num_arg,struct svalue *argp)
{
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function putenv() only supported in batchmode\n");
  putenv(strptr(argp));
  pop_stack();
}
#endif


#ifdef F_FORK
void f_fork(int num_arg,struct svalue *argp)
{
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("Function fork() only supported in batchmode\n");
  push_number(fork());
}
#endif

#ifdef F_SETUGID
void f_setugid(int num_arg,struct svalue *argp)
{
  int a,b;
  if(!batch_mode &&
     (!current_object->eff_user || current_object->eff_user!=master_ob->user))
    error("setuguid() may only be called by Root.\n");
  a=argp[0].u.number;
  b=argp[1].u.number;
  pop_stack();
  pop_stack();
  b=setgid((gid_t)b); /* gid_t == long */
  a=setuid((uid_t)a); /* uid_t == long */
  push_number(!!(a+b));
}
#endif