summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schlemmer <azarah@gentoo.org>2005-08-02 20:52:53 +0000
committerMartin Schlemmer <azarah@gentoo.org>2005-08-02 20:52:53 +0000
commit65dc5a20a4599b2312bd66d30bcb7531aad085da (patch)
tree1561dad01a726e8c8976f10fbe1c748ac660f6cd /app-admin/gamin/files
parentFixed digest (diff)
downloadhistorical-65dc5a20a4599b2312bd66d30bcb7531aad085da.tar.gz
historical-65dc5a20a4599b2312bd66d30bcb7531aad085da.tar.bz2
historical-65dc5a20a4599b2312bd66d30bcb7531aad085da.zip
Update version.
Package-Manager: portage-2.0.51.22-r2
Diffstat (limited to 'app-admin/gamin/files')
-rw-r--r--app-admin/gamin/files/digest-gamin-0.1.31
-rw-r--r--app-admin/gamin/files/gamin-0.1.3-freebsd.patch100
-rw-r--r--app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch884
3 files changed, 985 insertions, 0 deletions
diff --git a/app-admin/gamin/files/digest-gamin-0.1.3 b/app-admin/gamin/files/digest-gamin-0.1.3
new file mode 100644
index 000000000000..c631ea112523
--- /dev/null
+++ b/app-admin/gamin/files/digest-gamin-0.1.3
@@ -0,0 +1 @@
+MD5 1670da322c89ad56e778d36e7fb7c9e9 gamin-0.1.3.tar.gz 518087
diff --git a/app-admin/gamin/files/gamin-0.1.3-freebsd.patch b/app-admin/gamin/files/gamin-0.1.3-freebsd.patch
new file mode 100644
index 000000000000..d732c7f3e4b8
--- /dev/null
+++ b/app-admin/gamin/files/gamin-0.1.3-freebsd.patch
@@ -0,0 +1,100 @@
+diff -ur -x '*~' gamin-0.1.2/libgamin/gam_api.c gamin-0.1.2-fbsd/libgamin/gam_api.c
+--- gamin-0.1.2/libgamin/gam_api.c 2005-06-15 12:53:25.000000000 +0200
++++ gamin-0.1.2-fbsd/libgamin/gam_api.c 2005-07-16 00:15:37.317345328 +0200
+@@ -421,7 +421,7 @@
+ {
+ char data[2] = { 0, 0 };
+ int written;
+-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
++#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ struct {
+ struct cmsghdr hdr;
+ struct cmsgcred cred;
+@@ -445,7 +445,7 @@
+ #endif
+
+ retry:
+-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
++#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ written = sendmsg(fd, &msg, 0);
+ #else
+ written = write(fd, &data[0], 1);
+@@ -655,7 +655,7 @@
+
+ s_uid = getuid();
+
+-#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
++#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) && !defined(__FreeBSD__)
+ /* Set the socket to receive credentials on the next message */
+ {
+ int on = 1;
+Only in gamin-0.1.2-fbsd/libgamin: gam_api.c.orig
+diff -ur -x '*~' gamin-0.1.2/libgamin/gam_data.c gamin-0.1.2-fbsd/libgamin/gam_data.c
+--- gamin-0.1.2/libgamin/gam_data.c 2005-05-18 16:45:04.000000000 +0200
++++ gamin-0.1.2-fbsd/libgamin/gam_data.c 2005-07-16 12:06:58.586806112 +0200
+@@ -17,6 +17,10 @@
+ #ifdef HAVE_PTHREAD_H
+ #include <pthread.h>
+
++# ifdef __GLIBC__
++# define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
++# endif
++
+ static int is_threaded = -1;
+ #endif
+
+@@ -471,7 +475,7 @@
+ }
+ if (is_threaded > 0) {
+ pthread_mutexattr_init(&attr);
+- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
++ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&ret->lock, &attr);
+ pthread_mutexattr_destroy(&attr);
+ }
+diff -ur -x '*~' gamin-0.1.2/server/gam_channel.c gamin-0.1.2-fbsd/server/gam_channel.c
+--- gamin-0.1.2/server/gam_channel.c 2005-06-15 13:02:34.000000000 +0200
++++ gamin-0.1.2-fbsd/server/gam_channel.c 2005-07-16 00:15:37.326343960 +0200
+@@ -29,7 +29,7 @@
+ {
+ char data[2] = { 0, 0 };
+ int written;
+-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
++#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ struct {
+ struct cmsghdr hdr;
+ struct cmsgcred cred;
+@@ -53,7 +53,7 @@
+ #endif
+
+ retry:
+-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
++#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ written = sendmsg(fd, &msg, 0);
+ #else
+ written = write(fd, &data[0], 1);
+@@ -100,7 +100,7 @@
+
+ s_uid = getuid();
+
+-#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
++#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) && !defined(__FreeBSD__)
+ /* Set the socket to receive credentials on the next message */
+ {
+ int on = 1;
+diff -ur -x '*~' gamin-0.1.2/tests/testing.c gamin-0.1.2-fbsd/tests/testing.c
+--- gamin-0.1.2/tests/testing.c 2005-06-13 10:59:29.000000000 +0200
++++ gamin-0.1.2-fbsd/tests/testing.c 2005-07-16 00:15:37.337342288 +0200
+@@ -436,9 +436,9 @@
+ return (-1);
+ }
+ /*
+- * wait at most 3 secs before declaring failure
++ * wait at most 7 secs before declaring failure
+ */
+- while ((delay < 30) && (testState.nb_events < nb_events + count)) {
++ while ((delay < 70) && (testState.nb_events < nb_events + count)) {
+ debugLoop(100);
+
+ /* printf("+"); fflush(stdout); */
+Only in gamin-0.1.2-fbsd/tests: testing.c.orig
diff --git a/app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch b/app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch
new file mode 100644
index 000000000000..c551a01e0dc6
--- /dev/null
+++ b/app-admin/gamin/files/gamin-0.1.3-inotify-legacy-backend.patch
@@ -0,0 +1,884 @@
+Add support for INotify Legacy backend (pre 0.24)
+
+diff -urpN gamin-0.1.2/configure.in gamin-0.1.2.az/configure.in
+--- gamin-0.1.2/configure.in 2005-07-13 13:10:43.000000000 +0200
++++ gamin-0.1.2.az/configure.in 2005-07-16 09:23:22.000000000 +0200
+@@ -225,16 +225,41 @@ dnl check if inotify backend is enabled
+ AM_CONDITIONAL(ENABLE_INOTIFY, test x$inotify = xtrue)
+
+ if test x$inotify = xtrue; then
+- AC_CHECK_HEADERS(linux/inotify.h)
++ AC_CHECK_HEADERS(linux/inotify.h,
++ [AC_CHECK_DECL(INOTIFY_IOCTL_MAGIC,
++ [AC_DEFINE(HAVE_INOTIFY_IOCTL_MAGIC,1,[Have legacy linux/inotify.h])],
++ [],[#include <linux/inotify.h>])])
+ AC_DEFINE(ENABLE_INOTIFY,1,[Use inotify as backend])
+ backends="${backends}, inotify"
+ fi
+
++if test x$os = xlinux-gnu; then
++ AC_ARG_ENABLE(inotify-legacy,
++ [ --enable-inotify-legacy Enable the INotify Legacy backend],
++ [case "${enableval}" in
++ yes) inotify_legacy=true ;;
++ no) inotify_legacy=false;;
++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-inotify-legacy) ;;
++ esac],[inotify_legacy=false])
++fi
++
++dnl check if inotify legacy backend is enabled
++AM_CONDITIONAL(ENABLE_INOTIFY_LEGACY, test x$inotify_legacy = xtrue)
++
++if test x$inotify_legacy = xtrue; then
++ AC_CHECK_HEADERS(linux/inotify.h,
++ [AC_CHECK_DECL(INOTIFY_IOCTL_MAGIC,
++ [AC_DEFINE(HAVE_INOTIFY_IOCTL_MAGIC,1,[Have legacy linux/inotify.h])],
++ [],[#include <linux/inotify.h>])])
++ AC_DEFINE(ENABLE_INOTIFY_LEGACY,1,[Use inotify legacy as backend])
++ backends="${backends}, inotify_legacy"
++fi
++
+ if test x$os != xBogusOS; then
+ AC_CHECK_FUNC(kevent,[have_kevent=1],)
+ if test x$have_kevent = x1 ; then
+ AC_ARG_ENABLE(kqueue,
+- [ --disable-kqueue Disable the KQueue backend],
++ [ --disable-kqueue Disable the KQueue backend],
+ [case "${enableval}" in
+ yes) kqueue=true ;;
+ no) kqueue=false ;;
+diff -urpN gamin-0.1.2/server/Makefile.am gamin-0.1.2.az/server/Makefile.am
+--- gamin-0.1.2/server/Makefile.am 2005-06-08 23:48:00.000000000 +0200
++++ gamin-0.1.2.az/server/Makefile.am 2005-07-16 09:26:06.000000000 +0200
+@@ -41,6 +41,7 @@ gam_server_SOURCES = \
+ gam_excludes.h \
+ local_inotify.h \
+ local_inotify_syscalls.h \
++ local_inotify_legacy.h \
+ gam_fs.c \
+ gam_fs.h \
+ server_config.h
+@@ -49,6 +50,10 @@ if ENABLE_INOTIFY
+ gam_server_SOURCES += gam_inotify.c gam_inotify.h
+ endif
+
++if ENABLE_INOTIFY_LEGACY
++gam_server_SOURCES += gam_inotify_legacy.c gam_inotify_legacy.h
++endif
++
+ if ENABLE_DNOTIFY
+ gam_server_SOURCES += gam_dnotify.c gam_dnotify.h
+ endif
+diff -urpN gamin-0.1.2/server/gam_inotify.c gamin-0.1.2.az/server/gam_inotify.c
+--- gamin-0.1.2/server/gam_inotify.c 2005-07-12 23:15:19.000000000 +0200
++++ gamin-0.1.2.az/server/gam_inotify.c 2005-07-16 09:24:31.000000000 +0200
+@@ -32,7 +32,7 @@
+ #include <glib.h>
+ #include "gam_error.h"
+ #include "gam_poll.h"
+-#ifdef HAVE_LINUX_INOTIFY_H
++#if defined(HAVE_LINUX_INOTIFY_H) && !defined(HAVE_INOTIFY_IOCTL_MAGIC)
+ #include <linux/inotify.h>
+ #else
+ #include "local_inotify.h"
+diff -urpN gamin-0.1.2/server/gam_inotify_legacy.c gamin-0.1.2.az/server/gam_inotify_legacy.c
+--- gamin-0.1.2/server/gam_inotify_legacy.c 1970-01-01 02:00:00.000000000 +0200
++++ gamin-0.1.2.az/server/gam_inotify_legacy.c 2005-07-16 09:36:47.000000000 +0200
+@@ -0,0 +1,611 @@
++/* gamin inotify_legacy backend
++ * Copyright (C) 2005 John McCutchan
++ *
++ * Based off of code,
++ * Copyright (C) 2003 James Willcox, Corey Bowers
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++
++#include "server_config.h"
++#define _GNU_SOURCE
++#include <fcntl.h>
++#include <signal.h>
++#include <unistd.h>
++#include <sys/ioctl.h>
++#include <stdio.h>
++#include <glib.h>
++#include "gam_error.h"
++#include "gam_poll.h"
++#if defined(HAVE_LINUX_INOTIFY_H) && defined(HAVE_INOTIFY_IOCTL_MAGIC)
++#include <linux/inotify.h>
++#else
++#include "local_inotify_legacy.h"
++#endif
++#include "gam_inotify_legacy.h"
++#include "gam_tree.h"
++#include "gam_event.h"
++#include "gam_server.h"
++#include "gam_event.h"
++#ifdef GAMIN_DEBUG_API
++#include "gam_debugging.h"
++#endif
++
++typedef struct {
++ char *path;
++ int wd;
++ int refcount;
++ GList *subs;
++ int busy;
++ gboolean deactivated;
++ int events;
++ int deactivated_events;
++} inotify_legacy_data_t;
++
++static GHashTable *path_hash = NULL;
++static GHashTable *wd_hash = NULL;
++
++G_LOCK_DEFINE_STATIC(inotify_legacy);
++
++static GIOChannel *inotify_legacy_read_ioc = NULL;
++
++static gboolean have_consume_idler = FALSE;
++
++static int inotify_legacy_device_fd = -1;
++
++static guint should_poll_mask = IN_MODIFY|IN_ATTRIB|IN_CLOSE_WRITE|IN_MOVED_FROM|IN_MOVED_TO|IN_DELETE|IN_CREATE|IN_DELETE_SELF|IN_UNMOUNT;
++
++static void
++gam_inotify_legacy_data_debug (gpointer key, gpointer value, gpointer user_data)
++{
++ inotify_legacy_data_t *data = (inotify_legacy_data_t *)value;
++
++ if (!data)
++ return;
++
++ int deactivated = data->deactivated;
++
++ GAM_DEBUG(DEBUG_INFO, "isub wd %d refs %d busy %d deactivated %d events (%d:%d): %s\n", data->wd, data->refcount, data->busy, deactivated, data->events, data->deactivated_events, data->path);
++}
++
++void
++gam_inotify_legacy_debug(void)
++{
++ if (inotify_legacy_device_fd == -1)
++ {
++ GAM_DEBUG(DEBUG_INFO, "Inotify device not opened\n");
++ return;
++ }
++
++ if (path_hash == NULL)
++ return;
++
++ GAM_DEBUG(DEBUG_INFO, "Inotify device fd = %d\n", inotify_legacy_device_fd);
++ GAM_DEBUG(DEBUG_INFO, "Dumping inotify_legacy subscriptions\n");
++ g_hash_table_foreach (path_hash, gam_inotify_legacy_data_debug, NULL);
++}
++
++static void print_mask(int mask)
++{
++ if (mask & IN_ACCESS)
++ {
++ GAM_DEBUG(DEBUG_INFO, "ACCESS\n");
++ }
++ if (mask & IN_MODIFY)
++ {
++ GAM_DEBUG(DEBUG_INFO, "MODIFY\n");
++ }
++ if (mask & IN_ATTRIB)
++ {
++ GAM_DEBUG(DEBUG_INFO, "ATTRIB\n");
++ }
++ if (mask & IN_CLOSE_WRITE)
++ {
++ GAM_DEBUG(DEBUG_INFO, "CLOSE_WRITE\n");
++ }
++ if (mask & IN_CLOSE_NOWRITE)
++ {
++ GAM_DEBUG(DEBUG_INFO, "CLOSE_WRITE\n");
++ }
++ if (mask & IN_OPEN)
++ {
++ GAM_DEBUG(DEBUG_INFO, "OPEN\n");
++ }
++ if (mask & IN_MOVED_FROM)
++ {
++ GAM_DEBUG(DEBUG_INFO, "MOVE_FROM\n");
++ }
++ if (mask & IN_MOVED_TO)
++ {
++ GAM_DEBUG(DEBUG_INFO, "MOVE_TO\n");
++ }
++ if (mask & IN_DELETE)
++ {
++ GAM_DEBUG(DEBUG_INFO, "DELETE\n");
++ }
++ if (mask & IN_CREATE)
++ {
++ GAM_DEBUG(DEBUG_INFO, "CREATE_SUBDIR\n");
++ }
++ if (mask & IN_DELETE_SELF)
++ {
++ GAM_DEBUG(DEBUG_INFO, "DELETE_SELF\n");
++ }
++ if (mask & IN_UNMOUNT)
++ {
++ GAM_DEBUG(DEBUG_INFO, "UNMOUNT\n");
++ }
++ if (mask & IN_Q_OVERFLOW)
++ {
++ GAM_DEBUG(DEBUG_INFO, "Q_OVERFLOW\n");
++ }
++ if (mask & IN_IGNORED)
++ {
++ GAM_DEBUG(DEBUG_INFO, "IGNORED\n");
++ }
++}
++
++static inotify_legacy_data_t *
++gam_inotify_legacy_data_new(const char *path, int wd)
++{
++ inotify_legacy_data_t *data;
++
++ data = g_new0(inotify_legacy_data_t, 1);
++ data->path = g_strdup(path);
++ data->wd = wd;
++ data->busy = 0;
++ data->refcount = 1;
++ data->deactivated_events = 0;
++ data->events = 0;
++
++ return data;
++}
++
++static void
++gam_inotify_legacy_data_free(inotify_legacy_data_t * data)
++{
++ if (data->refcount != 0)
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_data_free called with reffed data.\n");
++ g_free(data->path);
++ g_free(data);
++}
++
++static void
++gam_inotify_legacy_directory_handler_internal(const char *path, pollHandlerMode mode)
++{
++ inotify_legacy_data_t *data;
++ int path_fd, path_wd;
++ struct inotify_watch_request iwr;
++ switch (mode) {
++ case GAMIN_ACTIVATE:
++ GAM_DEBUG(DEBUG_INFO, "Adding %s to inotify_legacy\n", path);
++ break;
++ case GAMIN_DESACTIVATE:
++ GAM_DEBUG(DEBUG_INFO, "Removing %s from inotify_legacy\n", path);
++ break;
++ case GAMIN_FLOWCONTROLSTART:
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: Start flow control for %s\n", path);
++ break;
++ case GAMIN_FLOWCONTROLSTOP:
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: Stop flow control for %s\n", path);
++ break;
++ default:
++ gam_error(DEBUG_INFO, "Unknown inotify_legacy operation %d for %s\n",
++ mode, path);
++ return;
++ }
++
++ G_LOCK(inotify_legacy);
++
++ if (mode == GAMIN_ACTIVATE) {
++
++ if ((data = g_hash_table_lookup(path_hash, path)) != NULL) {
++ data->refcount++;
++ GAM_DEBUG(DEBUG_INFO, " found incremented refcount: %d\n",
++ data->refcount);
++ G_UNLOCK(inotify_legacy);
++#ifdef GAMIN_DEBUG_API
++ gam_debug_report(GAMinotifyChange, path, data->refcount);
++#endif
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy updated refcount\n");
++ return;
++ }
++
++ path_fd = open(path, O_RDONLY);
++
++ if (path_fd < 0) {
++ G_UNLOCK(inotify_legacy);
++ return;
++ }
++
++ iwr.fd = path_fd;
++ iwr.mask = should_poll_mask;
++ path_wd = ioctl (inotify_legacy_device_fd, INOTIFY_WATCH, &iwr);
++ close (path_fd);
++
++ data = gam_inotify_legacy_data_new(path, path_wd);
++ g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd), data);
++ g_hash_table_insert(path_hash, data->path, data);
++
++ GAM_DEBUG(DEBUG_INFO, "activated inotify_legacy for %s\n", path);
++#ifdef GAMIN_DEBUG_API
++ gam_debug_report(GAMinotifyCreate, path, 0);
++#endif
++ } else if (mode == GAMIN_DESACTIVATE) {
++ data = g_hash_table_lookup(path_hash, path);
++
++ if (!data) {
++ GAM_DEBUG(DEBUG_INFO, " not found !!!\n");
++
++ G_UNLOCK(inotify_legacy);
++ return;
++ }
++
++ data->refcount--;
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy decremeneted refcount for %s\n",
++ path);
++
++ if (data->refcount == 0) {
++ int wd = data->wd;
++ GAM_DEBUG(DEBUG_INFO, "removed inotify_legacy watch for %s\n",
++ data->path);
++ g_hash_table_remove(path_hash, data->path);
++ g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd));
++ gam_inotify_legacy_data_free(data);
++ if (ioctl (inotify_legacy_device_fd, INOTIFY_IGNORE, &wd) < 0) {
++ GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE failed for %s (wd = %d)\n", data->path, data->wd);
++ }
++#ifdef GAMIN_DEBUG_API
++ gam_debug_report(GAMinotifyDelete, data->path, 0);
++#endif
++ } else {
++ GAM_DEBUG(DEBUG_INFO, " found decremented refcount: %d\n",
++ data->refcount);
++#ifdef GAMIN_DEBUG_API
++ gam_debug_report(GAMinotifyChange, data->path, data->refcount);
++#endif
++ }
++ } else if ((mode == GAMIN_FLOWCONTROLSTART) ||
++ (mode == GAMIN_FLOWCONTROLSTOP)) {
++ data = g_hash_table_lookup(path_hash, path);
++ if (!data) {
++ GAM_DEBUG(DEBUG_INFO, " not found !!!\n");
++
++ G_UNLOCK(inotify_legacy);
++ return;
++ }
++ if (data != NULL) {
++ if (mode == GAMIN_FLOWCONTROLSTART) {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: GAMIN_FLOWCONTROLSTART for %s\n", data->path);
++ if (data->wd >= 0) {
++ if (ioctl (inotify_legacy_device_fd, INOTIFY_IGNORE, &data->wd) < 0) {
++ GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE failed for %s (wd = %d)\n", data->path, data->wd);
++ }
++ data->deactivated = TRUE;
++ GAM_DEBUG(DEBUG_INFO, "deactivated inotify_legacy for %s\n",
++ data->path);
++#ifdef GAMIN_DEBUG_API
++ gam_debug_report(GAMinotifyFlowOn, data->path, 0);
++#endif
++ }
++ data->busy++;
++ } else {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: GAMIN_FLOWCONTROLSTOP for %s\n", data->path);
++ if (data->busy > 0) {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: data->busy > 0 for %s\n", data->path);
++ data->busy--;
++ if (data->busy == 0) {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: data->busy == 0 for %s\n", data->path);
++ path_fd = open(data->path, O_RDONLY);
++ if (path_fd < 0) {
++ G_UNLOCK(inotify_legacy);
++ GAM_DEBUG(DEBUG_INFO,
++ "failed to reactivate inotify_legacy for %s\n",
++ data->path);
++
++ return;
++ }
++
++ iwr.fd = path_fd;
++ iwr.mask = should_poll_mask;
++ path_wd = ioctl (inotify_legacy_device_fd, INOTIFY_WATCH, &iwr);
++ close (path_fd);
++
++ /* Remove the old wd from the hash table */
++ g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd));
++
++ data->wd = path_wd;
++ data->deactivated = FALSE;
++
++ /* Insert the new wd into the hash table */
++ g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd),
++ data);
++ GAM_DEBUG(DEBUG_INFO, "reactivated inotify_legacy for %s\n",
++ data->path);
++#ifdef GAMIN_DEBUG_API
++ gam_debug_report(GAMinotifyFlowOff, path, 0);
++#endif
++ }
++ }
++ }
++ }
++ } else {
++ GAM_DEBUG(DEBUG_INFO, "Unimplemented operation\n");
++ }
++
++ G_UNLOCK(inotify_legacy);
++}
++
++static void
++gam_inotify_legacy_directory_handler(const char *path, pollHandlerMode mode)
++{
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_directory_handler %s : %d\n",
++ path, mode);
++
++ gam_inotify_legacy_directory_handler_internal(path, mode);
++}
++
++static void
++gam_inotify_legacy_file_handler(const char *path, pollHandlerMode mode)
++{
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_file_handler %s : %d\n", path, mode);
++
++ if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
++ gam_inotify_legacy_directory_handler_internal(path, mode);
++ } else {
++ GAM_DEBUG(DEBUG_INFO, " not a dir %s, FAILED!!!\n", path);
++ }
++}
++
++static void
++gam_inotify_legacy_q_overflow (gpointer key, gpointer value, gpointer user_data)
++{
++ inotify_legacy_data_t *data = (inotify_legacy_data_t *)value;
++
++ gam_poll_scan_directory (data->path);
++}
++
++static gboolean
++gam_inotify_legacy_read_handler(gpointer user_data)
++{
++ char *buffer;
++ int buffer_size;
++ int events;
++ gsize buffer_i, read_size;
++
++ G_LOCK(inotify_legacy);
++
++ if (ioctl(inotify_legacy_device_fd, FIONREAD, &buffer_size) < 0) {
++ G_UNLOCK(inotify_legacy);
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy FIONREAD < 0. kaboom!\n");
++ return FALSE;
++ }
++
++ buffer = g_malloc(buffer_size);
++
++ if (g_io_channel_read_chars(inotify_legacy_read_ioc, (char *)buffer, buffer_size, &read_size, NULL) != G_IO_STATUS_NORMAL) {
++ G_UNLOCK(inotify_legacy);
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy failed to read events from inotify_legacy fd.\n");
++ g_free (buffer);
++ return FALSE;
++ }
++
++ buffer_i = 0;
++ events = 0;
++ while (buffer_i < read_size) {
++ struct inotify_event *event;
++ gsize event_size;
++ inotify_legacy_data_t *data;
++
++ event = (struct inotify_event *)&buffer[buffer_i];
++ event_size = sizeof(struct inotify_event) + event->len;
++
++ data = g_hash_table_lookup (wd_hash, GINT_TO_POINTER(event->wd));
++ if (!data) {
++ GAM_DEBUG(DEBUG_INFO, "processing event: inotify_legacy can't find wd %d\n", event->wd);
++ } else if (data->deactivated) {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: ignoring event on temporarily deactivated watch %s\n", data->path);
++ data->deactivated_events++;
++ } else {
++ if (event->mask == IN_IGNORED) {
++ GList *l;
++
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: IN_IGNORE on wd=%d\n", event->wd);
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy: removing all subscriptions for %s\n", data->path);
++
++ data->events++;
++
++ l = data->subs;
++ data->subs = NULL;
++ for (l = l; l; l = l->next) {
++ GamSubscription *sub = l->data;
++ gam_inotify_legacy_remove_subscription (sub);
++ }
++ } else if (event->mask != IN_Q_OVERFLOW) {
++ if (event->mask & should_poll_mask) {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy requesting poll for %s\n", data->path);
++ GAM_DEBUG(DEBUG_INFO, "poll was requested for event = ");
++ print_mask (event->mask);
++ data->events++;
++ gam_poll_scan_directory (data->path);
++ }
++ } else if (event->mask == IN_Q_OVERFLOW) {
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy queue over flowed, requesting poll on all watched paths\n");
++ g_hash_table_foreach (path_hash, gam_inotify_legacy_q_overflow, NULL);
++ }
++ }
++
++ buffer_i += event_size;
++ events++;
++ }
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy recieved %d events\n", events);
++
++ g_free(buffer);
++ G_UNLOCK(inotify_legacy);
++
++ return TRUE;
++}
++
++
++static gboolean
++gam_inotify_legacy_consume_subscriptions_real(gpointer data)
++{
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_consume_subscriptions_real()\n");
++ gam_poll_consume_subscriptions();
++ have_consume_idler = FALSE;
++ return FALSE;
++}
++
++static void
++gam_inotify_legacy_consume_subscriptions(void)
++{
++ GSource *source;
++
++ if (have_consume_idler)
++ return;
++
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_consume_subscriptions()\n");
++ have_consume_idler = TRUE;
++ source = g_idle_source_new();
++ g_source_set_callback(source, gam_inotify_legacy_consume_subscriptions_real,
++ NULL, NULL);
++ g_source_attach(source, NULL);
++}
++
++/**
++ * @defgroup inotify_legacy inotify_legacy Backend
++ * @ingroup Backends
++ * @brief inotify_legacy backend API
++ *
++ * Since version 2.6.X, Linux kernels have included the Linux Inode
++ * Notification system (inotify_legacy). This backend uses inotify_legacy to know when
++ * files are changed/created/deleted. Since inotify_legacy can't watch files/dirs that
++ * don't exist we still have to cache stat() information. For this,
++ * we can just use the code in the polling backend.
++ *
++ * @{
++ */
++
++
++/**
++ * Initializes the inotify_legacy backend. This must be called before
++ * any other functions in this module.
++ *
++ * @returns TRUE if initialization succeeded, FALSE otherwise
++ */
++gboolean
++gam_inotify_legacy_init(void)
++{
++ GSource *source;
++
++ g_return_val_if_fail(gam_poll_init_full(FALSE), FALSE);
++
++ inotify_legacy_device_fd = open("/dev/inotify", O_RDONLY);
++
++ if (inotify_legacy_device_fd < 0) {
++ GAM_DEBUG(DEBUG_INFO, "Could not open /dev/inotify\n");
++ return FALSE;
++ }
++
++ inotify_legacy_read_ioc = g_io_channel_unix_new(inotify_legacy_device_fd);
++
++ /* For binary data */
++ g_io_channel_set_encoding(inotify_legacy_read_ioc, NULL, NULL);
++ /* Non blocking */
++ g_io_channel_set_flags(inotify_legacy_read_ioc, G_IO_FLAG_NONBLOCK, NULL);
++
++ source = g_io_create_watch(inotify_legacy_read_ioc,
++ G_IO_IN | G_IO_HUP | G_IO_ERR);
++ g_source_set_callback(source, gam_inotify_legacy_read_handler, NULL, NULL);
++
++ g_source_attach(source, NULL);
++
++ path_hash = g_hash_table_new(g_str_hash, g_str_equal);
++ wd_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
++ gam_poll_set_kernel_handler(gam_inotify_legacy_directory_handler,
++ gam_inotify_legacy_file_handler,
++ GAMIN_K_INOTIFY);
++
++ GAM_DEBUG(DEBUG_INFO, "inotify_legacy initialized\n");
++
++ gam_backend_add_subscription = gam_inotify_legacy_add_subscription;
++ gam_backend_remove_subscription = gam_inotify_legacy_remove_subscription;
++ gam_backend_remove_all_for = gam_inotify_legacy_remove_all_for;
++
++ return TRUE;
++}
++
++/**
++ * Adds a subscription to be monitored.
++ *
++ * @param sub a #GamSubscription to be polled
++ * @returns TRUE if adding the subscription succeeded, FALSE otherwise
++ */
++gboolean
++gam_inotify_legacy_add_subscription(GamSubscription * sub)
++{
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_add_subscription\n");
++
++ if (!gam_poll_add_subscription(sub)) {
++ return FALSE;
++ }
++
++ gam_inotify_legacy_consume_subscriptions();
++
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_add_subscription: done\n");
++ return TRUE;
++}
++
++/**
++ * Removes a subscription which was being monitored.
++ *
++ * @param sub a #GamSubscription to remove
++ * @returns TRUE if removing the subscription succeeded, FALSE otherwise
++ */
++gboolean
++gam_inotify_legacy_remove_subscription(GamSubscription * sub)
++{
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_remove_subscription\n");
++
++ if (!gam_poll_remove_subscription(sub)) {
++ return FALSE;
++ }
++
++ gam_inotify_legacy_consume_subscriptions();
++
++ GAM_DEBUG(DEBUG_INFO, "gam_inotify_legacy_remove_subscription: done\n");
++ return TRUE;
++}
++
++/**
++ * Stop monitoring all subscriptions for a given listener.
++ *
++ * @param listener a #GamListener
++ * @returns TRUE if removing the subscriptions succeeded, FALSE otherwise
++ */
++gboolean
++gam_inotify_legacy_remove_all_for(GamListener * listener)
++{
++ if (!gam_poll_remove_all_for(listener)) {
++ return FALSE;
++ }
++
++ gam_inotify_legacy_consume_subscriptions();
++
++ return TRUE;
++}
++
++/** @} */
+diff -urpN gamin-0.1.2/server/gam_inotify_legacy.h gamin-0.1.2.az/server/gam_inotify_legacy.h
+--- gamin-0.1.2/server/gam_inotify_legacy.h 1970-01-01 02:00:00.000000000 +0200
++++ gamin-0.1.2.az/server/gam_inotify_legacy.h 2005-07-16 08:41:34.000000000 +0200
+@@ -0,0 +1,18 @@
++#ifndef __GAM_INOTIFY_LEGACY_H__
++#define __GAM_INOTIFY_LEGACY_H__
++
++#include <glib.h>
++#include "gam_poll.h"
++#include "gam_subscription.h"
++
++G_BEGIN_DECLS
++
++gboolean gam_inotify_legacy_init (void);
++gboolean gam_inotify_legacy_add_subscription (GamSubscription *sub);
++gboolean gam_inotify_legacy_remove_subscription (GamSubscription *sub);
++gboolean gam_inotify_legacy_remove_all_for (GamListener *listener);
++void gam_inotify_legacy_debug (void);
++
++G_END_DECLS
++
++#endif /* __GAM_INOTIFY_LEGACY_H__ */
+diff -urpN gamin-0.1.2/server/gam_server.c gamin-0.1.2.az/server/gam_server.c
+--- gamin-0.1.2/server/gam_server.c 2005-06-15 13:02:34.000000000 +0200
++++ gamin-0.1.2.az/server/gam_server.c 2005-07-16 08:44:19.000000000 +0200
+@@ -36,6 +36,9 @@
+ #ifdef ENABLE_INOTIFY
+ #include "gam_inotify.h"
+ #endif
++#ifdef ENABLE_INOTIFY_LEGACY
++#include "gam_inotify_legacy.h"
++#endif
+ #ifdef ENABLE_DNOTIFY
+ #include "gam_dnotify.h"
+ #endif
+@@ -87,6 +90,9 @@ gam_show_debug(void) {
+ #ifdef ENABLE_INOTIFY
+ gam_inotify_debug ();
+ #endif
++#ifdef ENABLE_INOTIFY_LEGACY
++ gam_inotify_legacy_debug ();
++#endif
+ #ifdef ENABLE_DNOTIFY
+ gam_dnotify_debug ();
+ #endif
+@@ -112,6 +118,12 @@ gam_init_subscriptions(void)
+ return(TRUE);
+ }
+ #endif
++#ifdef ENABLE_INOTIFY_LEGACY
++ if (gam_inotify_legacy_init()) {
++ GAM_DEBUG(DEBUG_INFO, "Using INotify Legacy as backend\n");
++ return(TRUE);
++ }
++#endif
+ #ifdef ENABLE_DNOTIFY
+ if (gam_dnotify_init()) {
+ GAM_DEBUG(DEBUG_INFO, "Using DNotify as backend\n");
+diff -urpN gamin-0.1.2/server/local_inotify_legacy.h gamin-0.1.2.az/server/local_inotify_legacy.h
+--- gamin-0.1.2/server/local_inotify_legacy.h 1970-01-01 02:00:00.000000000 +0200
++++ gamin-0.1.2.az/server/local_inotify_legacy.h 2005-07-16 08:42:16.000000000 +0200
+@@ -0,0 +1,124 @@
++/*
++ * Inode based directory notification for Linux
++ *
++ * Copyright (C) 2005 John McCutchan
++ */
++
++#ifndef _LINUX_INOTIFY_LEGACY_H
++#define _LINUX_INOTIFY_LEGACY_H
++
++#include <linux/types.h>
++
++/*
++ * struct inotify_event - structure read from the inotify device for each event
++ *
++ * When you are watching a directory, you will receive the filename for events
++ * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
++ */
++struct inotify_event {
++ __s32 wd; /* watch descriptor */
++ __u32 mask; /* watch mask */
++ __u32 cookie; /* cookie to synchronize two events */
++ __u32 len; /* length (including nulls) of name */
++ char name[0]; /* stub for possible name */
++};
++
++/*
++ * struct inotify_watch_request - represents a watch request
++ *
++ * Pass to the inotify device via the INOTIFY_WATCH ioctl
++ */
++struct inotify_watch_request {
++ int fd; /* fd of filename to watch */
++ __u32 mask; /* event mask */
++};
++
++/* the following are legal, implemented events that user-space can watch for */
++#define IN_ACCESS 0x00000001 /* File was accessed */
++#define IN_MODIFY 0x00000002 /* File was modified */
++#define IN_ATTRIB 0x00000004 /* Metadata changed */
++#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
++#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
++#define IN_OPEN 0x00000020 /* File was opened */
++#define IN_MOVED_FROM 0x00000040 /* File was moved from X */
++#define IN_MOVED_TO 0x00000080 /* File was moved to Y */
++#define IN_CREATE 0x00000100 /* Subfile was created */
++#define IN_DELETE 0x00000200 /* Subfile was deleted */
++#define IN_DELETE_SELF 0x00000400 /* Self was deleted */
++
++/* the following are legal events. they are sent as needed to any watch */
++#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
++#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
++#define IN_IGNORED 0x00008000 /* File was ignored */
++
++/* helper events */
++#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
++#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
++
++/* special flags */
++#define IN_ISDIR 0x40000000 /* event occurred against dir */
++#define IN_ONESHOT 0x80000000 /* only send event once */
++
++/*
++ * All of the events - we build the list by hand so that we can add flags in
++ * the future and not break backward compatibility. Apps will get only the
++ * events that they originally wanted. Be sure to add new events here!
++ */
++#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
++ IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
++ IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF)
++
++#define INOTIFY_IOCTL_MAGIC 'Q'
++#define INOTIFY_IOCTL_MAXNR 2
++
++#define INOTIFY_WATCH _IOR(INOTIFY_IOCTL_MAGIC, 1, struct inotify_watch_request)
++#define INOTIFY_IGNORE _IOR(INOTIFY_IOCTL_MAGIC, 2, int)
++
++#ifdef __KERNEL__
++
++#include <linux/dcache.h>
++#include <linux/fs.h>
++#include <linux/config.h>
++
++#ifdef CONFIG_INOTIFY
++
++extern void inotify_inode_queue_event(struct inode *, __u32, __u32,
++ const char *);
++extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32,
++ const char *);
++extern void inotify_unmount_inodes(struct list_head *);
++extern void inotify_inode_is_dead(struct inode *);
++extern u32 inotify_get_cookie(void);
++
++#else
++
++static inline void inotify_inode_queue_event(struct inode *inode,
++ __u32 mask, __u32 cookie,
++ const char *filename)
++{
++}
++
++static inline void inotify_dentry_parent_queue_event(struct dentry *dentry,
++ __u32 mask, __u32 cookie,
++ const char *filename)
++{
++}
++
++static inline void inotify_unmount_inodes(struct list_head *list)
++{
++}
++
++static inline void inotify_inode_is_dead(struct inode *inode)
++{
++}
++
++static inline u32 inotify_get_cookie(void)
++{
++ return 0;
++}
++
++#endif /* CONFIG_INOTIFY */
++
++#endif /* __KERNEL __ */
++
++#endif /* _LINUX_INOTIFY_LEGACY_H */