/*
 * Server-side smb network file management
 *
 * Copyright (C) 1998 Alexandre Julliard
 * Copyright (C) 2000, 2001, 2002 Mike McCormack
 *
 * 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
 *
 * FIXME: if you can't find something to fix,
 *          you're not looking hard enough
 */

#include "config.h"

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#include "winerror.h"
#include "winbase.h"

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

static void smb_dump( struct object *obj, int verbose );
static void smb_destroy(struct object *obj);

static int smb_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags );
static int smb_get_poll_events( struct fd *fd );

struct smb
{
    struct object       obj;
    unsigned int        tree_id;
    unsigned int        user_id;
    unsigned int        dialect;
    unsigned int        file_id;
    unsigned int        offset;
};

static const struct object_ops smb_ops =
{
    sizeof(struct smb),        /* size */
    smb_dump,                  /* dump */
    default_fd_add_queue,      /* add_queue */
    default_fd_remove_queue,   /* remove_queue */
    default_fd_signaled,       /* signaled */
    no_satisfied,              /* satisfied */
    default_get_fd,            /* get_fd */
    smb_destroy                /* destroy */
};

static const struct fd_ops smb_fd_ops =
{
    smb_get_poll_events,       /* get_poll_events */
    default_poll_event,        /* poll_event */
    no_flush,                  /* flush */
    smb_get_info,              /* get_file_info */
    no_queue_async             /* queue_async */
};

static void smb_destroy( struct object *obj)
{
    /* struct smb *smb = (struct smb *)obj; */
    assert( obj->ops == &smb_ops );
}

static void smb_dump( struct object *obj, int verbose )
{
    struct smb *smb = (struct smb *)obj;
    assert( obj->ops == &smb_ops );
    fprintf( stderr, "Smb file fd=%p\n", smb->obj.fd_obj );
}

struct smb *get_smb_obj( struct process *process, obj_handle_t handle, unsigned int access )
{
    return (struct smb *)get_handle_obj( process, handle, access, &smb_ops );
}

static int smb_get_poll_events( struct fd *fd )
{
    struct smb *smb = get_fd_user( fd );
    int events = 0;
    assert( smb->obj.ops == &smb_ops );

    events |= POLLIN;

    /* fprintf(stderr,"poll events are %04x\n",events); */

    return events;
}

static int smb_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags )
{
/*    struct smb *smb = get_fd_user( fd ); */
/*    assert( smb->obj.ops == &smb_ops ); */

    if (reply)
    {
        reply->type        = FILE_TYPE_CHAR;
        reply->attr        = 0;
        reply->access_time = 0;
        reply->write_time  = 0;
        reply->size_high   = 0;
        reply->size_low    = 0;
        reply->links       = 0;
        reply->index_high  = 0;
        reply->index_low   = 0;
        reply->serial      = 0;
    }

    *flags = 0;

    return FD_TYPE_SMB;
}

/* create a smb */
DECL_HANDLER(create_smb)
{
    struct smb *smb;
    int fd;

    reply->handle = 0;

    fd = thread_get_inflight_fd( current, req->fd );
    if (fd == -1)
    {
        set_error( STATUS_INVALID_HANDLE );
        return;
    }

    smb = alloc_fd_object( &smb_ops, &smb_fd_ops, fd );
    if (smb)
    {
        smb->tree_id = req->tree_id;
        smb->user_id = req->user_id;
        smb->dialect = req->dialect;
        smb->file_id = req->file_id;
        smb->offset = 0;
        reply->handle = alloc_handle( current->process, smb, GENERIC_READ, 0);
        release_object( smb );
    }
}

DECL_HANDLER(get_smb_info)
{
    struct smb *smb;

    if ((smb = get_smb_obj( current->process, req->handle, 0 )))
    {
        if(req->flags & SMBINFO_SET_OFFSET)
            smb->offset = req->offset;

        reply->tree_id = smb->tree_id;
        reply->user_id = smb->user_id;
        reply->dialect = smb->dialect;
        reply->file_id = smb->file_id;
        reply->offset  = smb->offset;

        release_object( smb );
    }
}
