/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program 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.

**********************************************************************/


#ifndef ___INCLUDE_H___
#define ___INCLUDE_H___

#ifndef INLINE
#ifdef MSC_VER
#define INLINE __inline
#elif __GNUC__
#define INLINE __inline__
#else
#define INLINE 
#endif
#endif

#define INLINE_STATIC	INLINE static

#ifndef OFF_POSIX_INCLUDE

#include	<sys/param.h>
#include	<math.h>
#include	<stdlib.h>
#include	<netdb.h>
#include	<errno.h>
#include	<sys/types.h>
#include	<sys/socket.h>
#include	<netinet/in.h>
#include	<arpa/inet.h>
#include	<stdio.h>
#include	<unistd.h>
#include	<dirent.h>
#include	<sys/stat.h>
#include	<string.h>
#include	<strings.h>
#include 	<ctype.h>
#include	<utime.h>

#include	<fcntl.h>
#ifdef VA2
#include	<varargs.h>
#else
#include	<stdarg.h>
#endif

#include	<sys/wait.h>
#include	<sys/time.h>
#include	<signal.h>
#include 	<sys/stat.h>

#endif

#include	"m_include.h"

#ifndef SA_INTERRUPT
#define SA_INTERRUPT	0
#endif

#define INTEGER64	long long
#define U_INTEGER64	unsigned long long
#define CONST_INT64(val) (val##LL)
#define I64_FORMAT "%lli"

#ifdef U_FILE_LIB
int m_mkdir(char*,int);
#else
int m_mkdir(char*,...);
#endif
#define _m_mkdir

#define m_getcwd getcwd
#define m_utime utime


typedef struct ufr_err {
	int		ufr_code;
#define UFR_E_FD	1
#define UFR_E_OK	0
#define UFR_E_ERRNO	(-1)
#define UFR_E_ARGC	(-2)
#define UFR_E_ARGV	(-3)
#define UFR_E_OWN	(-4)
#define UFR_E_FORK	(-5)
#define UFR_E_PERM	(-6)
#define UFR_E_CONN	(-7)
	union {
		int		sys_code;
		int		d_int;
		INTEGER64	d_int64;
	} r;
} UFR_ERR;


typedef union ufr_args {
	int		type;
#define UFR_T_INT		1
#define UFR_T_INT64		2
#define UFR_T_CHAR_PTR		3
#define UFR_T_REP_CHAR_PTR	4
	struct {
		int	type;
		int	d;
	} d_int;
	struct {
		int		type;
		INTEGER64	d;
	} d_int64;
	struct {
		int	type;
		int	len;
		char *	d;
	} d_char_ptr;
	struct {
		int	type;
		int 	len;
		char *	d;
	} d_rep_char_ptr;
} UFR_ARGS;



typedef struct ufr_req {
	struct ufr_req *	next;
	int			seq;
	int			ok;

	int			uid;
	int			transaction;
	int			ufr_code;
	int			argc;
	UFR_ARGS *		argv;
	UFR_ERR			ret;
} UFR_REQ;

typedef struct ufr_log {
	struct ufr_log *	next;
	int			seq;
	int			code;
} UFR_LOG;

typedef struct ufr_blk {
	struct ufr_blk *	next;
	int			seq;
	int			read_op;
	int			send;
	int			recv;
	int			uid;

	UFR_REQ *		req_queue;
	int			transaction;
	int			last_time;
	int			create_time;

	UFR_LOG *		send_log;
	UFR_LOG *		recv_log;
} UFR_BLK;

typedef union ufr_tbl {
	struct __fns {
	UFR_ERR		(*u_open)(UFR_REQ*);
	UFR_ERR		(*u_open64)(UFR_REQ*);
	UFR_ERR		(*u_close)(UFR_REQ*);
	UFR_ERR		(*u_read)(UFR_REQ*);
	UFR_ERR		(*u_write)(UFR_REQ*);
	UFR_ERR		(*u_lseek)(UFR_REQ*);
	UFR_ERR		(*u_lseek64)(UFR_REQ*);
	UFR_ERR		(*u_unlink)(UFR_REQ*);
	UFR_ERR		(*u_rmdir)(UFR_REQ*);
	UFR_ERR		(*u_mkdir)(UFR_REQ*);

	int		(*check_own)(int*,char*);
	UFR_ERR		(*__ufr_call)(UFR_REQ * rq);
	void		(*__u_cp)(char *,int);
	} fns;
	UFR_ERR		(*fns_Ary[sizeof(struct __fns)/sizeof(UFR_ERR(*)())])(UFR_REQ*);
} UFR_TBL;


extern UFR_TBL * ufr_dispatch;

void init_u_fileroot();
UFR_ERR __ufr_call(UFR_REQ * rq);

void throw_signal_enable();
void throw_signal_disable();


#define U_CP(tbl)	(*tbl->fns.__u_cp)(__FILE__,__LINE__)

#define UFR_CODE(x)	(((int)(&((UFR_TBL*)(0))->fns.x))/sizeof(UFR_ERR(*)()))

#define UFR_C_OPEN	UFR_CODE(u_open)
#define UFR_C_OPEN64	UFR_CODE(u_open64)
#define UFR_C_CLOSE	UFR_CODE(u_close)
#define UFR_C_READ	UFR_CODE(u_read)
#define UFR_C_WRITE	UFR_CODE(u_write)
#define UFR_C_LSEEK	UFR_CODE(u_lseek)
#define UFR_C_LSEEK64	UFR_CODE(u_lseek64)
#define UFR_C_UNLINK	UFR_CODE(u_unlink)
#define UFR_C_RMDIR	UFR_CODE(u_rmdir)
#define UFR_C_MKDIR	UFR_CODE(u_mkdir)

#define XLPATH_DELIM	";\t\n\r :"

void send_alarm(int tid);
void send_sw_trigger(unsigned int);

#endif
