typedef struct Rop Rop;
typedef struct Req Req;
typedef struct Trans Trans;

typedef struct Share Share;
typedef struct File File;
typedef struct Find Find;
typedef struct Tree Tree;
typedef struct Idmap Idmap;

#pragma incomplete Idmap

struct Rop
{
	int (*strpack)(uchar *, uchar *, uchar *, void *);
	int (*strunpack)(uchar *, uchar *, uchar *, void *);
	int (*namepack)(uchar *, uchar *, uchar *, void *);
	int (*nameunpack)(uchar *, uchar *, uchar *, void *);
	int (*untermstrpack)(uchar *, uchar *, uchar *, void *);
	int (*untermnamepack)(uchar *, uchar *, uchar *, void *);
};

struct Req
{
	int cmd;
	int tid;
	int pid;
	int uid;
	int mid;
	int flags;
	int flags2;

	uchar sig[8];

	uchar *lh, *rh, *rp, *re;

	Rop *o;
	char *name;
	void (*respond)(Req *r, int err);
	int (*namecmp)(char *, char *);
};

struct Trans
{
	int cmd;
	int flags;

	struct {
		struct {
			uchar *b, *p, *e;
		} param, data, setup;
	} in, out;

	Req *r;
	Rop *o;
	char *name;
	void (*respond)(Trans *t, int err);
	int (*namecmp)(char *, char *);
};

struct File
{
	int ref;
	int fd;
	int rtype;
	int dacc;
	char *path;
	void *aux;
};

struct Find
{
	int ref;
	int attr;
	char *base;
	char *pattern;
	int casesensitive;
	int index;
	Dir *dotdot;
	Dir *dot;
	Dir *dir;
	int ndir;
};

struct Share
{
	Share *next;

	char *service;
	int stype;

	char *name;
	char *root;
	char *remark;

	char *fsname;
	int namelen;
	vlong allocsize;
	vlong freesize;
	int sectorsize;
	int blocksize;

	Idmap *users;
	Idmap *groups;
};

struct Tree
{
	int tid;

	void **file;
	int nfile;

	void **find;
	int nfind;

	Share *share;
};

int debug;
int trspaces;
int needauth;
char *domain;
char *progname;
char *osname;

char *remotesys;
char *remoteuser;
int remotebuffersize;

long starttime;
int tzoff;

enum
{
	BUFFERSIZE = 0x8000,

	STATUS_INVALID_SMB				= 0x00010002,
	STATUS_SMB_BAD_TID				= 0x00050002,
	STATUS_SMB_BAD_FID				= 0x00060001,
	STATUS_OS2_INVALID_ACCESS		= 0x000C0001,
	STATUS_SMB_BAD_COMMAND			= 0x00160002,
	STATUS_SMB_BAD_UID				= 0x005B0002,
	STATUS_OS2_INVALID_LEVEL  		= 0x007C0001,
	STATUS_NO_MORE_FILES			= 0x80000006,
	STATUS_NOT_IMPLEMENTED			= 0xC0000002,
	STATUS_INVALID_HANDLE			= 0xC0000008,
	STATUS_NO_SUCH_FILE				= 0xC000000F,
	STATUS_ACCESS_DENIED			= 0xC0000022,
	STATUS_OBJECT_NAME_NOT_FOUND	= 0xC0000034,
	STATUS_OBJECT_NAME_COLLISION	= 0xC0000035,
	STATUS_OBJECT_PATH_INVALID		= 0xC0000039,
	STATUS_OBJECT_PATH_NOT_FOUND	= 0xC000003A,
	STATUS_OBJECT_PATH_SYNTAX_BAD	= 0xC000003B,
	STATUS_SHARING_VIOLATION		= 0xC0000043,
	STATUS_LOGON_FAILURE			= 0xC000006D,
	STATUS_FILE_IS_A_DIRECTORY		= 0xC00000BA,
	STATUS_NOT_SUPPORTED			= 0xC00000BB,
	STATUS_BAD_DEVICE_TYPE			= 0xC00000CB,
	STATUS_BAD_NETWORK_NAME 		= 0xC00000CC,
	STATUS_NOT_SAME_DEVICE			= 0xC00000D4,
	STATUS_DIRECTORY_NOT_EMPTY		= 0xC0000101,

	/* resource type */
	FileTypeDisk = 0,

	/* stype */
	STYPE_DISKTREE = 0,
	STYPE_PRINTQ = 1,
	STYPE_DEVICE = 2,
	STYPE_IPC = 3,

	/* capabilities */
	CAP_UNICODE = 0x4,
	CAP_LARGEFILES = 0x8,
	CAP_NT_SMBS = 0x10,
	CAP_NT_STATUS = 0x40,
	CAP_NT_FIND = 0x200,
	CAP_UNIX = 0x800000,

	/* extended file attributes */
	ATTR_READONLY = 0x1,
	ATTR_HIDDEN = 0x2,
	ATTR_SYSTEM = 0x4,
	ATTR_DIRECTORY = 0x10,
	ATTR_ARCHIVE = 0x20,
	ATTR_NORMAL = 0x80,

	DOSMASK	 = 0x37,

	/* access */
	FILE_READ_DATA = 0x1,
	FILE_WRITE_DATA = 0x2,
	FILE_APPEND_DATA = 0x4,
	FILE_EXECUTE = 0x20,
	FILE_DELETE = 0x10000,
	GENERIC_ALL = 0x10000000,
	GENERIC_EXECUTE = 0x20000000,
	GENERIC_WRITE = 0x40000000,
	GENERIC_READ = 0x80000000,

	READMASK =
		FILE_READ_DATA |
		FILE_EXECUTE |
		GENERIC_ALL |
		GENERIC_EXECUTE |
		GENERIC_READ,

	WRITEMASK = 
		FILE_WRITE_DATA |
		FILE_APPEND_DATA |
		GENERIC_ALL |
		GENERIC_WRITE,

	/* share access */
	FILE_SHARE_NONE = 0,
	FILE_SHARE_READ = 1,
	FILE_SHARE_WRITE = 2,
	FILE_SHARE_DELETE = 4,
	FILE_SHARE_COMPAT = -1,

	/* createdisposition */
	FILE_SUPERSEDE = 0,
	FILE_OPEN,
	FILE_CREATE,
	FILE_OPEN_IF,
	FILE_OVERWRITE,
	FILE_OVERWRITE_IF,

	/* createaction */
	FILE_SUPERSEDED = 0,
	FILE_OPEND,
	FILE_CREATED,
	FILE_OVERWRITTEN,

	/* createoptions */
	FILE_DIRECTORY_FILE = 0x1,
	FILE_NON_DIRECTORY_FILE = 0x40,
	FILE_DELETE_ON_CLOSE = 0x1000,
	FILE_OPEN_BY_FILE_ID = 0x2000,
};
