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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "system/filesys.h"
#include "ntvfs/sysdep/sys_notify.h"
#include "lib/events/events.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
#include "libcli/raw/smb.h"
+#include "param/param.h"
#include <linux/inotify.h>
#include <asm/unistd.h>
struct inotify_private {
struct sys_notify_context *ctx;
int fd;
- struct watch_context *watches;
+ struct inotify_watch_context *watches;
};
-struct watch_context {
- struct watch_context *next, *prev;
+struct inotify_watch_context {
+ struct inotify_watch_context *next, *prev;
struct inotify_private *in;
int wd;
sys_notify_callback_t callback;
- void *private;
+ void *private_data;
uint32_t mask; /* the inotify mask */
uint32_t filter; /* the windows completion filter */
const char *path;
};
-/*
- destroy the inotify private context
-*/
-static int inotify_destructor(struct inotify_private *in)
-{
- close(in->fd);
- return 0;
-}
-
-
/*
see if a particular event from inotify really does match a requested
notify event in SMB
*/
-static BOOL filter_match(struct watch_context *w, struct inotify_event *e)
+static bool filter_match(struct inotify_watch_context *w,
+ struct inotify_event *e)
{
if ((e->mask & w->mask) == 0) {
/* this happens because inotify_add_watch() coalesces watches on the same
path, oring their masks together */
- return False;
+ return false;
}
/* SMB separates the filters for files and directories */
if (e->mask & IN_ISDIR) {
if ((w->filter & FILE_NOTIFY_CHANGE_DIR_NAME) == 0) {
- return False;
+ return false;
}
} else {
if ((e->mask & IN_ATTRIB) &&
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_EA|
FILE_NOTIFY_CHANGE_SECURITY))) {
- return True;
+ return true;
}
if ((e->mask & IN_MODIFY) &&
(w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) {
- return True;
+ return true;
}
if ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) {
- return False;
+ return false;
}
}
- return True;
+ return true;
}
uint32_t prev_cookie,
struct inotify_event *e2)
{
- struct watch_context *w, *next;
+ struct inotify_watch_context *w, *next;
struct notify_event ne;
/* ignore extraneous events, such as unmount and IN_IGNORED events */
for (w=in->watches;w;w=next) {
next = w->next;
if (w->wd == e->wd && filter_match(w, e)) {
- w->callback(in->ctx, w->private, &ne);
+ w->callback(in->ctx, w->private_data, &ne);
}
}
next = w->next;
if (w->wd == e->wd && filter_match(w, e) &&
!(w->filter & FILE_NOTIFY_CHANGE_CREATION)) {
- w->callback(in->ctx, w->private, &ne);
+ w->callback(in->ctx, w->private_data, &ne);
}
}
}
called when the kernel has some events for us
*/
static void inotify_handler(struct event_context *ev, struct fd_event *fde,
- uint16_t flags, void *private)
+ uint16_t flags, void *private_data)
{
- struct inotify_private *in = talloc_get_type(private, struct inotify_private);
+ struct inotify_private *in = talloc_get_type(private_data,
+ struct inotify_private);
int bufsize = 0;
struct inotify_event *e0, *e;
uint32_t prev_cookie=0;
static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
{
struct inotify_private *in;
-
- if (!lp_parm_bool(-1, "notify", "inotify", True)) {
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
-
in = talloc(ctx, struct inotify_private);
NT_STATUS_HAVE_NO_MEMORY(in);
in->fd = inotify_init();
in->ctx = ctx;
in->watches = NULL;
- ctx->private = in;
- talloc_set_destructor(in, inotify_destructor);
+ ctx->private_data = in;
/* add a event waiting for the inotify fd to be readable */
- event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ, inotify_handler, in);
+ event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, inotify_handler, in);
return NT_STATUS_OK;
}
/*
destroy a watch
*/
-static int watch_destructor(struct watch_context *w)
+static int watch_destructor(struct inotify_watch_context *w)
{
struct inotify_private *in = w->in;
int wd = w->wd;
add a watch. The watch is removed when the caller calls
talloc_free() on *handle
*/
-static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entry *e,
- sys_notify_callback_t callback, void *private,
- void **handle)
+static NTSTATUS inotify_watch(struct sys_notify_context *ctx,
+ struct notify_entry *e,
+ sys_notify_callback_t callback,
+ void *private_data,
+ void *handle_p)
{
struct inotify_private *in;
int wd;
uint32_t mask;
- struct watch_context *w;
+ struct inotify_watch_context *w;
uint32_t filter = e->filter;
+ void **handle = (void **)handle_p;
/* maybe setup the inotify fd */
- if (ctx->private == NULL) {
+ if (ctx->private_data == NULL) {
NTSTATUS status;
+ if (!lp_parm_bool(global_loadparm, NULL, "notify", "inotify", true)) {
+ return NT_STATUS_INVALID_SYSTEM_SERVICE;
+ }
+
status = inotify_setup(ctx);
NT_STATUS_NOT_OK_RETURN(status);
}
- in = talloc_get_type(ctx->private, struct inotify_private);
+ in = talloc_get_type(ctx->private_data, struct inotify_private);
mask = inotify_map(e);
if (mask == 0) {
return map_nt_error_from_unix(errno);
}
- w = talloc(in, struct watch_context);
+ w = talloc(in, struct inotify_watch_context);
if (w == NULL) {
inotify_rm_watch(in->fd, wd);
e->filter = filter;
w->in = in;
w->wd = wd;
w->callback = callback;
- w->private = private;
+ w->private_data = private_data;
w->mask = mask;
w->filter = filter;
w->path = talloc_strdup(w, e->path);