1/*	$NetBSD: readufs.h,v 1.12 2013/06/18 18:18:58 christos Exp $	*/
2/*	from Id: readufs.h,v 1.9 2003/10/15 14:16:58 itohy Exp 	*/
3
4/*
5 * Written in 1999, 2002, 2003 by ITOH Yasufumi.
6 * Public domain.
7 */
8
9#include <sys/types.h>
10#include <sys/param.h>
11#ifdef USE_LFS
12#include <ufs/lfs/lfs.h>
13#endif
14#include <ufs/ufs/dinode.h>
15#include <ufs/lfs/lfs.h>
16#include <ufs/ufs/dir.h>
17
18/*
19 * UFS1 / UFS2
20 */
21union ufs_dinode {
22#ifdef USE_UFS1
23	struct ufs1_dinode di1;
24#endif
25#ifdef USE_UFS2
26	struct ufs2_dinode di2;
27#endif
28#ifdef USE_LFS
29	struct lfs32_dinode dil32;
30#endif
31};
32
33/* For more compact code and independence on 64-bit types and ops */
34typedef uint32_t	ino32_t;
35
36/* short-cut for common fields (di_mode, di_nlink) */
37#ifdef USE_UFS1
38# define di_common	di1
39#elif defined USE_UFS2
40# define di_common	di2
41#endif
42
43/* for fields of same names and different locations */
44#if !(defined(USE_UFS1) && defined(USE_UFS2))
45# ifdef USE_UFS1
46#  define di_thisver	di1
47# endif
48# ifdef USE_UFS2
49#  define di_thisver	di2
50# endif
51#endif
52
53/* this is a size hack */
54#if defined(USE_UFS1) && defined(USE_UFS2)
55# define DI_SIZE(di)	((di)->di1.di_size)
56#else
57# define DI_SIZE(di)	((di)->di_thisver.di_size)
58#endif
59/* and may break following fields on UFS2 */
60#define di_gid		di_gid__is_not_available
61#define di_blksize	di_blksize__is_not_available
62
63/*
64 * filesystem information
65 */
66struct ufs_info {
67	enum ufs_fstype {
68		UFSTYPE_UNKNOWN
69#ifdef USE_FFS
70		, UFSTYPE_FFS
71#endif
72#ifdef USE_LFS
73		, UFSTYPE_LFS
74#endif
75	} fstype;
76#if defined(USE_UFS1) && defined(USE_UFS2)
77	enum ufs_ufstype {
78		UFSTYPE_UFS1, UFSTYPE_UFS2
79	} ufstype;
80#endif
81	int (*get_inode)(ino32_t ino, union ufs_dinode *dibuf);
82
83	/* superblock information */
84	u_int32_t bsize;	/* fs block size */
85	u_int32_t nindir;	/* # indirect per block */
86	u_int32_t fsbtodb;	/* block -> sector shift count */
87	union {
88#ifdef USE_FFS
89		struct {
90			daddr_t iblkno;		/* inode-block offset */
91			int32_t old_cgoffset;	/* cylinder group offset */
92			int32_t old_cgmask;	/* cylinder group mask */
93			int32_t fragshift;	/* block to fragmentation */
94			int32_t inopb;		/* # inodes per block */
95			int32_t ipg;		/* # inodes per group */
96			int32_t fpg;		/* # inodes per group * frag */
97			int32_t magic;		/* FS_UFSx_MAGIC */
98		} u_ffs;
99#endif
100#ifdef USE_LFS
101		struct {
102			u_int32_t version;	/* LFS version # */
103			daddr_t idaddr;		/* ifile inode disk address */
104			u_int32_t inopb;	/* inodes per block (v1) */
105						/* inodes per frag (v2) */
106			u_int32_t ifpb;		/* inode addrs / ifile block */
107			u_int32_t ioffset;	/* start of inode in ifile */
108						/* (in sector) */
109			u_int32_t ibsize;	/* size of inode block */
110		} u_lfs;
111#endif
112	} fs_u;
113};
114
115extern struct ufs_info	ufs_info;
116#define ufs_get_inode(ino, di)	((*ufs_info.get_inode)((ino), (di)))
117
118void RAW_READ(void *buf, daddr_t blkpos, size_t bytelen);
119
120size_t ufs_read(union ufs_dinode *di, void *buf, unsigned off,
121    size_t count);
122ino32_t ufs_lookup(ino32_t dirino, const char *fn);
123ino32_t ufs_lookup_path(const char *path);
124size_t ufs_load_file(void *buf, ino32_t dirino, const char *fn);
125int ufs_init(void);
126
127#ifdef USE_FFS
128int try_ffs(void);
129#endif
130
131#ifdef USE_LFS
132int try_lfs(void);
133#endif
134
135#ifdef DEBUG_WITH_STDIO
136#include <fcntl.h>
137#include <err.h>
138#include <stdio.h>
139#include <unistd.h>
140#include <stdlib.h>
141#endif
142
143#ifdef __GNUC__
144# ifndef alloca
145#  define alloca(n)	__builtin_alloca(n)
146# endif
147# ifndef strcmp
148#  define strcmp(p, q)	__builtin_strcmp(p, q)
149# endif
150#endif
151