/* Copyright (C) 1999 Thorsten Kukuk
   Author: Thorsten Kukuk <kukuk@suse.de>

   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, or (at your option)
   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.  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define _GNU_SOURCE

#include <unistd.h>
#include <sys/signal.h>
#include <pthread.h>

#include "log_msg.h"
#include "nis_cache.h"
#include "nis_cachemgr.h"

pthread_mutex_t file_lock;
directory_obj *nis_cold_start;

static bool_t
reloadColdStartFile (void)
{
  bool_t ret = FALSE;
  nis_result *result;

  pthread_mutex_lock (&file_lock);

  result = nis_lookup (nis_local_directory (), 0);

  if (result == NULL || result->status != NIS_SUCCESS)
    {
      log_msg (LOG_ERR, "Could not lookup %s: %s",
               nis_local_directory (), nis_sperrno (result->status));
      goto exit;
    }
  if (!writeColdStartFile (&result->objects.objects_val->DI_data))
    log_msg (LOG_ERR, "Could not write NIS_COLD_START");
  if (nis_cold_start)
    nis_free_directory (nis_cold_start);
  nis_cold_start = nis_clone_directory (&result->objects.objects_val->DI_data,
					NULL);
  nis_freeresult (result);

  ret = TRUE;

 exit:
  pthread_mutex_unlock (&file_lock);

  return ret;
}

/* sig_reloader is called by the alarm signal. It's time to
   update the NIS_COLD_START file. */
static void
sig_reloader (int ignore __attribute__ ((unused)))
{
  if (reloadColdStartFile ())
    {
      signal (SIGALRM, sig_reloader);
      alarm (nis_cold_start->do_ttl);
    }
  else
    {
      signal (SIGALRM, sig_reloader);
      alarm (5); /* Try again in 5 seconds */
    }
}

nis_error
nis_coldcache_init (void)
{
  nis_cold_start = readColdStartFile ();

  if (!nis_cold_start)
    return NIS_COLDSTART_ERR;

  /* At first reload ColdStartFile, use sighandler for this ;-) */
  sig_reloader (0);

  return NIS_SUCCESS;
}


bool_t
nis_cache_read_coldstart_1_svc (void *argp __attribute__ ((unused)),
				void *result __attribute__ ((unused)),
				struct svc_req *rqstp __attribute__ ((unused)))
{
  bool_t retval = TRUE;

  /* Use sighandler for reloading NIS_COLD_START and reseting timer */
  sig_reloader (0);

  return retval;
}
