/*
 * DANG_BEGIN_MODULE
 * 
 * PHASE0 initialization:
 *
 * This is where you initialize anything related to the UNIX environment.
 * Do version & os detection, at console/not at console, read config info,
 * etc. here
 *
 * DANG_END_MODULE
 * 
 * DANG_BEGIN_CHANGELOG
 *
 * $Date: $
 * $Source: $
 * $Revision: $
 * $State: $
 *
 * $Log: $
 *
 * DANG_END_CHANGELOG
 */

#include "dosemu.h"
#include "base/memory.h"
#include "base/hlt.h"
#include "base/port.h"
#include "base/timers.h"
#include "base/int.h"
#include "env/setup.h"
#include "base/arch.h"
#include "base/keyb.h"
#include "base/phase.h"
#include "base/misc.h"
#include "base/ioctlq.h"
#include "env/vc.h"

#include <sys/stat.h>

/*
 * DANG_BEGIN_FUNCTION stdio_init
 *
 * description:
 *  Initialize stdio, open debugging output file if user specified one
 * 
 * DANG_END_FUNCTION
 */
static void stdio_init(void)
{
  if(dbg_fd) {
    warn("DBG_FD already set\n");
    return;
  }

  if (config.debugout) {
    dbg_fd = fopen(config.debugout,"w");
    if (!dbg_fd) {
      error("can't open \"%s\" for writing debug file\n", config.debugout);
      exit(1);
    }
  }
  else {
    dbg_fd = 0;
    warn("No debug output file specified, debugging information will not be printed");
  }
  sync();  /* for safety */
  setbuf(stdout, NULL);
}

/*
 * DANG_BEGIN_FUNCTION tmpdir_init
 *
 * description:
 *  Initialize the temporary directory
 * 
 * DANG_END_FUNCTION
 */
static void tmpdir_init(void)
{
#ifdef CONFIG_RUN_AS_ROOT
  priv_off();
#endif
  /* create tmpdir */
  mkdir(tmpdir, S_IREAD | S_IWRITE | S_IEXEC);
#ifdef CONFIG_RUN_AS_ROOT
  priv_on();
#endif
}

/*
 * DANG_BEGIN_FUNCTION phase0_init
 * 
 * description:
 *  Fire up phase 0
 *
 * DANG_END_FUNCTION
 */
void phase0_init(int argc, char **argv)
{
  if (0 == geteuid()) {
    warn("I am root\n");
    i_am_root = 1;
  } else {
    if (getuid() != geteuid()) {
      fprintf(stderr, "Can't setuid to anyone else but root\n");
      exit(1);
    }
  }
#ifndef CONFIG_RUN_AS_ROOT
  if (i_am_root)
    priv_off();
#endif

  /* the transposal of (config_|stdio_)init allows the addition of -o */
  /* to specify a debug out filename, if you're wondering */

  config_init(argc, argv);	/* parse the commands & config file(s) */
  stdio_init();		        /* initialize stdio & open debug file  */
  tmpdir_init();

  g_printf("getuid() = %d, geteuid() = %d\n", getuid(), geteuid());

  /* do any platform specific init's */
  arch_init();

  /* initialize the internal tables */
  hlt_init();
  int_init();
  port_init();
  memcheck_init();
  timer_init();
  signal_init();
  io_select_init();

  /* initialize the keyboard */
  if (keyboard_init() != 0) {
    error("ERROR: can't open keyboard\n");
    leavedos(19);
  }
  if (!config.vga)
    config.allowvideoportaccess = 0;

  /* get the video memory addresses */
  video_config_init();

  /* initialize the environment */
  env_phase0_init();
}

void phase0_term(void)
{
  /* remove tmpdir */
  rmdir(tmpdir);
  
  g_printf("LEAVE: calling arch_term()\n");
  arch_term();
  g_printf("LEAVE: calling env_term\n");
  env_terminate();
  g_printf("LEAVE: calling keyboard_close\n");
  fflush(stderr);
  fflush(stdout);
  keyboard_close();

  if (config.detach) {
    vt_restore(config.detach);
    vt_disallocate();
  }

  show_ints(0, 0x33);
}


