// Copyright, 2001-2003, Astra Network Inc.  All Rights Reserved

// This source code has been published by Astra Network Inc. However, any
// use, reproduction, modification, distribution or transfer of this
// software, or any software which includes or is based upon any of this
// code, is only permitted if expressly authorized by a written license
// agreement from Astra. Contact your Astra representative directly for
// more information.

#include <olmod.h>
#include <alive_struct.h>
#include <errno.h>
#include <signal.h>

olmod_error_t
alive_module_init ()
{
  return kMod_OK;
}

olmod_blackbox_t *
alive_module_inst (pid_t process, olmod_arglist_t * static_args)
{
  alive_data_t *blackbox;

  if (!(blackbox = (alive_data_t *) malloc (sizeof (alive_data_t))))
    {
      printf ("mod_alive: malloc failed\n");
      return NULL;
    }
  blackbox->process = process;

  return blackbox;
}

olmod_error_t
alive_module_set (olmod_blackbox_t * data, int64_t var)
{
  return kMod_OK;
}

int64_t
alive_module_get (olmod_blackbox_t * data, olmod_arglist_t * dynamic_args)
{
  /* pid 0 has different meaning on different systems, 
   * we will always return 0 because kill(0, ...) it not 
   * what we want.
   */
  if (((alive_data_t *) data)->process == 0)
    return (LTOQ (0l));

  /* To find if a pid exists, simply send a NULL signal to it,
   * if it does not exist errno is ESRCH
   */
  if (kill (((alive_data_t *) data)->process, 0) < 0)
    {
      if (errno == ESRCH)
	return (LTOQ (0l));	/* Process doesn't exist */
      else if (errno == EPERM)
	{
	  /* Process exists but we do not
	   * have permission to send a signal to it.
	   * The return code of 2 does not mean anything
	   * it is simply for debugging, do not depend on
	   * it.
	   */
	  return (LTOQ (2l));
	}
      else
	{
	  /* FIXME better logging of strange errors like this */
	  perror ("kill() returned strange error\n");
	  return (LTOQ (-1));
	}
    }
  /* It must exist and we must have permission to signal it. */
  return (LTOQ (1l));
}

void
alive_module_deinst (olmod_blackbox_t * data)
{
  free (data);
}

void
alive_module_deinit ()
{
}
