/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dir-watch-kqueue.c  OS specific directory change notification for message bus
 *
 * Copyright (C) 2003 Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * 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 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#include "bus.h"
#include <dbus/dbus-watch.h>

#include <dbus/dbus-internals.h>
#include <dbus/dbus-list.h>
#include "dir-watch.h"

#define MAX_DIRS_TO_WATCH 128

static int kq = -1;
static int fds[MAX_DIRS_TO_WATCH];
static char *dirs[MAX_DIRS_TO_WATCH];
static int num_fds = 0;
static DBusWatch *watch = NULL;
static DBusLoop *loop = NULL;

static dbus_bool_t
_kqueue_watch_callback (DBusWatch *watch, unsigned int condition, void *data)
{
  return dbus_watch_handle (watch, condition);
}

static dbus_bool_t
_handle_kqueue_watch (DBusWatch *watch, unsigned int flags, void *data)
{
  struct kevent ev;
  struct timespec nullts = { 0, 0 };
  int res;
  pid_t pid;

  res = kevent (kq, NULL, 0, &ev, 1, &nullts);

  /* Sleep for half a second to avoid a race when files are install(1)'d
   * to system.d. */
  usleep(500000);

  if (res > 0)
    {
      pid = getpid ();
      _dbus_verbose ("Sending SIGHUP signal on reception of a kevent\n");
      (void) kill (pid, SIGHUP);
    }
  else if (res < 0 && errno == EBADF)
    {
      kq = -1;
      if (watch != NULL)
	{
	  _dbus_loop_remove_watch (loop, watch, _kqueue_watch_callback, NULL);
          _dbus_watch_unref (watch);
	  watch = NULL;
	}
      pid = getpid ();
      _dbus_verbose ("Sending SIGHUP signal since kqueue has been closed\n");
      (void) kill (pid, SIGHUP);
    }

  return TRUE;
}

static int
_init_kqueue (BusContext *context)
{
  int ret = 0;

  if (kq < 0)
    {

      kq = kqueue ();
      if (kq < 0)
        {
          _dbus_warn ("Cannot create kqueue; error '%s'\n", _dbus_strerror (errno));
	  goto out;
	}

        loop = bus_context_get_loop (context);

        watch = _dbus_watch_new (kq, DBUS_WATCH_READABLE, TRUE,
                                 _handle_kqueue_watch, NULL, NULL);

	if (watch == NULL)
          {
            _dbus_warn ("Unable to create kqueue watch\n");
	    close (kq);
	    kq = -1;
	    goto out;
	  }

	if (!_dbus_loop_add_watch (loop, watch, _kqueue_watch_callback,
                                   NULL, NULL))
          {
            _dbus_warn ("Unable to add reload watch to main loop");
	    close (kq);
	    kq = -1;
	    _dbus_watch_unref (watch);
	    watch = NULL;
            goto out;
	  }
    }

  ret = 1;

out:
  return ret;
}

void
bus_set_watched_dirs (BusContext *context, DBusList **directories)
{
  int new_fds[MAX_DIRS_TO_WATCH];
  char *new_dirs[MAX_DIRS_TO_WATCH];
  DBusList *link;
  int i, j, f, fd;
  struct kevent ev;

  if (!_init_kqueue (context))
    goto out;

  for (i = 0; i < MAX_DIRS_TO_WATCH; i++)
    {
      new_fds[i] = -1;
      new_dirs[i] = NULL;
    }

  i = 0;
  link = _dbus_list_get_first_link (directories);
  while (link != NULL)
    {
      new_dirs[i++] = (char *)link->data;
      link = _dbus_list_get_next_link (directories, link);
    }

  /* Look for directories in both the old and new sets, if
   * we find one, move its data into the new set.
   */
  for (i = 0; new_dirs[i]; i++)
    {
      for (j = 0; j < num_fds; j++)
        {
          if (dirs[j] && strcmp (new_dirs[i], dirs[j]) == 0)
            {
              new_fds[i] = fds[j];
	      new_dirs[i] = dirs[j];
	      fds[j] = -1;
	      dirs[j] = NULL;
	      break;
	    }
	}
    }

  /* Any directory we find in "fds" with a nonzero fd must
   * not be in the new set, so perform cleanup now.
   */
  for (j = 0; j < num_fds; j++)
    {
      if (fds[j] != -1)
        {
          close (fds[j]);
	  dbus_free (dirs[j]);
	  fds[j] = -1;
	  dirs[j] = NULL;
	}
    }

  for (i = 0; new_dirs[i]; i++)
    {
      if (new_fds[i] == -1)
        {
          /* FIXME - less lame error handling for failing to add a watch;
	   * we may need to sleep.
	   */
          fd = open (new_dirs[i], O_RDONLY);
          if (fd < 0)
            {
              if (errno != ENOENT)
                {
                  _dbus_warn ("Cannot open directory '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
                  goto out;
                }
              else
                {
                  new_fds[i] = -1;
                  new_dirs[i] = NULL;
                  continue;
                }
            }

          EV_SET (&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
                  NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_RENAME, 0, 0);
          if (kevent (kq, &ev, 1, NULL, 0, NULL) == -1)
            {
              _dbus_warn ("Cannot setup a kevent for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
              close (fd);
              goto out;
            }

	  new_fds[i] = fd;
	  new_dirs[i] = _dbus_strdup (new_dirs[i]);
	  if (!new_dirs[i])
            {
              /* FIXME have less lame handling for OOM, we just silently fail to
	       * watch.  (In reality though, the whole OOM handling in dbus is
	       * stupid but we won't go into that in this comment =) )
	       */
              close (fd);
	      new_fds[i] = -1;
	    }
	}
    }

  num_fds = i;

  for (i = 0; i < MAX_DIRS_TO_WATCH; i++)
    {
      fds[i] = new_fds[i];
      dirs[i] = new_dirs[i];
    }

 out:
  ;
}
