/*****************************************************************************/
/* The development of this program is partly supported by IPA                */
/* (Information-Technology Promotion Agency, Japan).                         */
/*****************************************************************************/

/*****************************************************************************/
/*  cdavl.h - CUI disk allocation viewer header                              */
/*  Copyright: Copyright (c) Hitachi, Ltd. 2004-2008                         */
/*             Authors: Yumiko Sugita (yumiko.sugita.yf@hitachi.com),        */
/*                      Satoshi Fujiwara (sa-fuji@sdl.hitachi.co.jp)         */
/*                                                                           */
/*  This program is free software; you can redistribute it and/or modify     */
/*  it under the terms of the GNU General Public License as published by     */
/*  the Free Software Foundation; either version 2 of the License, or        */
/*  (at your option) any later version.                                      */
/*                                                                           */
/*  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.  See the            */
/*  GNU General Public License for more details.                             */
/*                                                                           */
/*  You should have received a copy of the GNU General Public License        */
/*  along with this program; if not, write to the Free Software              */
/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
/*****************************************************************************/

#define CDAVL_VER	"1.2.4"	/* version */
#define	COPYRIGHT	"Copyright (c) Hitachi, Ltd. 2004-2008"


/* function result code */
#define	ERROR		0	/* check false */
#define	SUCCESS		1	/* check complete */
#define	FOUND		2	/* target path found */
#define	NEXT		3	/* next find process */
#define	NOT_FOUND	4	/* target path not found */


#define	SB_OFFSET	1024	/* super block offset */
#define	COLUMNS_SIZE	80	/* line columns */


/* check mode */
enum {
	CHK_PARTITION,		/* full partition */
	CHK_FILE,		/* file/directory */
};

/* block check value */
enum {
	BT_UNUSED_BLOCK = 0,
	BT_FS1,			/* boot, super-block, group-desc */
	BT_FS2,			/* block-bitmap, inode-bitmap */
	BT_XATTR,
	BT_UNUSED_INODE,
	BT_USED_INODE,
	BT_USED_BLOCK,
	BT_FRAG_BLOCK,
};
#define	BF_NONE		0x00
#define	BF_SYS_FRAG	0x20
#define	BF_FRAG		0x40
#define	BF_IN_PROC	0x80
#define	BF_DEPTH_MASK	0x7f

/* inode check value */
enum {
	UNUSED_INODE,
	USED_INODE,
};

/* inode fragment check result */
enum {
	IS_CONTINUE,
	IS_FRAGMENT,
};


typedef struct {
	unsigned int		start;	/* start number of system block */
	unsigned int		end;	/* end number of system block */
}	t_sys_blk_info;

#define	SYSB_INFO_IS_SET(sysb)	(sysb)->end


#define	DEPTH_MAX		128	/* 7bit (flag 1bit) of t_bchk.in_proc */
#define	FNAME_MAX		256



typedef struct {
	unsigned int		top_ino;
	unsigned int		cnt;
	struct ext2_inode	*p;
}	t_inode_cache;
#define	INODE_CACHE_MAX		256


typedef struct {
	struct ext2_super_block	sb;		/* super block */
	unsigned int		bs;		/* block size */
	unsigned int		gc;		/* group count */
	char			mnt_dir[FNAME_MAX];	/* mount directory */
	struct ext2_group_desc	*gd;		/* group desc */
	t_sys_blk_info		*sysb_info;	/* system block info */
	t_inode_cache		inode_cache;	/* inode cache */
}	t_e2info;
#define	IS_MOUNT(fs)		((fs)->mnt_dir[0] != '\0')



typedef struct {
	unsigned char		in_proc;
	unsigned char		type;
}	t_bchk;


struct blk_seq {
	unsigned char		type;
	unsigned int		cnt;
	struct blk_seq		*next;
};
typedef	struct blk_seq	t_blk_seq;

#define	SET_BLK_SEQ(p, t)				\
	do {						\
		(p) = uMalloc(sizeof(t_blk_seq));	\
		if ((p)) {				\
			(p)->type = (t);		\
			(p)->cnt = 1;			\
			(p)->next = NULL;		\
		} else					\
			return ERROR;			\
	} while (0)

/*
#define	SET_NORMAL_BLK_SEQ(p)		SET_BLK_SEQ((p), BF_NONE)
#define	SET_SYS_FRAG_BLK_SEQ(p)		SET_BLK_SEQ((p), BF_SYS_FRAG)
#define	SET_FRAG_BLK_SEQ(p)		SET_BLK_SEQ((p), BF_FRAG)
*/



typedef struct {
	t_bchk*			blocks;		/* block check table */
	unsigned char*		inodes;		/* inode check table */

	int			max_depth;	/* max path depth */
						/* current path name */
	unsigned int		c_files;	/* continuous file/dir count */
	unsigned int		f_files;	/* fragmented file/dir count */
	unsigned int		fblocks;	/* file/dir block count */
	unsigned int		bn_min;		/* block number (min) */
	unsigned int		bn_max;		/* block number (max) */
	unsigned int		sfrags;		/* fragment by sys-block count*/
	unsigned int		frags;		/* fragmented block count */

	/* check path match */
	char			*p_fpath;	/* fpath pointer */
	char			name[DEPTH_MAX][FNAME_MAX];
	int			depth;		/* current path depth */
	int			path_found;	/* path found flag */

	/* block sequence of found file */
	t_blk_seq		*blk_seq;

	/* use by new syscall proccess */
	struct stat		stat;
}	t_chk;


typedef struct {
	struct ext2_inode	inode;		/* inode */
	unsigned int		ino;		/* inode number */
	unsigned int		fblocks;	/* file/directory block count */
	unsigned int		xattrs;		/* xattr block count */
	unsigned int		bn_min;		/* block number (min) */
	unsigned int		bn_max;		/* block number (max) */
	unsigned int		sfrags;		/* fragment by sys-block count*/
	unsigned int		frags;		/* fragmented block count */
	unsigned int		prev_bn;	/* previous checked block num */
	unsigned int		is_dir;		/* inode is directory? */
	t_blk_seq		*blk_seq_top;	/* block sequence (top) */
	t_blk_seq		*blk_seq;	/* block sequence (current) */
}	t_inode_info;


typedef struct {
	char			*dev_name;	/* device name */
	char			*fpath;		/* path of match check */
	int			mode;		/* check mode */
	int			fd;		/* file descriptor */
	int			liveinfo_fd;	/* liveinfo file descriptor */
	/* flag option */
	int			tcnts_view;	/* type-counts display */
	int			tcnts_one_line;	/* 1-line type-counts display */
	int			color;		/* color display */
	int			compare_bitmap;	/* compare bitmap */
	int			not_follow;	/* not follow directory tree
						   after path match*/
	int			not_use_devdrv;	/* not use device driver */
	int			verbose_level;	/* verbose level */
}	t_prog_const;


#define	READ_BLOCK(prog_c, info, bn, buf)	\
	uSeekRead((prog_c)->fd, (off_t)(bn) * (info)->bs, (buf), (info)->bs)



/* for displaying partition information */
typedef struct {
	unsigned int	major;
	unsigned int	minor;
	unsigned int	blocks;
	unsigned int	is_mount;
	char		name[COLUMNS_SIZE];
}	t_partition;



/* davl_liveinfo device driver support */
#define	LIVEINFO_PATH	"/dev/davl_liveinfo"
