/* -*- mode: C; c-file-style: "gnu" -*- */
/* dir-watch-inotify.c  OS specific directory change notification for message bus
 *
 * Copyright (C) 2003 Red Hat, Inc.
 *           (c) 2006 Mandriva
 *
 * 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 <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/inotify.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>

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

#define MAX_DIRS_TO_WATCH 128
#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
#define INOTIFY_BUF_LEN (1024 * (INOTIFY_EVENT_SIZE + 16))

/* use a static array to avoid handling OOM */
static int wds[MAX_DIRS_TO_WATCH];
static char *dirs[MAX_DIRS_TO_WATCH];
static int num_wds = 0;
static int inotify_fd = -1;
static DBusWatch *watch = NULL;
static DBusLoop *loop = NULL;

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

static dbus_bool_t
_handle_inotify_watch (DBusWatch *passed_watch, unsigned int flags, void *data)
{
  char buffer[INOTIFY_BUF_LEN];
  ssize_t ret = 0;
  int i = 0;
  pid_t pid;
  dbus_bool_t have_change = FALSE;

  ret = read (inotify_fd, buffer, INOTIFY_BUF_LEN);
  if (ret < 0)
    _dbus_verbose ("Error reading inotify event: '%s'\n", _dbus_strerror(errno));
  else if (!ret)
    _dbus_verbose ("Error reading inotify event: buffer too small\n");

  while (i < ret)
    {
      struct inotify_event *ev;
      pid = _dbus_getpid ();

      ev = (struct inotify_event *) &buffer[i];
      i += INOTIFY_EVENT_SIZE + ev->len;
#ifdef DBUS_ENABLE_VERBOSE_MODE
      if (ev->len)
        _dbus_verbose ("event name: '%s'\n", ev->name);
      _dbus_verbose ("inotify event: wd=%d mask=%u cookie=%u len=%u\n", ev->wd, ev->mask, ev->cookie, ev->len);
#endif
      _dbus_verbose ("Sending SIGHUP signal on reception of a inotify event\n");
      have_change = TRUE;
    }
  if (have_change)
    (void) kill (pid, SIGHUP);

  return TRUE;
}

#include <stdio.h>

static void
_set_watched_dirs_internal (DBusList **directories)
{
  int new_wds[MAX_DIRS_TO_WATCH];
  char *new_dirs[MAX_DIRS_TO_WATCH];
  DBusList *link;
  int i, j, wd;

  for (i = 0; i < MAX_DIRS_TO_WATCH; i++)
    {
      new_wds[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_wds; j++)
        {
          if (dirs[j] && strcmp (new_dirs[i], dirs[j]) == 0)
            {
              new_wds[i] = wds[j];
              new_dirs[i] = dirs[j];
              wds[j] = -1;
              dirs[j] = NULL;
              break;
            }
        }
    }

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

  for (i = 0; new_dirs[i]; i++)
    {
      if (new_wds[i] == -1)
        {
          /* FIXME - less lame error handling for failing to add a watch; we may need to sleep. */
          wd = inotify_add_watch (inotify_fd, new_dirs[i], IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM);
          if (wd < 0)
            {
              /* Not all service directories need to exist. */
              if (errno != ENOENT)
                {
                  _dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
                  goto out;
                }
              else
                {
                  new_wds[i] = -1;
                  new_dirs[i] = NULL;
                  continue;
                }
            }
          new_wds[i] = wd;
          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 =) )
               */
              inotify_rm_watch (inotify_fd, wd);
              new_wds[i] = -1;
            }
        }
    }

  num_wds = i;

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

 out:;
}

#include <stdio.h>
static void
_shutdown_inotify (void *data)
{
  DBusList *empty = NULL;

  if (inotify_fd == -1)
    return;

  _set_watched_dirs_internal (&empty);

  close (inotify_fd);
  inotify_fd = -1;
  if (watch != NULL)
    {
      _dbus_loop_remove_watch (loop, watch, _inotify_watch_callback, NULL);
      _dbus_watch_unref (watch);
      _dbus_loop_unref (loop);
    }
  watch = NULL;
  loop = NULL;
}

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

  if (inotify_fd == -1)
    {
#ifdef HAVE_INOTIFY_INIT1
      inotify_fd = inotify_init1 (IN_CLOEXEC);
      /* This ensures we still run on older Linux kernels.
       * https://bugs.freedesktop.org/show_bug.cgi?id=23957
       */
      if (inotify_fd < 0)
        inotify_fd = inotify_init ();
#else
      inotify_fd = inotify_init ();
#endif
      if (inotify_fd <= 0)
        {
          _dbus_warn ("Cannot initialize inotify\n");
          goto out;
        }
      loop = bus_context_get_loop (context);
      _dbus_loop_ref (loop);

      watch = _dbus_watch_new (inotify_fd, DBUS_WATCH_READABLE, TRUE,
                               _handle_inotify_watch, NULL, NULL);

      if (watch == NULL)
        {
          _dbus_warn ("Unable to create inotify watch\n");
          goto out;
        }

      if (!_dbus_loop_add_watch (loop, watch, _inotify_watch_callback,
                                 NULL, NULL))
        {
          _dbus_warn ("Unable to add reload watch to main loop");
          _dbus_watch_unref (watch);
          watch = NULL;
          goto out;
        }

      if (!_dbus_register_shutdown_func (_shutdown_inotify, NULL))
      {
          _dbus_warn ("Unable to register shutdown func");
          _dbus_watch_unref (watch);
          watch = NULL;
          goto out;
      }
    }

  ret = 1;

out:
  return ret;
}

void
bus_set_watched_dirs (BusContext *context, DBusList **directories)
{
  if (!_init_inotify (context))
    return;

  _set_watched_dirs_internal (directories);
}
