/* -*- 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
_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);

  if (watch != NULL)
    {
      _dbus_loop_remove_watch (loop, watch);
      _dbus_watch_invalidate (watch);
      _dbus_watch_unref (watch);
      _dbus_loop_unref (loop);
    }
  watch = NULL;
  loop = NULL;

  close (inotify_fd);
  inotify_fd = -1;
}

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))
        {
          _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);
}
