aboutsummaryrefslogtreecommitdiff
path: root/src/libdiskfs/hfs.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libdiskfs/hfs.h')
-rw-r--r--src/libdiskfs/hfs.h210
1 files changed, 210 insertions, 0 deletions
diff --git a/src/libdiskfs/hfs.h b/src/libdiskfs/hfs.h
new file mode 100644
index 00000000..2f6d943d
--- /dev/null
+++ b/src/libdiskfs/hfs.h
@@ -0,0 +1,210 @@
+/*
+ Supports HFS Plus and HFSX file systems with or without an HFS
+ wrapper.
+
+ Apple technical note 1150 documents the file system:
+
+ http://developer.apple.com/technotes/tn/tn1150.html
+
+ Briefly an hfs file system comprises a volume header, an
+ optional journal, and a set of forks.
+
+ Most fs metadata resides in forks including a block allocation
+ bitmap, a tree storing extents (q.v.) for forks and bad disk
+ blocks, and a tree storing catalog (file and directory)
+ information.
+
+ An extent comprises a starting block number and block count.
+ The fs maintains a list of k*NEXTENTS extents for each fork.
+ These are used to map fork block numbers to disk block
+ numbers. A fork's initial extents are in its catalog record
+ or (for fs forks) the volume header. The rest are in the
+ extents tree.
+
+ Fs trees are layed out (in a fork) as an array of fixed-size
+ nodes. A node comprises a header, a sorted list of
+ variable-size records, and trailing record offsets. The
+ records in interior nodes map keys to (child) node numbers.
+ The records in leaf nodes map keys to data. The nodes at each
+ level in a tree are also sorted via (sibling) node numbers
+ stored in each node header.
+*/
+
+typedef struct Extent Extent;
+typedef struct Fork Fork;
+typedef struct Inode Inode;
+typedef struct Tree Tree;
+typedef struct Node Node;
+typedef struct Treeref Treeref;
+typedef struct Key Key;
+typedef struct Extentkey Extentkey;
+typedef struct Name Name;
+typedef struct Catalogkey Catalogkey;
+typedef struct Hfs Hfs;
+
+enum
+{
+ Hfssig = 0x4244,
+ Hfsplussig = 0x482B,
+ Hfsxsig = 0x4858,
+ Hfsplusmagic = (Hfsplussig<<16)|4,
+ Hfsxmagic = (Hfsxsig<<16)|5,
+
+ NAMELEN = 255,
+ UTFNAMELEN = NAMELEN*UTFmax,
+
+ NEXTENTS = 8,
+
+ Dfork = 0, Rfork = 255,
+
+ /* fixed cnids */
+ RootpId = 1, RootId, ExtentsId, CatalogId,
+ BadblockId, AllocId, MinuserId = 16,
+
+ /* size of a few structures on disk */
+ Extentlen = 8, /* Extent */
+ Ndlen = 14, /* Node */
+ Folderlen = 88, Filelen = 248, /* Inode */
+
+ /* values in Node.type */
+ LeafNode = -1, IndexNode, HeaderNode, MapNode,
+
+ /* catalog record types */
+ Folder = 1, File, FolderThread, FileThread,
+
+ /* permissions in Inode.mode */
+ IEXEC = 00100,
+ IWRITE = 0200,
+ IREAD = 0400,
+ ISTXT = 01000,
+ ISGID = 02000,
+ ISUID = 04000,
+
+ /* type in Inode.mode */
+ IFMT = 0170000,
+ IFIFO = 0010000,
+ IFCHR = 0020000,
+ IFDIR = 0040000,
+ IFBLK = 0060000,
+ IFREG = 0100000,
+ IFLNK = 0120000,
+ IFSOCK = 0140000,
+ IFWHT = 0160000,
+};
+
+struct Extent
+{
+ u32int start; /* first block in extent */
+ u32int count; /* number of blocks in extent */
+};
+
+struct Fork
+{
+ u32int cnid; /* catalog node id (in memory only) */
+ int type; /* Dfork or Rfork (in memory only) */
+ u64int size; /* size in bytes */
+ u32int nblocks;
+ Extent extent[NEXTENTS]; /* initial extents */
+};
+
+/*
+ * In-core catalog record for a file or folder.
+ */
+struct Inode
+{
+ u32int cnid;
+ u32int mtime; /* modification */
+ u32int ctime; /* attribute modification */
+ u32int atime; /* access */
+ u32int uid;
+ u32int gid;
+ int mode;
+ u32int special;
+ union{
+ u32int nentries; /* directories */
+ struct{ /* files */
+ Fork dfork;
+ /*Fork rfork;*/
+ };
+ };
+};
+
+struct Tree
+{
+ int nodesize; /* node size in bytes */
+ u32int nnodes; /* number of nodes in tree */
+ u32int root; /* node number of the tree's root */
+ int height;
+ int maxkeylen; /* maximum key size in bytes */
+ int indexkeylen; /* 0 or length of index node keys */
+ int sensitive; /* are key strings case sensitive */
+ Hfs *fs;
+ Fork *fork;
+};
+
+struct Node
+{
+ int type; /* type of this node */
+ u32int next; /* next related node or 0 */
+ int nrec; /* number of records in this node */
+};
+
+struct Treeref
+{
+ Tree *tree;
+ u32int cnid; /* tree->fork->cnid, for debugging prints */
+
+ Block *block; /* a node in the tree */
+ u32int nno;
+ Node node;
+
+ int rno; /* a record in the node */
+ int klen;
+ uchar *key;
+ int dlen;
+ uchar *data;
+};
+
+struct Key
+{
+ int (*_cmp)(uchar *k, int len, int *order, Key *key);
+ void *priv;
+};
+
+struct Extentkey
+{
+ u32int cnid;
+ int type;
+ u32int bno;
+};
+
+struct Name
+{
+ int len;
+ Rune name[NAMELEN]; /* only len runes on disk */
+};
+
+struct Catalogkey
+{
+ u32int parent;
+ union{
+ Name name;
+ uchar *b; /* not yet decoded */
+ };
+};
+
+struct Hfs
+{
+ u32int blocksize;
+ u32int nblock;
+ u32int nfree; /* for debugging */
+ int hasbadblocks;
+ Fork alloc; /* block allocation bitmap */
+ Fork extentsfork;
+ Fork catalogfork;
+ Tree extents; /* Extentkey -> Extent[NEXTENT] */
+ Tree catalog; /* Catalogkey -> Catalogkey + Inode */
+ int wrapper; /* HFS wrapper used? */
+ Disk *disk;
+ Fsys *fsys;
+};