#include "kernel.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <limits.h>
#include "sockets.h"

#include "def.h"
#include "defstruc.h"
#include "connstrc.h"

#include "event.h"
#include "master.h"
#include "telnet.h"
#include "syslogif.h"
#include "sshproxyif.h"
#include "buildmsg.h"

#include "Desk.Core.h"
#include "Desk.Resource.h"
#include "Desk.Event.h"
#include "Desk.EventMsg.h"
#include "Desk.Msgs.h"
#include "Desk.Error2.h"
#include "Desk.Icon.h"

#ifdef MEMORY_DEBUG
#include "memleak.h"
#endif

static void *module_globalPrivateWord;

Desk_bool global_quit = Desk_FALSE;

static FILE *memleakFile = NULL;

#ifdef MEMORY_DEBUG
void memleak_init(void)
{
  memleakFile = fopen("<Wimp$ScrapDir>.SSHMemleak","wb");
  if (memleakFile != NULL)
  {
    memleak_set_stream(memleakFile);
    memleak_verbose(TRUE);
  }
}

void memleak_finalise(void)
{
/*  if (memleakFile)
    fclose(memleakFile);*/
}

#endif

void app_finalise(void)
{
  xsyslogf(SYSLOG_FILE,LOG_INIT,"Killing SSHProxy...\n");
  sshinterface_finalise();
  telnet_finalise();
  master_finalise();
  event_finalise(module_globalPrivateWord);
  #ifdef PROFILING
  _fmapstore("<wimp$scrapdir>.sshprof");
  #endif
#ifdef MEMORY_DEBUG
  memleak_finalise();
#endif
}

#ifdef DEBUG
void sighand(int sig)
{
  xsyslogf(SYSLOG_FILE,LOG_DEBUG_HIGH,"sighand: got signal %d - exiting\n",sig);
  exit(5);
}
#endif

int main(int argc, char *argv[])
{
  OSERROR *result;
  char          appname[64];
  char          portMessage[32];
  int           messageList[] = { 8, 0};
  long          port=2200;

  module_globalPrivateWord=0;

  xsyslogf(SYSLOG_FILE,LOG_INIT,"Starting SSHProxy... %s\n",welcomeMessage);
#ifdef DEBUG
  signal(SIGABRT,sighand);
  signal(SIGFPE,sighand);
  signal(SIGILL,sighand);
  signal(SIGINT,sighand);
  signal(SIGSEGV,sighand);
  signal(SIGTERM,sighand);
  signal(SIGSTAK,sighand);
  signal(SIGOSERROR,sighand);
#endif
  if (argv[1]!=NULL)
  {

    port = strtol(argv[1],NULL,10);
    if ((port == 0) || (port == LONG_MAX) || (port == LONG_MIN) || (port<0) )
      port = 2200;

  }

#ifdef MEMORY_DEBUG
  memleak_init();
#endif

  masterPort = port;
  Desk_Error2_Init_JumpSig();
  Desk_Resource_Initialise("SSHProxy");   /* resources in <Tester$Dir> */
  Desk_Msgs_LoadFile("messages");
  Desk_Msgs_Lookup("app.name:SSHProxy", appname, 64);
  sprintf(portMessage," (port %d)",port);
  strcat(appname,portMessage);
  Desk_Event_Initialise3(appname,310,messageList);
  Desk_EventMsg_Initialise();
#ifdef DEBUG
  /* put an icon on the iconbar so Zap's Read memory can find us */
  Desk_Icon_BarIcon("file_ffd",Desk_iconbar_LEFT);
#endif

  if ((result=event_initialise(module_globalPrivateWord))!=NULL)
  {
    Desk_Error2_CheckOS(result);
    return 4/*result*/;
  }


  if ((result=master_initialise())!=NULL)
  {
    /* if that didn't succeed, we must tidy up everything set up
     * beforehand, otherwise handlers will be left without
     * code to call etc
     */
    event_finalise(module_globalPrivateWord);
    Desk_Error2_CheckOS(result);
    return 4/*result*/;
  }

  if ((result=telnet_initialise())!=NULL)
  {
    master_finalise();
    event_finalise(module_globalPrivateWord);
    Desk_Error2_CheckOS(result);
    return 4/*result*/;
  }

  if ((result=sshinterface_initialise())!=NULL)
  {
    master_finalise();
    event_finalise(module_globalPrivateWord);
    telnet_finalise();
    Desk_Error2_CheckOS(result);
    return 4/*result*/;
  }

  /* if everything here went OK, we can attach the normal finalisation
   * code - don't do this before here, as we might try to finalise
   * something that hasn't been initialised
   */
  atexit(app_finalise);

  while (!global_quit)
    event_poll_single(TRUE);


  return 0;
}


