/*
 * Server-side change notification management
 *
 * Copyright (C) 1998 Alexandre Julliard
 *
 * 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.1 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"

#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
#include "winternl.h"

#ifdef linux
#ifndef F_NOTIFY
#define F_NOTIFY 1026
#define DN_ACCESS       0x00000001      /* File accessed */
#define DN_MODIFY       0x00000002      /* File modified */
#define DN_CREATE       0x00000004      /* File created */
#define DN_DELETE       0x00000008      /* File removed */
#define DN_RENAME       0x00000010      /* File renamed */
#define DN_ATTRIB       0x00000020      /* File changed attibutes */
#define DN_MULTISHOT    0x80000000      /* Don't remove notifier */
#endif
#endif

struct change
{
    struct object  obj;      /* object header */
    struct fd     *fd;       /* file descriptor to the directory */
    struct list    entry;    /* entry in global change notifications list */
    int            subtree;  /* watch all the subtree */
    unsigned int   filter;   /* notification filter */
    int            notified; /* SIGIO counter */
    long           signaled; /* the file changed */
};

static void change_dump( struct object *obj, int verbose );
static int change_signaled( struct object *obj, struct thread *thread );
static void change_destroy( struct object *obj );

static const struct object_ops change_ops =
{
    sizeof(struct change),    /* size */
    change_dump,              /* dump */
    add_queue,                /* add_queue */
    remove_queue,             /* remove_queue */
    change_signaled,          /* signaled */
    no_satisfied,             /* satisfied */
    no_signal,                /* signal */
    no_get_fd,                /* get_fd */
    no_lookup_name,           /* lookup_name */
    no_close_handle,          /* close_handle */
    change_destroy            /* destroy */
};

static struct list change_list = LIST_INIT(change_list);

static void adjust_changes( int fd, unsigned int filter )
{
#if defined(F_SETSIG) && defined(F_NOTIFY)
    unsigned int val;
    if ( 0 > fcntl( fd, F_SETSIG, SIGIO) )
        return;

    val = DN_MULTISHOT;
    if (filter & FILE_NOTIFY_CHANGE_FILE_NAME)
        val |= DN_RENAME | DN_DELETE | DN_CREATE;
    if (filter & FILE_NOTIFY_CHANGE_DIR_NAME)
        val |= DN_RENAME | DN_DELETE | DN_CREATE;
    if (filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)
        val |= DN_ATTRIB;
    if (filter & FILE_NOTIFY_CHANGE_SIZE)
        val |= DN_MODIFY;
    if (filter & FILE_NOTIFY_CHANGE_LAST_WRITE)
        val |= DN_MODIFY;
    if (filter & FILE_NOTIFY_CHANGE_LAST_ACCESS)
        val |= DN_ACCESS;
    if (filter & FILE_NOTIFY_CHANGE_CREATION)
        val |= DN_CREATE;
    if (filter & FILE_NOTIFY_CHANGE_SECURITY)
        val |= DN_ATTRIB;
    fcntl( fd, F_NOTIFY, val );
#endif
}

/* insert change in the global list */
static inline void insert_change( struct change *change )
{
    sigset_t sigset;

    sigemptyset( &sigset );
    sigaddset( &sigset, SIGIO );
    sigprocmask( SIG_BLOCK, &sigset, NULL );
    list_add_head( &change_list, &change->entry );
    sigprocmask( SIG_UNBLOCK, &sigset, NULL );
}

/* remove change from the global list */
static inline void remove_change( struct change *change )
{
    sigset_t sigset;

    sigemptyset( &sigset );
    sigaddset( &sigset, SIGIO );
    sigprocmask( SIG_BLOCK, &sigset, NULL );
    list_remove( &change->entry );
    sigprocmask( SIG_UNBLOCK, &sigset, NULL );
}

static struct change *create_change_notification( struct fd *fd, int subtree, unsigned int filter )
{
    struct change *change;
    struct stat st;
    int unix_fd = get_unix_fd( fd );

    if (unix_fd == -1) return NULL;

    if (fstat( unix_fd, &st ) == -1 || !S_ISDIR(st.st_mode))
    {
        set_error( STATUS_NOT_A_DIRECTORY );
        return NULL;
    }

    if ((change = alloc_object( &change_ops )))
    {
        change->fd       = (struct fd *)grab_object( fd );
        change->subtree  = subtree;
        change->filter   = filter;
        change->notified = 0;
        change->signaled = 0;
        insert_change( change );
        adjust_changes( unix_fd, filter );
    }
    return change;
}

static void change_dump( struct object *obj, int verbose )
{
    struct change *change = (struct change *)obj;
    assert( obj->ops == &change_ops );
    fprintf( stderr, "Change notification fd=%p sub=%d filter=%08x\n",
             change->fd, change->subtree, change->filter );
}

static int change_signaled( struct object *obj, struct thread *thread )
{
    struct change *change = (struct change *)obj;

    return change->signaled != 0;
}

static void change_destroy( struct object *obj )
{
    struct change *change = (struct change *)obj;

    release_object( change->fd );
    remove_change( change );
}

/* enter here directly from SIGIO signal handler */
void do_change_notify( int unix_fd )
{
    struct list *ptr;

    /* FIXME: this is O(n) ... probably can be improved */
    LIST_FOR_EACH( ptr, &change_list )
    {
        struct change *change = LIST_ENTRY( ptr, struct change, entry );
        if (get_unix_fd( change->fd ) != unix_fd) continue;
        interlocked_xchg_add( &change->notified, 1 );
        break;
    }
}

/* SIGIO callback, called synchronously with the poll loop */
void sigio_callback(void)
{
    struct list *ptr;

    LIST_FOR_EACH( ptr, &change_list )
    {
        struct change *change = LIST_ENTRY( ptr, struct change, entry );
        long count = interlocked_xchg( &change->notified, 0 );
        if (count)
        {
            change->signaled += count;
            if (change->signaled == count)  /* was it 0? */
                wake_up( &change->obj, 0 );
        }
    }
}

/* create a change notification */
DECL_HANDLER(create_change_notification)
{
    struct change *change;
    struct file *file;
    struct fd *fd;

    if (!(file = get_file_obj( current->process, req->handle, 0 ))) return;
    fd = get_obj_fd( (struct object *)file );
    release_object( file );
    if (!fd) return;

    if ((change = create_change_notification( fd, req->subtree, req->filter )))
    {
        reply->handle = alloc_handle( current->process, change,
                                      STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
        release_object( change );
    }
    release_object( fd );
}

/* move to the next change notification */
DECL_HANDLER(next_change_notification)
{
    struct change *change;

    if ((change = (struct change *)get_handle_obj( current->process, req->handle,
                                                   0, &change_ops )))
    {
        if (change->signaled > 0) change->signaled--;
        release_object( change );
    }
}
