#ifndef _SMBLIB_H_
#define _SMBLIB_H_

#include <sys/types.h>
#include "basic.h"

#define SMB_NAMELEN 13

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;

typedef WORD sfid_t;

/* Protocol constants */
enum protocols {
  PROT_NONE,
  PROT_CORE,
  PROT_COREPLUS,
  PROT_LANMAN1,
  PROT_LANMAN2
};


struct smb_conn {
  int        server;
  BYTE       rcls;
  WORD       err;
  WORD       tid;
  WORD       pid;
  WORD       uid;               /* the UID we use for Inodes                 */
  WORD       server_uid;        /* the UID the server gave us                */
  WORD       mid;
  int        max_xmit;          /* this includes the 4 bytes from rfc 1002   */
  enum protocols prot;

  umode_t    file_mode;
  umode_t    dir_mode;
  gid_t      gid;
  char       buffer[0];
};

#if DEBUG > 0
void _AssertConn(const char *f, int l, struct smb_conn *conn);
#define AssertConn(c) _AssertConn(__FILE__, __LINE__, c)
#else
#define AssertConn(c)
#endif /* DEBUG > 0 */


struct smb_finfo {
  sfid_t     fid;
  DWORD      size;
  DWORD      mtime;
  WORD       attrib;
  int        access;            /* 0:r/o, 1:w/o, 2:r/w */
  char       name[SMB_NAMELEN];
};

struct smb_servattr {
  int        total;
  int        allocblocks;
  int        blocksize;
  int        free;
};


void
Debug(int, char *, ...);

int
smb2unix_errno(struct smb_conn *conn);

extern int smb_errno;

struct smb_conn *
smb_connect(const char *server,
            int port,
            const char *myname,
            const char *service,
            const char *user,
            const char *passwd);

struct smb_conn *
smb_do_connect(const int serv_socket,
               const char *my_name,
               const char *serv_name,
               const char *service,
               const char *user,
               const char *passwd);

Status
smb_disconnect(struct smb_conn *conn);

Status
smb_open(struct smb_conn *conn, const char *name, struct smb_finfo *finfo);

Bool
smb_mkdir(struct smb_conn *conn, const char *name);

Status
smb_mknew(struct smb_conn *conn, const char *name, struct smb_finfo *finfo);

Status
smb_close(struct smb_conn *conn, sfid_t fid, time_t time);

Status
smb_truncate(struct smb_conn *conn, sfid_t fid, size_t length);

Status 
smb_create(struct smb_conn *conn, const char *name, struct smb_finfo *finfo);

Status
smb_read(struct smb_conn *conn, sfid_t fid, off_t off, void *buf, size_t size,
         size_t *nread);

Status
smb_write(struct smb_conn *conn, sfid_t fid, off_t off, void *buf,
          size_t size, size_t *written);

Bool
smb_flush(struct smb_conn *conn, sfid_t fid);

Status
smb_getatr(struct smb_conn *conn, const char *name, struct smb_finfo *finfo);

Status
smb_setatr(struct smb_conn *conn, const char *name, struct smb_finfo *finfo);

Status
smb_dskattr(struct smb_conn *conn, struct smb_servattr *smb_stat);

Status
smb_rmdir(struct smb_conn *conn, const char *name);

Status
smb_unlink(struct smb_conn *conn, const char *name);

Status
smb_mv(struct smb_conn *conn, const char *opath, const char *npath);

Status
smb_do_dir(struct smb_conn *conn, const char *mask,
           void (*handler)(struct smb_finfo *finfo, void *data), void *data);

Bool
smb_valid_name(const char *name);

#if DEBUG > 0
void _AssertConnSpace(const char *f, int l,
                      struct smb_conn *conn,
                      const char *p,
                      int length);
                      
#define AssertConnSpace(c,p,s) _AssertConnSpace( __FILE__, __LINE__, c,p,s)
#else
#define AssertConnSpace(c,p,s)
#endif /* DEBUG > 0 */



#endif /*_SMBLIB_H_*/
