OpenBIOS
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1999 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1998 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1997 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1996 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1995 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1994 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1993 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1992 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1991 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1990 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1989 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1988 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1987 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1986 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1985 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1984 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1983 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1982 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1981 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1980 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1979 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1978 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1977 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1976 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1975 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1974 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1973 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1972 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1971 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1970 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1969 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1968 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1967 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1966 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1965 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1964 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1963 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1962 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1961 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1960 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1959 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1958 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1957 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1956 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1955 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1954 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1953 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1952 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1951 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1950 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1949 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1948 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1947 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1946 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1945 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1944 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1943 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1942 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1941 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1940 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1939 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1938 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1937 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1936 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1935 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1934 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1933 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1932 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1931 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1930 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1929 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1928 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1927 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1926 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1925 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1924 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1923 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1922 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1921 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1920 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1919 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1918 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1917 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1916 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1915 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1914 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1913 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1912 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1911 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1910 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1909 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1908 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1907 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1906 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1905 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1904 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
November 2010
- 10 participants
- 59 discussions
[PATCH] RFC: Change ofmem_common.c to set memory translation properties by reference
by Mark Cave-Ayland May 4, 2011
by Mark Cave-Ayland May 4, 2011
May 4, 2011
Hi folks,
The attached patch changes OFMEM so that instead of allocating new space
within the Forth dictionary every time the /memory and /virtual-memory
available/translations nodes are updated, we simply change the property
to point directly to a static buffer. This has the effect of saving
substantial amounts of memory during OpenSolaris 10 boot (in fact the
final dictionary size after boot is now < 256K once again).
Blue/Andreas: please could you take a look at this patch and make sure
it doesn't break anything in your SPARC64/PPC tests?
On the plus side, with this patch applied Milax gets to the end of its
natural boot without crashing giving the following output:
OpenBIOS for Sparc64
Configuration device id QEMU version 1 machine id 0
kernel cmdline
CPUs: 1 x SUNW,UltraSPARC-IIi
UUID: 00000000-0000-0000-0000-000000000000
Welcome to OpenBIOS v1.0 built on Oct 14 2010 20:18
Type 'help' for detailed information
Trying cdrom:f...
Not a bootable ELF image
Not a bootable a.out image
Loading FCode image...
Loaded 7084 bytes
entry point is 0x4000
Ignoring failed claim for va 1000000 memsz bf34e!
Ignoring failed claim for va 1402000 memsz 303b3!
Ignoring failed claim for va 1800000 memsz 60a30!
Jumping to entry point 00000000010071d8 for type 0000000000000001...
switching to new context: entry point 0x10071d8 stack 0x00000000ffe06b49
warning:interpret: exception -13 caught
SunOS Release 5.11 Version MilaX_0.3.2 64-bit
Copyright 1983-2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
spacex@:interpret: exception -13 caught
kdbg-words:interpret: exception -13 caught
cb-r/w:interpret: exception -13 caught
(Can't load tod module) EXIT
-1 >
Does anyone know what the tod modules does? Is it Time Of Day (i.e. we
are missing some kind of hardware clock emulation?)
ATB,
Mark.
--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063
Sirius Labs: http://www.siriusit.co.uk/labs
4
14
Display one MMU translation per row for .properties command.
Signed-off-by: Andreas Färber <andreas.faerber(a)web.de>
---
forth/admin/devices.fs | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/forth/admin/devices.fs b/forth/admin/devices.fs
index 7a5b693..00b4f55 100644
--- a/forth/admin/devices.fs
+++ b/forth/admin/devices.fs
@@ -326,6 +326,30 @@
3drop drop
;
+\ Print the value of the MMU translations property
+: .p-translations ( data len -- )
+ 2dup + -rot ( data+len data len )
+ >r >r [IFDEF] CONFIG_PPC
+ [IFDEF] CONFIG_PPC64 5 [ELSE] 4 [THEN]
+ [ELSE]
+ 3
+ [THEN] 4 * dup ( data+len #bytes #bytes R: len data ) r> r>
+ bounds ( data+len #bytes #bytes data+len data ) ?do
+ 2dup <> if \ non-first byte in row
+ dup 3 and 0= if space then \ make numbers more readable
+ then
+ i c@ 2 0.r \ print byte
+ 1- dup 0= if \ end of row
+ 2 pick i 1+ > if \ non-last byte
+ cr \ start new line
+ d# 26 spaces \ indentation
+ then
+ drop dup \ update counter
+ then
+ loop
+ 2drop drop
+;
+
\ This function hardwires data formats to particular node properties
: (.property-by-name) ( name-str name-len data len -- )
2over " reg" strcmp 0= if
@@ -346,6 +370,10 @@
1 1 2swap .p-reg
2drop exit
then
+ 2over " translations" strcmp 0= if
+ .p-translations
+ 2drop exit
+ then
then
then
then
--
1.7.3
3
11
Dec. 12, 2010
Hi all,
Here is my first attempt at switching over OFMEM to use phys_addr_t for
physical addresses. It was mainly a case of going through all of the
OFMEM APIs by hand and then updating the definitions used to hold
physical addresses, along with swapping over range_t to use phys_addr_t
on the assumption that sizeof(phys_addr_t) >= sizeof(ucell).
Andreas - note I've not touched anything in ppc64 as I figure this is
still experimental and I don't really have anything to test it with.
This patch seems to work on my SPARC64/PPC tests here, but since it
touches a core part of OpenBIOS I'd like to get a little more feedback
before committing it.
ATB,
Mark.
--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063
Sirius Labs: http://www.siriusit.co.uk/labs
3
27
.properties before:
someproperty -- 3 : 1 42 3
Now:
someproperty -- 3 : 01 42 03
Signed-off-by: Andreas Färber <andreas.faerber(a)web.de>
---
forth/admin/devices.fs | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/forth/admin/devices.fs b/forth/admin/devices.fs
index e24c6da..dbb4646 100644
--- a/forth/admin/devices.fs
+++ b/forth/admin/devices.fs
@@ -283,7 +283,7 @@
dup r@ + c@
( len n ch )
- pocket tohexstr type ." "
+ pocket tohexstr dup 2 <> if ." 0" then type ." "
1+
repeat
2drop r> drop 1
--
1.7.3
5
52
Hi folks,
It's taken me a lot longer to get to grips with moving SPARC32 to OFMEM
than expected, mostly due to problems with the increased BSS size of the
resulting image causing several large headaches.
Having spent some time looking at where the memory is currently being
used, it strikes me that there are 2 main places where we can claim some
back:
i) Reduce (remove) the runtime memory allocated to the Forth machine
One interesting aspect of the current design is that we have 2 memory
allocation ranges - the Forth machine memory which is used for alloc-mem
and free-mem, and also the OFMEM ranges. For example, in SPARC32 this is
set to 256K which given the large I/O space requirements for the frame
buffer, is about a quarter of the total memory.
I'd like to suggest that we unify the memory management by removing the
Forth implementations of alloc-mem/free-mem and replace them with
wrappers to the internal ofmem_malloc() and ofmem_free() functions. This
would then enable us to have one continuous pool of allocatable memory
which could be used for everything.
One slight issue with this is that there are a few references to
alloc-mem/free-mem within the internal Forth code. These are mainly for
allocating static buffers, and so I believe these could be removed and
replaced by functions that simply allocate memory within the dictionary
itself.
ii) Avoid re-allocation of memory for the Forth dictionary
At runtime we currently have two copies of the dictionary held within
memory - the first is the actual static dictionary data, while the
second is the relocated dictionary image within the BSS. In the case of
SPARC32 this is responsible for just over 100K of the BSS image size.
Rather than having to allocate a second copy of the dictionary, would it
make sense to embed the fixed size dictionary directly within the
OpenBIOS image? As an example SPARC32 specifies 256K for the total
dictionary size.
I think it should be possible to rewrite the relocation routine to
relocate the dictionary 'in place' and then remove the relocation data
so that the dictionary can extend normally up to its final limit. The
downside of this is that the ROM images will be bigger on disk, but I
don't feel that this should be too much of an issue.
I realise that these two ideas are probably fairly controversial, but
they should both help considerably reduce the size of the OpenBIOS
runtime memory footprint. Thoughts/comments/criticisms?
ATB,
Mark.
--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063
Sirius Labs: http://www.siriusit.co.uk/labs
3
5
[commit] r969 - in trunk/openbios-devel/arch: ppc/qemu ppc64/qemu
by repository service Nov. 30, 2010
by repository service Nov. 30, 2010
Nov. 30, 2010
Author: afaerber
Date: Thu Nov 25 22:56:23 2010
New Revision: 969
URL: http://tracker.coreboot.org/trac/openbios/changeset/969
Log:
ppc: Set up TOC base for ppc64
r2 points to TOC base, __toc_start + 0x8000.
This value is stored as part of the function descriptor.
Include some related ELF sections in the linker script.
Cc: Alexander Graf <agraf(a)suse.de>
Cc: Segher Boessenkool <segher(a)kernel.crashing.org>
Signed-off-by: Andreas Färber <andreas.faerber(a)web.de>
Modified:
trunk/openbios-devel/arch/ppc/qemu/start.S
trunk/openbios-devel/arch/ppc64/qemu/ldscript
Modified: trunk/openbios-devel/arch/ppc/qemu/start.S
==============================================================================
--- trunk/openbios-devel/arch/ppc/qemu/start.S Thu Nov 25 22:53:25 2010 (r968)
+++ trunk/openbios-devel/arch/ppc/qemu/start.S Thu Nov 25 22:56:23 2010 (r969)
@@ -445,6 +445,13 @@
/* save memory size in stack */
+#ifdef __powerpc64__
+ /* set up TOC pointer */
+
+ LOAD_REG_IMMEDIATE(r2, setup_mmu)
+ ld r2, 8(r2)
+#endif
+
bl BRANCH_LABEL(setup_mmu)
bl BRANCH_LABEL(entry)
1: nop
Modified: trunk/openbios-devel/arch/ppc64/qemu/ldscript
==============================================================================
--- trunk/openbios-devel/arch/ppc64/qemu/ldscript Thu Nov 25 22:53:25 2010 (r968)
+++ trunk/openbios-devel/arch/ppc64/qemu/ldscript Thu Nov 25 22:56:23 2010 (r969)
@@ -41,8 +41,18 @@
_data = .;
*(.data)
*(.data.*)
+ *(.toc1)
+ *(.branch_lt)
_edata = .;
}
+ .opd : {
+ *(.opd)
+ }
+ .got : {
+ __toc_start = .;
+ *(.got)
+ *(.toc)
+ }
.bss ALIGN(4096): {
_bss = .;
4
19
Files in fs/hfs and fs/hfsplus have same names, this causes problems
during linkage.
Use prefix 'hfsp_' for the conflicting files.
Signed-off-by: Blue Swirl <blauwirbel(a)gmail.com>
---
fs/hfsplus/btree.c | 372 -----------------------
fs/hfsplus/build.xml | 6 +-
fs/hfsplus/hfsp_btree.c | 372 +++++++++++++++++++++++
fs/hfsplus/hfsp_record.c | 759 ++++++++++++++++++++++++++++++++++++++++++++++
fs/hfsplus/hfsp_volume.c | 314 +++++++++++++++++++
fs/hfsplus/record.c | 759 ----------------------------------------------
fs/hfsplus/volume.c | 314 -------------------
7 files changed, 1448 insertions(+), 1448 deletions(-)
delete mode 100644 fs/hfsplus/btree.c
create mode 100644 fs/hfsplus/hfsp_btree.c
create mode 100644 fs/hfsplus/hfsp_record.c
create mode 100644 fs/hfsplus/hfsp_volume.c
delete mode 100644 fs/hfsplus/record.c
delete mode 100644 fs/hfsplus/volume.c
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
deleted file mode 100644
index 5409418..0000000
--- a/fs/hfsplus/btree.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * libhfs - library for reading and writing Macintosh HFS volumes
- * The fucntions are used to handle the various forms of btrees
- * found on HFS+ volumes.
- *
- * The fucntions are used to handle the various forms of btrees
- * found on HFS+ volumes.
- *
- * Copyright (C) 2000 Klaus Halfmann <khalfmann(a)libra.de>
- * Original 1996-1998 Robert Leslie <rob(a)mars.org>
- * Additional work by Brad Boyer (flar(a)pants.nu)
- *
- * 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., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * $Id: btree.c,v 1.14 2000/10/25 05:43:04 hasi Exp $
- */
-
-#include "config.h"
-#include "libhfsp.h"
-#include "volume.h"
-#include "btree.h"
-#include "record.h"
-#include "swab.h"
-
-/* Read the node from the given buffer and swap the bytes.
- *
- * return pointer after reading the structure
- */
-static void* btree_readnode(btree_node_desc* node, void *p)
-{
- node->next = bswabU32_inc(p);
- node->prev = bswabU32_inc(p);
- node->kind = bswabU8_inc(p);
- node->height = bswabU8_inc(p);
- node->num_rec = bswabU16_inc(p);
- node->reserved = bswabU16_inc(p);
- return p;
-}
-
-/* read a btree header from the given buffer and swap the bytes.
- *
- * return pointer after reading the structure
- */
-static void* btree_readhead(btree_head* head, void *p)
-{
- UInt32 *q;
- head->depth = bswabU16_inc(p);
- head->root = bswabU32_inc(p);
- head->leaf_count = bswabU32_inc(p);
- head->leaf_head = bswabU32_inc(p);
- head->leaf_tail = bswabU32_inc(p);
- head->node_size = bswabU16_inc(p);
- head->max_key_len = bswabU16_inc(p);
- head->node_count = bswabU32_inc(p);
- head->free_nodes = bswabU32_inc(p);
- head->reserved1 = bswabU16_inc(p);
- head->clump_size = bswabU32_inc(p);
- head->btree_type = bswabU8_inc(p);
- head->reserved2 = bswabU8_inc(p);
- head->attributes = bswabU32_inc(p);
- // skip reserved bytes
- q=((UInt32*) p);
- // ((UInt32*) p) += 16;
- q+=16;
- return q;
-}
-
-/* Priority of the depth of the node compared to LRU value.
- * Should be the average number of keys per node but these vary. */
-#define DEPTH_FACTOR 1000
-
-/* Cache size is height of tree + this value
- * Really big numbers wont help in case of ls -R
- */
-#define EXTRA_CACHESIZE 3
-
-/* Not in use by now ... */
-#define CACHE_DIRTY 0x0001
-
-/* Intialize cache with default cache Size,
- * must call node_cache_close to deallocate memory */
-static int node_cache_init(node_cache* cache, btree* tree, int size)
-{
- int nodebufsize;
- char * buf;
-
- cache->size = size;
- cache->currindex = 0;
- nodebufsize = tree->head.node_size + sizeof(node_buf);
- buf = malloc(size *(sizeof(node_entry) + nodebufsize));
- if (!buf)
- return -1;
- cache -> nodebufsize = nodebufsize;
- cache -> entries = (node_entry*) buf;
- cache -> buffers = (char*) &cache->entries[size];
- bzero(cache->entries, size*sizeof(node_entry));
- return 0;
-}
-
-/* Like cache->buffers[i], since size of node_buf is variable */
-static inline node_buf* node_buf_get(node_cache* cache, int i)
-{
- return (node_buf*) (cache->buffers + (i * cache->nodebufsize));
-}
-
-/* flush the node at index */
-static void node_cache_flush_node(node_cache* cache, int index)
-{
- // NYI
- cache -> entries[index].index = 0; // invalidate entry
-}
-
-static void node_cache_close(node_cache* cache)
-{
- if (!cache->entries) // not (fully) intialized ?
- return;
- free(cache->entries);
-}
-
-/* Load the cach node indentified by index with
- * the node identified by node_index */
-
-static node_buf* node_cache_load_buf
- (btree* bt, node_cache* cache, int index, UInt16 node_index)
-{
- node_buf *result = node_buf_get(cache ,index);
- UInt32 blkpernode = bt->blkpernode;
- UInt32 block = node_index * blkpernode;
- void* p = volume_readfromfork(bt->vol, result->node, bt->fork,
- block, blkpernode, HFSP_EXTENT_DATA, bt->cnid);
- node_entry *e = &cache->entries[index];
-
- if (!p)
- return NULL; // evil ...
-
- result->index = node_index;
- btree_readnode(&result->desc, p);
-
- e -> priority = result->desc.height * DEPTH_FACTOR;
- e -> index = node_index;
- return result;
-}
-
-/* Read node at given index, using cache.
- */
-node_buf* btree_node_by_index(btree* bt, UInt16 index)
-{
- node_cache* cache = &bt->cache;
- int oldindex, lruindex;
- int currindex = cache->currindex;
- UInt32 prio;
- node_entry *e;
-
- // Shortcut acces to current node, will not change priorities
- if (cache->entries[currindex].index == index)
- return node_buf_get(cache ,currindex);
- oldindex = currindex;
- if (currindex == 0)
- currindex = cache->size;
- currindex--;
- lruindex = oldindex; // entry to be flushed when needed
- prio = 0; // current priority
- while (currindex != oldindex) // round robin
- {
- e = &cache->entries[currindex];
- if (e->index == index) // got it
- {
- if (e->priority != 0) // already top, uuh
- e->priority--;
- cache->currindex = currindex;
- return node_buf_get(cache ,currindex);
- }
- else
- {
- if (!e->index)
- {
- lruindex = currindex;
- break; // empty entry, load it
- }
- if (e->priority != UINT_MAX) // already least, uuh
- e->priority++;
- }
- if (prio < e->priority)
- {
- lruindex = currindex;
- prio = e->priority;
- }
- if (currindex == 0)
- currindex = cache->size;
- currindex--;
- }
- e = &cache->entries[lruindex];
- cache->currindex = lruindex;
- if (e->flags & CACHE_DIRTY)
- node_cache_flush_node( cache, lruindex);
- return node_cache_load_buf (bt, cache, lruindex, index);
-}
-
-/** intialize the btree with the first entry in the fork */
-static int btree_init(btree* bt, volume* vol, hfsp_fork_raw* fork)
-{
- void *p;
- char buf[vol->blksize];
- UInt16 node_size;
- btree_node_desc node;
-
- bt->vol = vol;
- bt->fork = fork;
- p = volume_readfromfork(vol, buf, fork, 0, 1,
- HFSP_EXTENT_DATA, bt->cnid);
- if (!p)
- return -1;
- p = btree_readnode(&node, p);
- if (node.kind != HFSP_NODE_HEAD)
- return -1; // should not happen ?
- btree_readhead(&bt->head, p);
-
- node_size = bt->head.node_size;
- bt->blkpernode = node_size / vol->blksize;
-
- if (bt->blkpernode == 0 || vol->blksize *
- bt->blkpernode != node_size)
- return -1; // should never happen ...
-
- node_cache_init(&bt->cache, bt, bt->head.depth + EXTRA_CACHESIZE);
-
- // Allocate buffer
- // bt->buf = malloc(node_size);
- // if (!bt->buf)
- // return ENOMEM;
-
- return 0;
-}
-
-/** Intialize catalog btree, so that btree_close can safely be called. */
-void btree_reset(btree* bt)
-{
- bt->cache.entries = NULL;
-}
-
-/** Intialize catalog btree */
-int btree_init_cat(btree* bt, volume* vol, hfsp_fork_raw* fork)
-{
- int result = btree_init(bt,vol,fork); // super (...)
- bt->cnid = HFSP_CAT_CNID;
- bt->kcomp = record_key_compare;
- bt->kread = record_readkey;
- return result;
-}
-
-/** Intialize catalog btree */
-int btree_init_extent(btree* bt, volume* vol, hfsp_fork_raw* fork)
-{
- int result = btree_init(bt,vol,fork); // super (...)
- bt->cnid = HFSP_EXT_CNID;
- bt->kcomp = record_extent_key_compare;
- bt->kread = record_extent_readkey;
- return result;
-}
-
-/** close the btree and free any resources */
-void btree_close(btree* bt)
-{
- node_cache_close(&bt->cache);
- // free(bt->buf);
-}
-
-/* returns pointer to key given by index in current node.
- *
- * Assumes that current node is not NODE_HEAD ...
- */
-void* btree_key_by_index(btree* bt, node_buf* buf, UInt16 index)
-{
- UInt16 node_size = bt->head.node_size;
- // The offsets are found at the end of the node ...
- UInt16 off_pos = node_size - (index +1) * sizeof(btree_record_offset);
- // position of offset at end of node
- btree_record_offset* offset =
- (btree_record_offset*) (buf->node + off_pos);
-
- // now we have the offset and can read the key ...
-#ifdef CONFIG_LITTLE_ENDIAN
- return buf->node + bswabU16(*offset);
-#else
- return buf->node + *offset;
-#endif
-}
-
-
-#ifdef DEBUG
-
-/* print btree header node information */
-void btree_printhead(btree_head* head)
-{
- UInt32 attr;
- printf(" depth : %#X\n", head->depth);
- printf(" root : %#lX\n", head->root);
- printf(" leaf_count : %#lX\n", head->leaf_count);
- printf(" leaf_head : %#lX\n", head->leaf_head);
- printf(" leaf_tail : %#lX\n", head->leaf_tail);
- printf(" node_size : %#X\n", head->node_size);
- printf(" max_key_len : %#X\n", head->max_key_len);
- printf(" node_count : %#lX\n", head->node_count);
- printf(" free_nodes : %#lX\n", head->free_nodes);
- printf(" reserved1 : %#X\n", head->reserved1);
- printf(" clump_size : %#lX\n", head->clump_size);
- printf(" btree_type : %#X\n", head->btree_type);
- attr = head->attributes;
- printf(" reserved2 : %#X\n", head->reserved2);
- if (attr & HFSPLUS_BAD_CLOSE)
- printf(" HFSPLUS_BAD_CLOSE *** ");
- else
- printf(" !HFSPLUS_BAD_CLOSE");
- if (attr & HFSPLUS_TREE_BIGKEYS)
- printf(" HFSPLUS_TREE_BIGKEYS ");
- else
- printf(" !HFSPLUS_TREE_BIGKEYS");
- if (attr & HFSPLUS_TREE_VAR_NDXKEY_SIZE)
- printf(" HFSPLUS_TREE_VAR_NDXKEY_SIZE");
- else
- printf(" !HFSPLUS_TREE_VAR_NDXKEY_SIZE");
- if (attr & HFSPLUS_TREE_UNUSED)
- printf(" HFSPLUS_TREE_UNUSED ***\n");
- printf("\n");
-}
-
-/* Dump all the node information to stdout */
-void btree_print(btree* bt)
-{
- btree_node_desc* node;
-
- btree_printhead(&bt->head);
-
- node = &bt->node;
- printf("next : %#lX\n", node->next);
- printf("prev : %#lX\n", node->prev);
- printf("height : %#X\n", node->height);
- printf("num_rec : %#X\n", node->num_rec);
- printf("reserved : %#X\n", node->reserved);
- printf("height : %#X\n", node->height);
switch(node->kind)
- {
- case HFSP_NODE_NDX :
- printf("HFSP_NODE_NDX\n");
- break;
- case HFSP_NODE_HEAD :
- printf("HFSP_NODE_HEAD\n");
- break;
- case HFSP_NODE_MAP :
- printf("HFSP_NODE_MAP\n");
- break;
- case HFSP_NODE_LEAF :
- printf("HFSP_NODE_LEAF\n");
- break;
- default:
- printf("*** Unknown Node type ***\n");
- }
-}
-
-#endif
diff --git a/fs/hfsplus/build.xml b/fs/hfsplus/build.xml
index d3d32cb..f6f5369 100644
--- a/fs/hfsplus/build.xml
+++ b/fs/hfsplus/build.xml
@@ -1,11 +1,11 @@
<build>
<library name="fs" type="static" target="target">
<object source="blockiter.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="btree.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_btree.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
<object source="libhfsp.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="record.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_record.c"
flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/
-fno-strict-aliasing" condition="HFSP"/>
<object source="unicode.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="volume.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_volume.c"
flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/
-fno-strict-aliasing" condition="HFSP"/>
<object source="hfsp_fs.c" flags="-I$(SRCDIR)/fs/hfsplus/include
-I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
</library>
</build>
diff --git a/fs/hfsplus/hfsp_btree.c b/fs/hfsplus/hfsp_btree.c
new file mode 100644
index 0000000..24eca92
--- /dev/null
+++ b/fs/hfsplus/hfsp_btree.c
@@ -0,0 +1,372 @@
+/*
+ * libhfs - library for reading and writing Macintosh HFS volumes
+ * The fucntions are used to handle the various forms of btrees
+ * found on HFS+ volumes.
+ *
+ * The fucntions are used to handle the various forms of btrees
+ * found on HFS+ volumes.
+ *
+ * Copyright (C) 2000 Klaus Halfmann <khalfmann(a)libra.de>
+ * Original 1996-1998 Robert Leslie <rob(a)mars.org>
+ * Additional work by Brad Boyer (flar(a)pants.nu)
+ *
+ * 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., 51 Franklin Street - Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * $Id: btree.c,v 1.14 2000/10/25 05:43:04 hasi Exp $
+ */
+
+#include "config.h"
+#include "libhfsp.h"
+#include "volume.h"
+#include "btree.h"
+#include "record.h"
+#include "swab.h"
+
+/* Read the node from the given buffer and swap the bytes.
+ *
+ * return pointer after reading the structure
+ */
+static void* btree_readnode(btree_node_desc* node, void *p)
+{
+ node->next = bswabU32_inc(p);
+ node->prev = bswabU32_inc(p);
+ node->kind = bswabU8_inc(p);
+ node->height = bswabU8_inc(p);
+ node->num_rec = bswabU16_inc(p);
+ node->reserved = bswabU16_inc(p);
+ return p;
+}
+
+/* read a btree header from the given buffer and swap the bytes.
+ *
+ * return pointer after reading the structure
+ */
+static void* btree_readhead(btree_head* head, void *p)
+{
+ UInt32 *q;
+ head->depth = bswabU16_inc(p);
+ head->root = bswabU32_inc(p);
+ head->leaf_count = bswabU32_inc(p);
+ head->leaf_head = bswabU32_inc(p);
+ head->leaf_tail = bswabU32_inc(p);
+ head->node_size = bswabU16_inc(p);
+ head->max_key_len = bswabU16_inc(p);
+ head->node_count = bswabU32_inc(p);
+ head->free_nodes = bswabU32_inc(p);
+ head->reserved1 = bswabU16_inc(p);
+ head->clump_size = bswabU32_inc(p);
+ head->btree_type = bswabU8_inc(p);
+ head->reserved2 = bswabU8_inc(p);
+ head->attributes = bswabU32_inc(p);
+ // skip reserved bytes
+ q=((UInt32*) p);
+ // ((UInt32*) p) += 16;
+ q+=16;
+ return q;
+}
+
+/* Priority of the depth of the node compared to LRU value.
+ * Should be the average number of keys per node but these vary. */
+#define DEPTH_FACTOR 1000
+
+/* Cache size is height of tree + this value
+ * Really big numbers wont help in case of ls -R
+ */
+#define EXTRA_CACHESIZE 3
+
+/* Not in use by now ... */
+#define CACHE_DIRTY 0x0001
+
+/* Intialize cache with default cache Size,
+ * must call node_cache_close to deallocate memory */
+static int node_cache_init(node_cache* cache, btree* tree, int size)
+{
+ int nodebufsize;
+ char * buf;
+
+ cache->size = size;
+ cache->currindex = 0;
+ nodebufsize = tree->head.node_size + sizeof(node_buf);
+ buf = malloc(size *(sizeof(node_entry) + nodebufsize));
+ if (!buf)
+ return -1;
+ cache -> nodebufsize = nodebufsize;
+ cache -> entries = (node_entry*) buf;
+ cache -> buffers = (char*) &cache->entries[size];
+ bzero(cache->entries, size*sizeof(node_entry));
+ return 0;
+}
+
+/* Like cache->buffers[i], since size of node_buf is variable */
+static inline node_buf* node_buf_get(node_cache* cache, int i)
+{
+ return (node_buf*) (cache->buffers + (i * cache->nodebufsize));
+}
+
+/* flush the node at index */
+static void node_cache_flush_node(node_cache* cache, int index)
+{
+ // NYI
+ cache -> entries[index].index = 0; // invalidate entry
+}
+
+static void node_cache_close(node_cache* cache)
+{
+ if (!cache->entries) // not (fully) intialized ?
+ return;
+ free(cache->entries);
+}
+
+/* Load the cach node indentified by index with
+ * the node identified by node_index */
+
+static node_buf* node_cache_load_buf
+ (btree* bt, node_cache* cache, int index, UInt16 node_index)
+{
+ node_buf *result = node_buf_get(cache ,index);
+ UInt32 blkpernode = bt->blkpernode;
+ UInt32 block = node_index * blkpernode;
+ void* p = volume_readfromfork(bt->vol, result->node, bt->fork,
+ block, blkpernode, HFSP_EXTENT_DATA, bt->cnid);
+ node_entry *e = &cache->entries[index];
+
+ if (!p)
+ return NULL; // evil ...
+
+ result->index = node_index;
+ btree_readnode(&result->desc, p);
+
+ e -> priority = result->desc.height * DEPTH_FACTOR;
+ e -> index = node_index;
+ return result;
+}
+
+/* Read node at given index, using cache.
+ */
+node_buf* btree_node_by_index(btree* bt, UInt16 index)
+{
+ node_cache* cache = &bt->cache;
+ int oldindex, lruindex;
+ int currindex = cache->currindex;
+ UInt32 prio;
+ node_entry *e;
+
+ // Shortcut acces to current node, will not change priorities
+ if (cache->entries[currindex].index == index)
+ return node_buf_get(cache ,currindex);
+ oldindex = currindex;
+ if (currindex == 0)
+ currindex = cache->size;
+ currindex--;
+ lruindex = oldindex; // entry to be flushed when needed
+ prio = 0; // current priority
+ while (currindex != oldindex) // round robin
+ {
+ e = &cache->entries[currindex];
+ if (e->index == index) // got it
+ {
+ if (e->priority != 0) // already top, uuh
+ e->priority--;
+ cache->currindex = currindex;
+ return node_buf_get(cache ,currindex);
+ }
+ else
+ {
+ if (!e->index)
+ {
+ lruindex = currindex;
+ break; // empty entry, load it
+ }
+ if (e->priority != UINT_MAX) // already least, uuh
+ e->priority++;
+ }
+ if (prio < e->priority)
+ {
+ lruindex = currindex;
+ prio = e->priority;
+ }
+ if (currindex == 0)
+ currindex = cache->size;
+ currindex--;
+ }
+ e = &cache->entries[lruindex];
+ cache->currindex = lruindex;
+ if (e->flags & CACHE_DIRTY)
+ node_cache_flush_node( cache, lruindex);
+ return node_cache_load_buf (bt, cache, lruindex, index);
+}
+
+/** intialize the btree with the first entry in the fork */
+static int btree_init(btree* bt, volume* vol, hfsp_fork_raw* fork)
+{
+ void *p;
+ char buf[vol->blksize];
+ UInt16 node_size;
+ btree_node_desc node;
+
+ bt->vol = vol;
+ bt->fork = fork;
+ p = volume_readfromfork(vol, buf, fork, 0, 1,
+ HFSP_EXTENT_DATA, bt->cnid);
+ if (!p)
+ return -1;
+ p = btree_readnode(&node, p);
+ if (node.kind != HFSP_NODE_HEAD)
+ return -1; // should not happen ?
+ btree_readhead(&bt->head, p);
+
+ node_size = bt->head.node_size;
+ bt->blkpernode = node_size / vol->blksize;
+
+ if (bt->blkpernode == 0 || vol->blksize *
+ bt->blkpernode != node_size)
+ return -1; // should never happen ...
+
+ node_cache_init(&bt->cache, bt, bt->head.depth + EXTRA_CACHESIZE);
+
+ // Allocate buffer
+ // bt->buf = malloc(node_size);
+ // if (!bt->buf)
+ // return ENOMEM;
+
+ return 0;
+}
+
+/** Intialize catalog btree, so that btree_close can safely be called. */
+void btree_reset(btree* bt)
+{
+ bt->cache.entries = NULL;
+}
+
+/** Intialize catalog btree */
+int btree_init_cat(btree* bt, volume* vol, hfsp_fork_raw* fork)
+{
+ int result = btree_init(bt,vol,fork); // super (...)
+ bt->cnid = HFSP_CAT_CNID;
+ bt->kcomp = record_key_compare;
+ bt->kread = record_readkey;
+ return result;
+}
+
+/** Intialize catalog btree */
+int btree_init_extent(btree* bt, volume* vol, hfsp_fork_raw* fork)
+{
+ int result = btree_init(bt,vol,fork); // super (...)
+ bt->cnid = HFSP_EXT_CNID;
+ bt->kcomp = record_extent_key_compare;
+ bt->kread = record_extent_readkey;
+ return result;
+}
+
+/** close the btree and free any resources */
+void btree_close(btree* bt)
+{
+ node_cache_close(&bt->cache);
+ // free(bt->buf);
+}
+
+/* returns pointer to key given by index in current node.
+ *
+ * Assumes that current node is not NODE_HEAD ...
+ */
+void* btree_key_by_index(btree* bt, node_buf* buf, UInt16 index)
+{
+ UInt16 node_size = bt->head.node_size;
+ // The offsets are found at the end of the node ...
+ UInt16 off_pos = node_size - (index +1) * sizeof(btree_record_offset);
+ // position of offset at end of node
+ btree_record_offset* offset =
+ (btree_record_offset*) (buf->node + off_pos);
+
+ // now we have the offset and can read the key ...
+#ifdef CONFIG_LITTLE_ENDIAN
+ return buf->node + bswabU16(*offset);
+#else
+ return buf->node + *offset;
+#endif
+}
+
+
+#ifdef DEBUG
+
+/* print btree header node information */
+void btree_printhead(btree_head* head)
+{
+ UInt32 attr;
+ printf(" depth : %#X\n", head->depth);
+ printf(" root : %#lX\n", head->root);
+ printf(" leaf_count : %#lX\n", head->leaf_count);
+ printf(" leaf_head : %#lX\n", head->leaf_head);
+ printf(" leaf_tail : %#lX\n", head->leaf_tail);
+ printf(" node_size : %#X\n", head->node_size);
+ printf(" max_key_len : %#X\n", head->max_key_len);
+ printf(" node_count : %#lX\n", head->node_count);
+ printf(" free_nodes : %#lX\n", head->free_nodes);
+ printf(" reserved1 : %#X\n", head->reserved1);
+ printf(" clump_size : %#lX\n", head->clump_size);
+ printf(" btree_type : %#X\n", head->btree_type);
+ attr = head->attributes;
+ printf(" reserved2 : %#X\n", head->reserved2);
+ if (attr & HFSPLUS_BAD_CLOSE)
+ printf(" HFSPLUS_BAD_CLOSE *** ");
+ else
+ printf(" !HFSPLUS_BAD_CLOSE");
+ if (attr & HFSPLUS_TREE_BIGKEYS)
+ printf(" HFSPLUS_TREE_BIGKEYS ");
+ else
+ printf(" !HFSPLUS_TREE_BIGKEYS");
+ if (attr & HFSPLUS_TREE_VAR_NDXKEY_SIZE)
+ printf(" HFSPLUS_TREE_VAR_NDXKEY_SIZE");
+ else
+ printf(" !HFSPLUS_TREE_VAR_NDXKEY_SIZE");
+ if (attr & HFSPLUS_TREE_UNUSED)
+ printf(" HFSPLUS_TREE_UNUSED ***\n");
+ printf("\n");
+}
+
+/* Dump all the node information to stdout */
+void btree_print(btree* bt)
+{
+ btree_node_desc* node;
+
+ btree_printhead(&bt->head);
+
+ node = &bt->node;
+ printf("next : %#lX\n", node->next);
+ printf("prev : %#lX\n", node->prev);
+ printf("height : %#X\n", node->height);
+ printf("num_rec : %#X\n", node->num_rec);
+ printf("reserved : %#X\n", node->reserved);
+ printf("height : %#X\n", node->height);
switch(node->kind)
+ {
+ case HFSP_NODE_NDX :
+ printf("HFSP_NODE_NDX\n");
+ break;
+ case HFSP_NODE_HEAD :
+ printf("HFSP_NODE_HEAD\n");
+ break;
+ case HFSP_NODE_MAP :
+ printf("HFSP_NODE_MAP\n");
+ break;
+ case HFSP_NODE_LEAF :
+ printf("HFSP_NODE_LEAF\n");
+ break;
+ default:
+ printf("*** Unknown Node type ***\n");
+ }
+}
+
+#endif
diff --git a/fs/hfsplus/hfsp_record.c b/fs/hfsplus/hfsp_record.c
new file mode 100644
index 0000000..d4e7af1
--- /dev/null
+++ b/fs/hfsplus/hfsp_record.c
@@ -0,0 +1,759 @@
+/*
+ * libhfsp - library for reading and writing Macintosh HFS+ volumes.
+ *
+ * a record contains a key and a folder or file and is part
+ * of a btree.
+ *
+ * Copyright (C) 2000 Klaus Halfmann <khalfmann(a)libra.de>
+ * Original 1996-1998 Robert Leslie <rob(a)mars.org>
+ * Additional work by Brad Boyer (flar(a)pants.nu)
+ *
+ * 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., 51 Franklin Street - Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * $Id: record.c,v 1.24 2000/10/17 05:58:46 hasi Exp $
+ */
+
+#include "config.h"
+#include "libhfsp.h"
+#include "hfstime.h"
+#include "record.h"
+#include "volume.h"
+#include "btree.h"
+#include "unicode.h"
+#include "swab.h"
+
+/* read a hfsp_cat_key from memory */
+void* record_readkey(void* p, void* buf)
+{
+ hfsp_cat_key* key = (hfsp_cat_key*) buf;
+ const void* check;
+ UInt16 key_length, len,i;
+ UInt16* cp;
+
+ key->key_length = key_length = bswabU16_inc(p);
+ check = p;
+ key->parent_cnid = bswabU32_inc(p);
+ key->name.strlen = len = bswabU16_inc(p);
+ cp = key->name.name;
+ for (i=0; i < len; i++, cp++)
+ *cp = bswabU16_inc(p);
+ /* check if keylenght was correct */
+ if (key_length != ((char*) p) - ((char*) check))
+ HFSP_ERROR(EINVAL, "Invalid key length in record_readkey");
+ return p;
+ fail:
+ return NULL;
+}
+
+/* read a hfsp_extent_key from memory */
+void* record_extent_readkey(void* p, void* buf)
+{
+ hfsp_extent_key* key = (hfsp_extent_key*) buf;
+ UInt16 key_length;
+
+ key->key_length = key_length = bswabU16_inc(p);
+ key->fork_type = bswabU8_inc(p);
+ key->filler = bswabU8_inc(p);
+ if (key_length != 10)
+ HFSP_ERROR(-1, "Invalid key length in record_extent_readkey");
+ key->file_id = bswabU32_inc(p);
+ key->start_block = bswabU32_inc(p);
+ return p;
+ fail:
+ return NULL;
+}
+
+
+/* read posix permission from memory */
+static inline void* record_readperm(void *p, hfsp_perm* perm)
+{
+ perm->owner= bswabU32_inc(p);
+ perm->group= bswabU32_inc(p);
+ perm->mode = bswabU32_inc(p);
+ perm->dev = bswabU32_inc(p);
+ return p;
+}
+
+/* read directory info */
+static inline void* record_readDInfo(void *p, DInfo* info)
+{
+ info->frRect.top = bswabU16_inc(p);
+ info->frRect.left = bswabU16_inc(p);
+ info->frRect.bottom = bswabU16_inc(p);
+ info->frRect.right = bswabU16_inc(p);
+ info->frFlags = bswabU16_inc(p);
+ info->frLocation.v = bswabU16_inc(p);
+ info->frLocation.h = bswabU16_inc(p);
+ info->frView = bswabU16_inc(p);
+ return p;
+}
+
+/* read extra Directory info */
+static inline void* record_readDXInfo(void *p, DXInfo* xinfo)
+{
+ xinfo->frScroll.v = bswabU16_inc(p);
+ xinfo->frScroll.h = bswabU16_inc(p);
+ xinfo->frOpenChain = bswabU32_inc(p);
+ xinfo->frUnused = bswabU16_inc(p);
+ xinfo->frComment = bswabU16_inc(p);
+ xinfo->frPutAway = bswabU32_inc(p);
+ return p;
+}
+
+/* read a hfsp_cat_folder from memory */
+static void* record_readfolder(void *p, hfsp_cat_folder* folder)
+{
+ folder->flags = bswabU16_inc(p);
+ folder->valence = bswabU32_inc(p);
+ folder->id = bswabU32_inc(p);
+ folder->create_date = bswabU32_inc(p);
+ folder->content_mod_date = bswabU32_inc(p);
+ folder->attribute_mod_date = bswabU32_inc(p);
+ folder->access_date = bswabU32_inc(p);
+ folder->backup_date = bswabU32_inc(p);
+ p = record_readperm (p, &folder->permissions);
+ p = record_readDInfo (p, &folder->user_info);
+ p = record_readDXInfo (p, &folder->finder_info);
+ folder->text_encoding = bswabU32_inc(p);
+ folder->reserved = bswabU32_inc(p);
+ return p;
+}
+
+/* read file info */
+static inline void* record_readFInfo(void *p, FInfo* info)
+{
+ info->fdType = bswabU32_inc(p);
+ info->fdCreator = bswabU32_inc(p);
+ info->fdFlags = bswabU16_inc(p);
+ info->fdLocation.v = bswabU16_inc(p);
+ info->fdLocation.h = bswabU16_inc(p);
+ info->fdFldr = bswabU16_inc(p);
+ return p;
+}
+
+/* read extra File info */
+static inline void* record_readFXInfo(void *p, FXInfo* xinfo)
+{
+ SInt16 *q;
+ xinfo->fdIconID = bswabU16_inc(p);
+ q=(SInt16*) p;
+ q+=4; // skip unused
+ p=(void *)q;
+ xinfo->fdComment = bswabU16_inc(p);
+ xinfo->fdPutAway = bswabU32_inc(p);
+ return p;
+}
+
+/* read a hfsp_cat_file from memory */
+static void* record_readfile(void *p, hfsp_cat_file* file)
+{
+ file->flags = bswabU16_inc(p);
+ file->reserved1 = bswabU32_inc(p);
+ file->id = bswabU32_inc(p);
+ file->create_date = bswabU32_inc(p);
+ file->content_mod_date = bswabU32_inc(p);
+ file->attribute_mod_date = bswabU32_inc(p);
+ file->access_date = bswabU32_inc(p);
+ file->backup_date = bswabU32_inc(p);
+ p = record_readperm (p, &file->permissions);
+ p = record_readFInfo (p, &file->user_info);
+ p = record_readFXInfo (p, &file->finder_info);
+ file->text_encoding = bswabU32_inc(p);
+ file->reserved2 = bswabU32_inc(p);
+ p = volume_readfork (p, &file->data_fork);
+ return volume_readfork (p, &file->res_fork);
+}
+
+/* read a hfsp_cat_thread from memory */
+static void* record_readthread(void *p, hfsp_cat_thread* entry)
+{
+ int i;
+ UInt16 len;
+ UInt16* cp;
+
+ entry-> reserved = bswabU16_inc(p);
+ entry-> parentID = bswabU32_inc(p);
+ entry->nodeName.strlen = len= bswabU16_inc(p);
+ cp = entry->nodeName.name;
+ if (len > 255)
+ HFSP_ERROR(-1, "Invalid key length in record thread");
+ for (i=0; i < len; i++, cp++)
+ *cp = bswabU16_inc(p);
+ return p;
+ fail:
+ return NULL;
+}
+
+/* read a hfsp_cat_entry from memory */
+static void* record_readentry(void *p, hfsp_cat_entry* entry)
+{
+ UInt16 type = bswabU16_inc(p);
+ entry->type = type;
+ switch (type)
+ {
+ case HFSP_FOLDER:
+ return record_readfolder(p, &entry->u.folder);
+ case HFSP_FILE:
+ return record_readfile (p, &entry->u.file);
+ case HFSP_FOLDER_THREAD:
+ case HFSP_FILE_THREAD:
+ return record_readthread(p, &entry->u.thread);
+ default:
+ HFSP_ERROR(-1, "Unexpected record type in record_readentry");
+ } ;
+ fail:
+ return NULL;
+}
+
+
+/* Most of the functions here will not change the node in the btree,
+ But this must be changed in the future ... */
+
+
+/* intialize the record with the given index entry in the btree. */
+static int record_init(record* r, btree* bt, node_buf* buf, UInt16 index)
+{
+ void *p;
+ r-> tree = bt;
+ p = btree_key_by_index(bt,buf,index);
+ if (!p)
+ return -1;
+ p = record_readkey (p, &r->key);
+ if (!p)
+ return -1;
+ p = record_readentry(p, &r->record);
+ if (!p)
+ return -1;
+ r->node_index = buf->index;
+ r-> keyind = index;
+
+ return 0;
+}
+
+/* intialize the record with the given index entry in the btree. */
+static int record_init_extent(extent_record* r, btree* bt, node_buf*
buf, UInt16 index)
+{
+ void *p;
+ r-> tree = bt;
+ p = btree_key_by_index(bt, buf,index);
+ if (!p)
+ return -1;
+ p = record_extent_readkey(p, &r->key);
+ if (!p)
+ return -1;
+ p = volume_readextent(p, r->extent);
+ if (!p)
+ return -1;
+ r->node_index = buf->index;
+ r-> keyind = index;
+
+ return 0;
+}
+
+/* intialize the record to the first record of the tree
+ * which is (per design) the root node.
+ */
+int record_init_root(record* r, btree* tree)
+{
+ // Position to first leaf node ...
+ UInt32 leaf_head = tree->head.leaf_head;
+ node_buf* buf = btree_node_by_index(tree, leaf_head);
+ if (!buf)
+ return -1;
+ return record_init(r, tree, buf, 0);
+}
+
+/* Compare two cat_keys ... */
+int record_key_compare(void* k1, void* k2)
+{
+ hfsp_cat_key* key1 = (hfsp_cat_key*) k1;
+ hfsp_cat_key* key2 = (hfsp_cat_key*) k2;
+ int diff = key2->parent_cnid - key1->parent_cnid;
+ if (!diff) // same parent
+ diff = fast_unicode_compare(&key1->name, &key2->name);
+ return diff;
+}
+
+/* Compare two extent_keys ... */
+int record_extent_key_compare(void* k1, void* k2)
+{
+ hfsp_extent_key* key1 = (hfsp_extent_key*) k1;
+ hfsp_extent_key* key2 = (hfsp_extent_key*) k2;
+ int diff = key2->fork_type - key1->fork_type;
+ if (!diff) // same type
+ {
+ diff = key2->file_id - key1->file_id;
+ if (!diff) // same file
+ diff = key2->start_block - key1->start_block;
+ }
+ return diff;
+}
+
+/* Position node in btree so that key might be inside */
+static node_buf* record_find_node(btree* tree, void *key)
+{
+ int start, end, mid, comp; // components of a binary search
+ void *p = NULL;
+ char curr_key[tree->head.max_key_len];
+ // The current key under examination
+ hfsp_key_read readkey = tree->kread;
+ hfsp_key_compare key_compare = tree->kcomp;
+ UInt32 index;
+ node_buf* node = btree_node_by_index(tree, tree->head.root);
+ if (!node)
+ HFSP_ERROR(-1, "record_find_node: Cant position to root node");
+ while (node->desc.kind == HFSP_NODE_NDX)
+ {
+ mid = start = 0;
+ end = node->desc.num_rec;
+ comp = -1;
+ while (start < end)
+ {
+ mid = (start + end) >> 1;
+ p = btree_key_by_index(tree, node, mid);
+ if (!p)
+ HFSP_ERROR(-1, "record_find_node: unexpected error");
+ p = readkey (p, curr_key);
+ if (!p)
+ HFSP_ERROR(-1, "record_find_node: unexpected error");
+ comp = key_compare(curr_key, key);
+ if (comp > 0)
+ start = mid + 1;
+ else if (comp < 0)
+ end = mid;
+ else
+ break;
+ }
+ if (!p) // Empty tree, fascinating ...
+ HFSP_ERROR(-1, "record_find_node: unexpected empty node");
+ if (comp < 0) // mmh interesting key is before this key ...
+ {
+ if (mid == 0)
+ return NULL; // nothing before this key ..
+ p = btree_key_by_index(tree, node, mid-1);
+ if (!p)
+ HFSP_ERROR(-1, "record_find_node: unexpected error");
+ p = readkey (p, curr_key);
+ if (!p)
+ HFSP_ERROR(-1, "record_find_node: unexpected error");
+ }
+
+ index = bswabU32_inc(p);
+ node = btree_node_by_index(tree, index);
+ }
+ return node; // go on and use the found node
+ fail:
+ return NULL;
+}
+
+/* search for the given key in the btree.
+ *
+ * returns pointer to memory just after key or NULL
+ * In any case *keyind recives the index where the
+ * key was found (or could be inserted.)
+ */
+static void *
+record_find_key(btree* tree, void* key, int* keyind, UInt16* node_index)
+{
+ node_buf* buf = record_find_node(tree, key);
+ if (buf)
+ {
+ int comp = -1;
+ int start = 0; // components of a binary search
+ int end = buf->desc.num_rec;
+ int mid = -1;
+ void *p = NULL;
+ char curr_key[tree->head.max_key_len];
+ hfsp_key_read readkey = tree->kread;
+ hfsp_key_compare key_compare = tree->kcomp;
+ while (start < end)
+ {
+ mid = (start + end) >> 1;
+ p = btree_key_by_index(tree, buf, mid);
+ if (!p)
+ HFSP_ERROR(-1, "record_init_key: unexpected error");
+ p = readkey (p, curr_key);
+ if (!p)
+ HFSP_ERROR(-1, "record_init_cat_key: unexpected error");
+ comp = key_compare(curr_key, key);
+ if (comp > 0)
+ start = mid + 1;
+ else if (comp < 0)
+ end = mid;
+ else
+ break;
+ }
+ if (!p) // Empty tree, fascinating ...
+ HFSP_ERROR(ENOENT, "record_init_key: unexpected empty node");
+ *keyind = mid;
+ *node_index = buf->index;
+ if (!comp) // found something ...
+ return p;
+ }
+ HFSP_ERROR(ENOENT, NULL);
+ fail:
+ return NULL;
+}
+
+/* intialize the record by searching for the given key in the btree.
+ *
+ * r is umodified on error.
+ */
+static int
+record_init_key(record* r, btree* tree, hfsp_cat_key* key)
+{
+ int keyind;
+ UInt16 node_index;
+ void *p = record_find_key(tree, key, &keyind, &node_index);
+
+ if (p)
+ {
+ r -> tree = tree;
+ r -> node_index= node_index;
+ r -> keyind = keyind;
+ r -> key = *key; // Better use a record_key_copy ...
+ p = record_readentry(p, &r->record);
+ if (!p)
+ HFSP_ERROR(-1, "record_init_key: unexpected error");
+ return 0;
+ }
+ fail:
+ return -1;
+}
+
+/* intialize the extent_record to the extent identified by the
+ * (first) blockindex.
+ *
+ * forktype: either HFSP_EXTEND_DATA or HFSP_EXTEND_RSRC
+ */
+int record_init_file(extent_record* r, btree* tree,
+ UInt8 forktype, UInt32 fileId, UInt32 blockindex)
+{
+ int keyind;
+ UInt16 node_index;
+ hfsp_extent_key key = { 10, forktype, 0, fileId, blockindex };
+ void *p = record_find_key(tree, &key, &keyind, &node_index);
+
+ if (p)
+ {
+ r -> tree = tree;
+ r -> node_index= node_index;
+ r -> keyind = keyind;
+ r -> key = key; // Better use a record_key_copy ...
+ p = volume_readextent(p, r->extent);
+ if (!p)
+ HFSP_ERROR(-1, "record_init_file: unexpected error");
+ return 0;
+ }
+ fail:
+ return -1;
+}
+
+/* intialize the record to the folder identified by cnid
+ */
+int record_init_cnid(record* r, btree* tree, UInt32 cnid)
+{
+ hfsp_cat_key thread_key; // the thread is the first record
+
+ thread_key.key_length = 6; // null name (like '.' in unix )
+ thread_key.parent_cnid = cnid;
+ thread_key.name.strlen = 0;
+
+ return record_init_key(r, tree, &thread_key);
+}
+
+/* intialize the record to the first record of the parent.
+ */
+int record_init_parent(record* r, record* parent)
+{
+ if (parent->record.type == HFSP_FOLDER)
+ return record_init_cnid(r, parent->tree, parent->record.u.folder.id);
+ else if(parent->record.type == HFSP_FOLDER_THREAD)
+ {
+ if (r != parent)
+ *r = *parent; // The folder thread is in fact the first entry, like '.'
+ return 0;
+ }
+ HFSP_ERROR(EINVAL,
+ "record_init_parent: parent is neither folder nor folder thread.");
+
+ fail:
+ return EINVAL;
+}
+
+
+/* find correct node record for given node and *pindex.
+ *
+ * index of record in this (or next) node
+ * */
+static node_buf* prepare_next(btree* tree, UInt16 node_index, UInt16* pindex)
+{
+ node_buf* buf = btree_node_by_index(tree, node_index);
+ btree_node_desc* desc = &buf->desc;
+ UInt32 numrec = desc->num_rec;
+ if (*pindex >= numrec) // move on to next node
+ {
+ UInt16 next = desc->next;
+ *pindex = 0;
+ if (!next /* is there a next node ? */
+ || !( buf = btree_node_by_index(tree, next)))
+ return NULL;
+ }
+ return buf;
+}
+/* move record foreward to next entry.
+ *
+ * In case of an error the value of *r is undefined !
+ */
+int record_next(record* r)
+{
+ btree* tree = r->tree;
+ UInt16 index = r->keyind +1;
+ UInt32 parent;
+ node_buf* buf = prepare_next(tree, r->node_index, &index);
+
+ if (!buf)
+ return ENOENT; // No (more) such file or directory
+
+ parent = r->key.parent_cnid;
+
+ if (record_init(r, tree, buf, index))
+ return -1;
+
+ if (r->key.parent_cnid != parent || // end of current directory
+ index != r->keyind) // internal error ?
+ return ENOENT; // No (more) such file or directory
+
+ return 0;
+}
+
+/* move record foreward to next extent record.
+ *
+ * In case of an error the value of *r is undefined !
+ */
+int record_next_extent(extent_record* r)
+{
+ btree* tree = r->tree;
+ UInt16 index = r->keyind +1;
+ UInt32 file_id;
+ UInt8 fork_type;
+ node_buf* buf = prepare_next(tree, r->node_index, &index);
+
+ if (!buf)
+ return ENOENT; // No (more) such file or directory
+
+ file_id = r->key.file_id;
+ fork_type = r->key.fork_type;
+
+ if (record_init_extent(r, tree, buf, index))
+ return -1;
+
+ if (r->key.file_id != file_id || // end of current file
+ r->key.fork_type != fork_type || // end of current fork
+ index != r->keyind) // internal error ?
+ return ENOENT; // No (more) such file or directory
+
+ return 0;
+}
+
+/* intialize the record by searching for the given string in the given folder.
+ *
+ * parent and r may be the same.
+ */
+int record_init_string_parent(record* r, record* parent, char* name)
+{
+ hfsp_cat_key key;
+
+ if (parent->record.type == HFSP_FOLDER)
+ key.parent_cnid = parent->record.u.folder.id;
+ else if(parent->record.type == HFSP_FOLDER_THREAD)
+ key.parent_cnid = parent->key.parent_cnid;
+ else
+ HFSP_ERROR(-1, "record_init_string_parent: parent is not a folder.");
+
+ key.key_length = 6 + unicode_asc2uni(&key.name,name); // 6 for minumum size
+ return record_init_key(r, parent->tree, &key);
+
+ fail:
+ return -1;
+}
+
+/* move record up in folder hierarchy (if possible) */
+int record_up(record* r)
+{
+ if (r->record.type == HFSP_FOLDER)
+ {
+ // locate folder thread
+ if (record_init_cnid(r, r->tree, r->record.u.folder.id))
+ return -1;
+ }
+ else if(r->record.type == HFSP_FOLDER_THREAD)
+ {
+ // do nothing were are already where we want to be
+ }
+ else
+ HFSP_ERROR(-1, "record_up: record is neither folder nor folder thread.");
+
+ if(r->record.type != HFSP_FOLDER_THREAD)
+ HFSP_ERROR(-1, "record_up: unable to locate parent");
+ return record_init_cnid(r, r->tree, r->record.u.thread.parentID);
+
+ fail:
+ return -1;
+}
+
+#ifdef DEBUG
+
+/* print Quickdraw Point */
+static void record_print_Point(Point* p)
+{
+ printf("[ v=%d, h=%d ]", p->v, p->h);
+}
+
+/* print Quickdraw Rect */
+static void record_print_Rect(Rect* r)
+{
+ printf("[ top=%d, left=%d, bottom=%d, right=%d ]",
+ r->top, r->left, r->bottom, r->right);
+}
+
+/* print the key of a record */
+static void record_print_key(hfsp_cat_key* key)
+{
+ char buf[255]; // mh this _might_ overflow
+ unicode_uni2asc(buf, &key->name, 255);
+ printf("parent cnid : %ld\n", key->parent_cnid);
+ printf("name : %s\n", buf);
+}
+
+/* print permissions */
+static void record_print_perm(hfsp_perm* perm)
+{
+ printf("owner :\t%ld\n", perm->owner);
+ printf("group :\t%ld\n", perm->group);
+ printf("perm :\t0x%lX\n",perm->mode);
+ printf("dev :\t%ld\n", perm->dev);
+}
+
+/* print Directory info */
+static void record_print_DInfo(DInfo* dinfo)
+{
+ printf( "frRect :\t"); record_print_Rect(&dinfo->frRect);
+ printf("\nfrFlags :\t0X%X\n", dinfo->frFlags);
+ printf( "frLocation :\t");
record_print_Point(&dinfo->frLocation);
+ printf("\nfrView :\t0X%X\n", dinfo->frView);
+}
+
+/* print extended Directory info */
+static void record_print_DXInfo(DXInfo* xinfo)
+{
+ printf( "frScroll :\t");
record_print_Point(&xinfo->frScroll);
+ printf("\nfrOpenChain :\t%ld\n", xinfo->frOpenChain);
+ printf( "frUnused :\t%d\n", xinfo->frUnused);
+ printf( "frComment :\t%d\n", xinfo->frComment);
+ printf( "frPutAway :\t%ld\n", xinfo->frPutAway);
+}
+
+static void record_print_folder(hfsp_cat_folder* folder)
+{
+ printf("flags :\t0x%X\n", folder->flags);
+ printf("valence :\t0x%lX\n", folder->valence);
+ printf("id :\t%ld\n", folder->id);
+ record_print_perm (&folder->permissions);
+ record_print_DInfo (&folder->user_info);
+ record_print_DXInfo (&folder->finder_info);
+ printf("text_encoding :\t0x%lX\n", folder->text_encoding);
+ printf("reserved :\t0x%lX\n", folder->reserved);
+}
+
+/* print File info */
+static void record_print_FInfo(FInfo* finfo)
+{
+ printf( "fdType :\t%4.4s\n", (char*) &finfo->fdType);
+ printf( "fdCreator :\t%4.4s\n", (char*) &finfo->fdCreator);
+ printf( "fdFlags :\t0X%X\n", finfo->fdFlags);
+ printf( "fdLocation :\t");
record_print_Point(&finfo->fdLocation);
+ printf("\nfdFldr :\t%d\n", finfo->fdFldr);
+}
+
+/* print extended File info */
+static void record_print_FXInfo(FXInfo* xinfo)
+{
+ printf( "fdIconID :\t%d\n", xinfo->fdIconID);
+ // xinfo -> fdUnused;
+ printf( "fdComment :\t%d\n", xinfo->fdComment);
+ printf( "fdPutAway :\t%ld\n", xinfo->fdPutAway);
+}
+
+/* print folder entry */
+
+/* print file entry */
+static void record_print_file(hfsp_cat_file* file)
+{
+ printf("flags :\t0x%X\n", file->flags);
+ printf("reserved1 :\t0x%lX\n", file->reserved1);
+ printf("id :\t%ld\n", file->id);
+ record_print_perm (&file->permissions);
+ record_print_FInfo (&file->user_info);
+ record_print_FXInfo (&file->finder_info);
+ printf("text_encoding :\t0x%lX\n", file->text_encoding);
+ printf("reserved :\t0x%lX\n", file->reserved2);
+ printf("Datafork:\n");
+ volume_print_fork (&file->data_fork);
+ printf("Rsrcfork:\n");
+ volume_print_fork (&file->res_fork);
+}
+
+/* print info for a file or folder thread */
+static void record_print_thread(hfsp_cat_thread* entry)
+{
+ char buf[255]; // mh this _might_ overflow
+ unicode_uni2asc(buf, &entry->nodeName, 255);
+ printf("parent cnid :\t%ld\n", entry->parentID);
+ printf("name :\t%s\n" , buf);
+}
+
+/* print the information for a record */
+static void record_print_entry(hfsp_cat_entry* entry)
+{
+ switch (entry->type)
+ {
+ case HFSP_FOLDER:
+ printf("=== Folder ===\n");
+ return record_print_folder(&entry->u.folder);
+ case HFSP_FILE:
+ printf("=== File ===\n");
+ return record_print_file (&entry->u.file);
+ case HFSP_FOLDER_THREAD:
+ printf("=== Folder Thread ===\n");
+ return record_print_thread(&entry->u.thread);
+ case HFSP_FILE_THREAD:
+ printf("=== File Thread ==\n");
+ return record_print_thread(&entry->u.thread);
+ default:
+ printf("=== Unknown Record Type ===\n");
+ } ;
+}
+
+ /* Dump all the record information to stdout */
+void record_print(record* r)
+{
+ printf ("keyind : %u\n", r->keyind);
+ record_print_key (&r->key);
+ record_print_entry(&r->record);
+}
+
+#endif
diff --git a/fs/hfsplus/hfsp_volume.c b/fs/hfsplus/hfsp_volume.c
new file mode 100644
index 0000000..802d700
--- /dev/null
+++ b/fs/hfsplus/hfsp_volume.c
@@ -0,0 +1,314 @@
+/*
+ * libhfs - library for reading and writing Macintosh HFS volumes
+ *
+ * Code to acces the basic volume information of a HFS+ volume.
+ *
+ * Copyright (C) 2000 Klaus Halfmann <khalfmann(a)libra.de>
+ * Original work by 1996-1998 Robert Leslie <rob(a)mars.org>
+ * other work 2000 from Brad Boyer (flar(a)pants.nu)
+ *
+ * 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., 51 Franklin Street - Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * $Id: volume.c,v 1.21 2000/10/25 05:43:04 hasi Exp $
+ */
+
+#include "config.h"
+#include "libhfsp.h"
+#include "volume.h"
+#include "record.h"
+#include "btree.h"
+#include "blockiter.h"
+#include "os.h"
+#include "swab.h"
+#include "hfstime.h"
+
+
+/* Fill a given buffer with the given block in volume.
+ */
+int
+volume_readinbuf(volume * vol,void* buf, long block)
+{
+ UInt16 blksize_bits;
+ ASSERT( block < vol->maxblocks);
+
+ blksize_bits = vol->blksize_bits;
+ block += vol->startblock;
+ if( os_seek(vol->os_fd, block, blksize_bits) == block)
+ if( 1 == os_read(vol->os_fd, buf, 1, blksize_bits))
+ return 0;
+ return -1;
+}
+
+/* read multiple blocks into given memory.
+ *
+ * returns given pinter or NULL on failure.
+ */
+void*
+volume_readfromfork(volume* vol, void* buf,
+ hfsp_fork_raw* f, UInt32 block,
+ UInt32 count, UInt8 forktype, UInt32 fileId)
+{
+ blockiter iter;
+ char *cbuf = buf;
+
+ blockiter_init(&iter, vol, f, forktype, fileId);
+ if( blockiter_skip(&iter, block))
+ return NULL;
+
+ while( count > 0) {
+ --count;
+ if( volume_readinbuf(vol, cbuf, blockiter_curr(&iter)))
+ return NULL;
+ cbuf += vol->blksize;
+ if( count > 0 && blockiter_next(&iter))
+ return NULL;
+ }
+ return buf;
+}
+
+
+/* Read a raw hfsp_extent_rec from memory.
+ *
+ * return pointer right after the structure.
+ */
+void*
+volume_readextent(void *p, hfsp_extent_rec er)
+{
+ int i;
+ hfsp_extent *e;
+
+ for( i=0; i < 8; i++) {
+ e = &er[i];
+ e->start_block = bswabU32_inc(p);
+ e->block_count = bswabU32_inc(p);
+ }
+ return p;
+}
+
+/* Read a raw hfsp_fork from memory.
+ *
+ * return pointer right after the structure.
+ */
+void*
+volume_readfork(void *p, hfsp_fork_raw* f)
+{
+ f->total_size = bswabU64_inc(p);
+ f->clump_size = bswabU32_inc(p);
+ f->total_blocks = bswabU32_inc(p);
+
+ return volume_readextent(p, f->extents);
+}
+
+/* Read the volume from the given buffer and swap the bytes.
+ *
+ * ToDo: add more consitency checks.
+ */
+static int
+volume_readbuf(hfsp_vh* vh, char * p)
+{
+ if( (vh->signature = bswabU16_inc(p)) != HFSP_VOLHEAD_SIG)
+ HFSP_ERROR(-1, "This is not a HFS+ volume");
+
+ vh->version = bswabU16_inc(p);
+ vh->attributes = bswabU32_inc(p);
+ vh->last_mount_vers = bswabU32_inc(p);
+ vh->reserved = bswabU32_inc(p);
+ vh->create_date = bswabU32_inc(p);
+ vh->modify_date = bswabU32_inc(p);
+ vh->backup_date = bswabU32_inc(p);
+ vh->checked_date = bswabU32_inc(p);
+ vh->file_count = bswabU32_inc(p);
+ vh->folder_count = bswabU32_inc(p);
+ vh->blocksize = bswabU32_inc(p);
+ vh->total_blocks = bswabU32_inc(p);
+ vh->free_blocks = bswabU32_inc(p);
+ vh->next_alloc = bswabU32_inc(p);
+ vh->rsrc_clump_sz = bswabU32_inc(p);
+ vh->data_clump_sz = bswabU32_inc(p);
+ vh->next_cnid = bswabU32_inc(p);
+ vh->write_count = bswabU32_inc(p);
+ vh->encodings_bmp = bswabU64_inc(p);
+ memcpy(vh->finder_info, p, 32);
+ p += 32; // So finderinfo must be swapped later, ***
+ p = volume_readfork(p, &vh->alloc_file );
+ p = volume_readfork(p, &vh->ext_file );
+ p = volume_readfork(p, &vh->cat_file );
+ p = volume_readfork(p, &vh->attr_file );
+ volume_readfork(p, &vh->start_file );
+ return 0;
+ fail:
+ return -1;
+}
+
+/* Read the volume from the given block */
+static int
+volume_read(volume * vol, hfsp_vh* vh, UInt32 block)
+{
+ char buf[vol->blksize];
+
+ if( volume_readinbuf(vol, buf, block))
+ return -1;
+ return volume_readbuf(vh, buf);
+}
+
+/* Find out wether the volume is wrapped and unwrap it eventually */
+static int
+volume_read_wrapper(volume * vol, hfsp_vh* vh)
+{
+ UInt16 signature;
+ char buf[vol->blksize];
+ char *p = buf;
+
+ if( volume_readinbuf(vol, buf, 2) ) // Wrapper or volume header starts here
+ return -1;
+
+ signature = bswabU16_inc(p);
+ if( signature == HFS_VOLHEAD_SIG) { /* Wrapper */
+ UInt32 drAlBlkSiz; /* size (in bytes) of allocation blocks */
+ UInt32 sect_per_block; /* how may block build an hfs sector */
+ UInt16 drAlBlSt; /* first allocation block in volume */
+ UInt16 embeds, embedl; /* Start/lenght of embedded area in blocks */
+
+ p += 0x12; /* skip unneded HFS vol fields */
+ drAlBlkSiz = bswabU32_inc(p); /* offset 0x14 */
+ p += 0x4; /* skip unneded HFS vol fields */
+ drAlBlSt = bswabU16_inc(p); /* offset 0x1C */
+
+ p += 0x5E; /* skip unneded HFS vol fields */
+ signature = bswabU16_inc(p); /* offset 0x7C, drEmbedSigWord */
+ if( signature != HFSP_VOLHEAD_SIG)
+ HFSP_ERROR(-1, "This looks like a normal HFS volume");
+ embeds = bswabU16_inc(p);
+ embedl = bswabU16_inc(p);
+ sect_per_block = (drAlBlkSiz / HFSP_BLOCKSZ);
+ // end is absolute (not relative to HFS+ start)
+ vol->maxblocks = embedl * sect_per_block;
+ vol->startblock = drAlBlSt + embeds * sect_per_block;
+ /* Now we can try to read the embedded HFS+ volume header */
+ return volume_read(vol,vh,2);
+ }
+ else if( signature == HFSP_VOLHEAD_SIG) { /* Native HFS+ volume */
+ p = buf; // Restore to begin of block
+ return volume_readbuf(vh, p);
+ } else
+ HFSP_ERROR(-1, "Neither Wrapper nor native HFS+ volume header found");
+fail:
+ return -1;
+}
+
+
+/* Open the device, read and verify the volume header
+ (and its backup) */
+int
+volume_open( volume* vol, int os_fd )
+{
+ hfsp_vh backup; /* backup volume found at second to last block */
+ long sect_per_block;
+ int shift;
+
+ vol->blksize_bits = HFSP_BLOCKSZ_BITS;
+ vol->blksize = HFSP_BLOCKSZ;
+ vol->startblock = 0;
+ vol->maxblocks = 3;
+ /* this should be enough until we find the volume descriptor */
+ vol->extents = NULL; /* Thanks to Jeremias Sauceda */
+
+ btree_reset(&vol->catalog);
+ vol->os_fd = os_fd;
+
+ // vol->maxblocks = os_seek(vol->os_fd, -1, HFSP_BLOCKSZ_BITS);
+ // This wont work for /dev/... but we do not really need it
+
+ if( volume_read_wrapper(vol, &vol->vol))
+ return -1;
+ if( volume_read(vol, &backup, vol->maxblocks - 2))
+ return -1;
+
+ /* Now switch blksize from HFSP_BLOCKSZ (512) to value given in header
+ and adjust depend values accordingly, after that a block always
+ means a HFS+ allocation size */
+
+ /* Usually 4096 / 512 == 8 */
+ sect_per_block = vol->vol.blocksize / HFSP_BLOCKSZ;
+ shift = 0;
+ if( sect_per_block > 1) {
+ shift = 1;
+ while( sect_per_block > 2) {
+ sect_per_block >>=1;
+ shift++;
+ } /* shift = 3 */
+ }
+ vol -> blksize_bits += shift;
+ vol -> blksize = 1 << vol->blksize_bits;
+ vol -> startblock >>= shift;
+ vol -> maxblocks = vol->vol.total_blocks; /* cant calculate via shift ? */
+
+ if( btree_init_cat(&vol->catalog, vol, &vol->vol.cat_file))
+ return -1;
+
+ return 0;
+}
+
+/* Write back all data eventually cached and close the device */
+int
+volume_close(volume* vol)
+{
+ btree_close(&vol->catalog);
+ if( vol->extents) {
+ btree_close(vol->extents);
+ FREE(vol->extents);
+ }
+ return 0;
+}
+
+/* internal fucntion used to create the extents btree,
+ is called by inline function when needed */
+void
+volume_create_extents_tree(volume* vol)
+{
+ btree* result = (btree*) ALLOC(btree*, sizeof(btree));
+ if( !result)
+ HFSP_ERROR(ENOMEM, "No memory for extents btree");
+ if( !btree_init_extent(result, vol, &vol->vol.ext_file)) {
+ vol->extents = result;
+ return;
+ }
+ fail:
+ vol->extents = NULL;
+}
+
+/* Determine whether the volume is a HFS-plus volume */
+int
+volume_probe(int fd, long long offset)
+{
+ UInt16 *vol;
+ int ret = 0;
+
+ vol = (UInt16 *)malloc(2 * 1 << HFSP_BLOCKSZ_BITS);
+ os_seek_offset( fd, 2 * (1 << HFSP_BLOCKSZ_BITS) + offset );
+ os_read(fd, vol, 2, HFSP_BLOCKSZ_BITS);
+
+ if (__be16_to_cpu(vol[0]) == HFS_VOLHEAD_SIG &&
+ __be16_to_cpu(vol[0x7c]) == HFSP_VOLHEAD_SIG) {
+ ret = -1;
+ } else if (__be16_to_cpu(vol[0]) == HFSP_VOLHEAD_SIG) {
+ ret = -1;
+ }
+
+ free(vol);
+ return ret;
+}
+
diff --git a/fs/hfsplus/record.c b/fs/hfsplus/record.c
deleted file mode 100644
index d4e7af1..0000000
--- a/fs/hfsplus/record.c
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * libhfsp - library for reading and writing Macintosh HFS+ volumes.
- *
- * a record contains a key and a folder or file and is part
- * of a btree.
- *
- * Copyright (C) 2000 Klaus Halfmann <khalfmann(a)libra.de>
- * Original 1996-1998 Robert Leslie <rob(a)mars.org>
- * Additional work by Brad Boyer (flar(a)pants.nu)
- *
- * 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., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * $Id: record.c,v 1.24 2000/10/17 05:58:46 hasi Exp $
- */
-
-#include "config.h"
-#include "libhfsp.h"
-#include "hfstime.h"
-#include "record.h"
-#include "volume.h"
-#include "btree.h"
-#include "unicode.h"
-#include "swab.h"
-
-/* read a hfsp_cat_key from memory */
-void* record_readkey(void* p, void* buf)
-{
- hfsp_cat_key* key = (hfsp_cat_key*) buf;
- const void* check;
- UInt16 key_length, len,i;
- UInt16* cp;
-
- key->key_length = key_length = bswabU16_inc(p);
- check = p;
- key->parent_cnid = bswabU32_inc(p);
- key->name.strlen = len = bswabU16_inc(p);
- cp = key->name.name;
- for (i=0; i < len; i++, cp++)
- *cp = bswabU16_inc(p);
- /* check if keylenght was correct */
- if (key_length != ((char*) p) - ((char*) check))
- HFSP_ERROR(EINVAL, "Invalid key length in record_readkey");
- return p;
- fail:
- return NULL;
-}
-
-/* read a hfsp_extent_key from memory */
-void* record_extent_readkey(void* p, void* buf)
-{
- hfsp_extent_key* key = (hfsp_extent_key*) buf;
- UInt16 key_length;
-
- key->key_length = key_length = bswabU16_inc(p);
- key->fork_type = bswabU8_inc(p);
- key->filler = bswabU8_inc(p);
- if (key_length != 10)
- HFSP_ERROR(-1, "Invalid key length in record_extent_readkey");
- key->file_id = bswabU32_inc(p);
- key->start_block = bswabU32_inc(p);
- return p;
- fail:
- return NULL;
-}
-
-
-/* read posix permission from memory */
-static inline void* record_readperm(void *p, hfsp_perm* perm)
-{
- perm->owner= bswabU32_inc(p);
- perm->group= bswabU32_inc(p);
- perm->mode = bswabU32_inc(p);
- perm->dev = bswabU32_inc(p);
- return p;
-}
-
-/* read directory info */
-static inline void* record_readDInfo(void *p, DInfo* info)
-{
- info->frRect.top = bswabU16_inc(p);
- info->frRect.left = bswabU16_inc(p);
- info->frRect.bottom = bswabU16_inc(p);
- info->frRect.right = bswabU16_inc(p);
- info->frFlags = bswabU16_inc(p);
- info->frLocation.v = bswabU16_inc(p);
- info->frLocation.h = bswabU16_inc(p);
- info->frView = bswabU16_inc(p);
- return p;
-}
-
-/* read extra Directory info */
-static inline void* record_readDXInfo(void *p, DXInfo* xinfo)
-{
- xinfo->frScroll.v = bswabU16_inc(p);
- xinfo->frScroll.h = bswabU16_inc(p);
- xinfo->frOpenChain = bswabU32_inc(p);
- xinfo->frUnused = bswabU16_inc(p);
- xinfo->frComment = bswabU16_inc(p);
- xinfo->frPutAway = bswabU32_inc(p);
- return p;
-}
-
-/* read a hfsp_cat_folder from memory */
-static void* record_readfolder(void *p, hfsp_cat_folder* folder)
-{
- folder->flags = bswabU16_inc(p);
- folder->valence = bswabU32_inc(p);
- folder->id = bswabU32_inc(p);
- folder->create_date = bswabU32_inc(p);
- folder->content_mod_date = bswabU32_inc(p);
- folder->attribute_mod_date = bswabU32_inc(p);
- folder->access_date = bswabU32_inc(p);
- folder->backup_date = bswabU32_inc(p);
- p = record_readperm (p, &folder->permissions);
- p = record_readDInfo (p, &folder->user_info);
- p = record_readDXInfo (p, &folder->finder_info);
- folder->text_encoding = bswabU32_inc(p);
- folder->reserved = bswabU32_inc(p);
- return p;
-}
-
-/* read file info */
-static inline void* record_readFInfo(void *p, FInfo* info)
-{
- info->fdType = bswabU32_inc(p);
- info->fdCreator = bswabU32_inc(p);
- info->fdFlags = bswabU16_inc(p);
- info->fdLocation.v = bswabU16_inc(p);
- info->fdLocation.h = bswabU16_inc(p);
- info->fdFldr = bswabU16_inc(p);
- return p;
-}
-
-/* read extra File info */
-static inline void* record_readFXInfo(void *p, FXInfo* xinfo)
-{
- SInt16 *q;
- xinfo->fdIconID = bswabU16_inc(p);
- q=(SInt16*) p;
- q+=4; // skip unused
- p=(void *)q;
- xinfo->fdComment = bswabU16_inc(p);
- xinfo->fdPutAway = bswabU32_inc(p);
- return p;
-}
-
-/* read a hfsp_cat_file from memory */
-static void* record_readfile(void *p, hfsp_cat_file* file)
-{
- file->flags = bswabU16_inc(p);
- file->reserved1 = bswabU32_inc(p);
- file->id = bswabU32_inc(p);
- file->create_date = bswabU32_inc(p);
- file->content_mod_date = bswabU32_inc(p);
- file->attribute_mod_date = bswabU32_inc(p);
- file->access_date = bswabU32_inc(p);
- file->backup_date = bswabU32_inc(p);
- p = record_readperm (p, &file->permissions);
- p = record_readFInfo (p, &file->user_info);
- p = record_readFXInfo (p, &file->finder_info);
- file->text_encoding = bswabU32_inc(p);
- file->reserved2 = bswabU32_inc(p);
- p = volume_readfork (p, &file->data_fork);
- return volume_readfork (p, &file->res_fork);
-}
-
-/* read a hfsp_cat_thread from memory */
-static void* record_readthread(void *p, hfsp_cat_thread* entry)
-{
- int i;
- UInt16 len;
- UInt16* cp;
-
- entry-> reserved = bswabU16_inc(p);
- entry-> parentID = bswabU32_inc(p);
- entry->nodeName.strlen = len= bswabU16_inc(p);
- cp = entry->nodeName.name;
- if (len > 255)
- HFSP_ERROR(-1, "Invalid key length in record thread");
- for (i=0; i < len; i++, cp++)
- *cp = bswabU16_inc(p);
- return p;
- fail:
- return NULL;
-}
-
-/* read a hfsp_cat_entry from memory */
-static void* record_readentry(void *p, hfsp_cat_entry* entry)
-{
- UInt16 type = bswabU16_inc(p);
- entry->type = type;
- switch (type)
- {
- case HFSP_FOLDER:
- return record_readfolder(p, &entry->u.folder);
- case HFSP_FILE:
- return record_readfile (p, &entry->u.file);
- case HFSP_FOLDER_THREAD:
- case HFSP_FILE_THREAD:
- return record_readthread(p, &entry->u.thread);
- default:
- HFSP_ERROR(-1, "Unexpected record type in record_readentry");
- } ;
- fail:
- return NULL;
-}
-
-
-/* Most of the functions here will not change the node in the btree,
- But this must be changed in the future ... */
-
-
-/* intialize the record with the given index entry in the btree. */
-static int record_init(record* r, btree* bt, node_buf* buf, UInt16 index)
-{
- void *p;
- r-> tree = bt;
- p = btree_key_by_index(bt,buf,index);
- if (!p)
- return -1;
- p = record_readkey (p, &r->key);
- if (!p)
- return -1;
- p = record_readentry(p, &r->record);
- if (!p)
- return -1;
- r->node_index = buf->index;
- r-> keyind = index;
-
- return 0;
-}
-
-/* intialize the record with the given index entry in the btree. */
-static int record_init_extent(extent_record* r, btree* bt, node_buf*
buf, UInt16 index)
-{
- void *p;
- r-> tree = bt;
- p = btree_key_by_index(bt, buf,index);
- if (!p)
- return -1;
- p = record_extent_readkey(p, &r->key);
- if (!p)
- return -1;
- p = volume_readextent(p, r->extent);
- if (!p)
- return -1;
- r->node_index = buf->index;
- r-> keyind = index;
-
- return 0;
-}
-
-/* intialize the record to the first record of the tree
- * which is (per design) the root node.
- */
-int record_init_root(record* r, btree* tree)
-{
- // Position to first leaf node ...
- UInt32 leaf_head = tree->head.leaf_head;
- node_buf* buf = btree_node_by_index(tree, leaf_head);
- if (!buf)
- return -1;
- return record_init(r, tree, buf, 0);
-}
-
-/* Compare two cat_keys ... */
-int record_key_compare(void* k1, void* k2)
-{
- hfsp_cat_key* key1 = (hfsp_cat_key*) k1;
- hfsp_cat_key* key2 = (hfsp_cat_key*) k2;
- int diff = key2->parent_cnid - key1->parent_cnid;
- if (!diff) // same parent
- diff = fast_unicode_compare(&key1->name, &key2->name);
- return diff;
-}
-
-/* Compare two extent_keys ... */
-int record_extent_key_compare(void* k1, void* k2)
-{
- hfsp_extent_key* key1 = (hfsp_extent_key*) k1;
- hfsp_extent_key* key2 = (hfsp_extent_key*) k2;
- int diff = key2->fork_type - key1->fork_type;
- if (!diff) // same type
- {
- diff = key2->file_id - key1->file_id;
- if (!diff) // same file
- diff = key2->start_block - key1->start_block;
- }
- return diff;
-}
-
-/* Position node in btree so that key might be inside */
-static node_buf* record_find_node(btree* tree, void *key)
-{
- int start, end, mid, comp; // components of a binary search
- void *p = NULL;
- char curr_key[tree->head.max_key_len];
- // The current key under examination
- hfsp_key_read readkey = tree->kread;
- hfsp_key_compare key_compare = tree->kcomp;
- UInt32 index;
- node_buf* node = btree_node_by_index(tree, tree->head.root);
- if (!node)
- HFSP_ERROR(-1, "record_find_node: Cant position to root node");
- while (node->desc.kind == HFSP_NODE_NDX)
- {
- mid = start = 0;
- end = node->desc.num_rec;
- comp = -1;
- while (start < end)
- {
- mid = (start + end) >> 1;
- p = btree_key_by_index(tree, node, mid);
- if (!p)
- HFSP_ERROR(-1, "record_find_node: unexpected error");
- p = readkey (p, curr_key);
- if (!p)
- HFSP_ERROR(-1, "record_find_node: unexpected error");
- comp = key_compare(curr_key, key);
- if (comp > 0)
- start = mid + 1;
- else if (comp < 0)
- end = mid;
- else
- break;
- }
- if (!p) // Empty tree, fascinating ...
- HFSP_ERROR(-1, "record_find_node: unexpected empty node");
- if (comp < 0) // mmh interesting key is before this key ...
- {
- if (mid == 0)
- return NULL; // nothing before this key ..
- p = btree_key_by_index(tree, node, mid-1);
- if (!p)
- HFSP_ERROR(-1, "record_find_node: unexpected error");
- p = readkey (p, curr_key);
- if (!p)
- HFSP_ERROR(-1, "record_find_node: unexpected error");
- }
-
- index = bswabU32_inc(p);
- node = btree_node_by_index(tree, index);
- }
- return node; // go on and use the found node
- fail:
- return NULL;
-}
-
-/* search for the given key in the btree.
- *
- * returns pointer to memory just after key or NULL
- * In any case *keyind recives the index where the
- * key was found (or could be inserted.)
- */
-static void *
-record_find_key(btree* tree, void* key, int* keyind, UInt16* node_index)
-{
- node_buf* buf = record_find_node(tree, key);
- if (buf)
- {
- int comp = -1;
- int start = 0; // components of a binary search
- int end = buf->desc.num_rec;
- int mid = -1;
- void *p = NULL;
- char curr_key[tree->head.max_key_len];
- hfsp_key_read readkey = tree->kread;
- hfsp_key_compare key_compare = tree->kcomp;
- while (start < end)
- {
- mid = (start + end) >> 1;
- p = btree_key_by_index(tree, buf, mid);
- if (!p)
- HFSP_ERROR(-1, "record_init_key: unexpected error");
- p = readkey (p, curr_key);
- if (!p)
- HFSP_ERROR(-1, "record_init_cat_key: unexpected error");
- comp = key_compare(curr_key, key);
- if (comp > 0)
- start = mid + 1;
- else if (comp < 0)
- end = mid;
- else
- break;
- }
- if (!p) // Empty tree, fascinating ...
- HFSP_ERROR(ENOENT, "record_init_key: unexpected empty node");
- *keyind = mid;
- *node_index = buf->index;
- if (!comp) // found something ...
- return p;
- }
- HFSP_ERROR(ENOENT, NULL);
- fail:
- return NULL;
-}
-
-/* intialize the record by searching for the given key in the btree.
- *
- * r is umodified on error.
- */
-static int
-record_init_key(record* r, btree* tree, hfsp_cat_key* key)
-{
- int keyind;
- UInt16 node_index;
- void *p = record_find_key(tree, key, &keyind, &node_index);
-
- if (p)
- {
- r -> tree = tree;
- r -> node_index= node_index;
- r -> keyind = keyind;
- r -> key = *key; // Better use a record_key_copy ...
- p = record_readentry(p, &r->record);
- if (!p)
- HFSP_ERROR(-1, "record_init_key: unexpected error");
- return 0;
- }
- fail:
- return -1;
-}
-
-/* intialize the extent_record to the extent identified by the
- * (first) blockindex.
- *
- * forktype: either HFSP_EXTEND_DATA or HFSP_EXTEND_RSRC
- */
-int record_init_file(extent_record* r, btree* tree,
- UInt8 forktype, UInt32 fileId, UInt32 blockindex)
-{
- int keyind;
- UInt16 node_index;
- hfsp_extent_key key = { 10, forktype, 0, fileId, blockindex };
- void *p = record_find_key(tree, &key, &keyind, &node_index);
-
- if (p)
- {
- r -> tree = tree;
- r -> node_index= node_index;
- r -> keyind = keyind;
- r -> key = key; // Better use a record_key_copy ...
- p = volume_readextent(p, r->extent);
- if (!p)
- HFSP_ERROR(-1, "record_init_file: unexpected error");
- return 0;
- }
- fail:
- return -1;
-}
-
-/* intialize the record to the folder identified by cnid
- */
-int record_init_cnid(record* r, btree* tree, UInt32 cnid)
-{
- hfsp_cat_key thread_key; // the thread is the first record
-
- thread_key.key_length = 6; // null name (like '.' in unix )
- thread_key.parent_cnid = cnid;
- thread_key.name.strlen = 0;
-
- return record_init_key(r, tree, &thread_key);
-}
-
-/* intialize the record to the first record of the parent.
- */
-int record_init_parent(record* r, record* parent)
-{
- if (parent->record.type == HFSP_FOLDER)
- return record_init_cnid(r, parent->tree, parent->record.u.folder.id);
- else if(parent->record.type == HFSP_FOLDER_THREAD)
- {
- if (r != parent)
- *r = *parent; // The folder thread is in fact the first entry, like '.'
- return 0;
- }
- HFSP_ERROR(EINVAL,
- "record_init_parent: parent is neither folder nor folder thread.");
-
- fail:
- return EINVAL;
-}
-
-
-/* find correct node record for given node and *pindex.
- *
- * index of record in this (or next) node
- * */
-static node_buf* prepare_next(btree* tree, UInt16 node_index, UInt16* pindex)
-{
- node_buf* buf = btree_node_by_index(tree, node_index);
- btree_node_desc* desc = &buf->desc;
- UInt32 numrec = desc->num_rec;
- if (*pindex >= numrec) // move on to next node
- {
- UInt16 next = desc->next;
- *pindex = 0;
- if (!next /* is there a next node ? */
- || !( buf = btree_node_by_index(tree, next)))
- return NULL;
- }
- return buf;
-}
-/* move record foreward to next entry.
- *
- * In case of an error the value of *r is undefined !
- */
-int record_next(record* r)
-{
- btree* tree = r->tree;
- UInt16 index = r->keyind +1;
- UInt32 parent;
- node_buf* buf = prepare_next(tree, r->node_index, &index);
-
- if (!buf)
- return ENOENT; // No (more) such file or directory
-
- parent = r->key.parent_cnid;
-
- if (record_init(r, tree, buf, index))
- return -1;
-
- if (r->key.parent_cnid != parent || // end of current directory
- index != r->keyind) // internal error ?
- return ENOENT; // No (more) such file or directory
-
- return 0;
-}
-
-/* move record foreward to next extent record.
- *
- * In case of an error the value of *r is undefined !
- */
-int record_next_extent(extent_record* r)
-{
- btree* tree = r->tree;
- UInt16 index = r->keyind +1;
- UInt32 file_id;
- UInt8 fork_type;
- node_buf* buf = prepare_next(tree, r->node_index, &index);
-
- if (!buf)
- return ENOENT; // No (more) such file or directory
-
- file_id = r->key.file_id;
- fork_type = r->key.fork_type;
-
- if (record_init_extent(r, tree, buf, index))
- return -1;
-
- if (r->key.file_id != file_id || // end of current file
- r->key.fork_type != fork_type || // end of current fork
- index != r->keyind) // internal error ?
- return ENOENT; // No (more) such file or directory
-
- return 0;
-}
-
-/* intialize the record by searching for the given string in the given folder.
- *
- * parent and r may be the same.
- */
-int record_init_string_parent(record* r, record* parent, char* name)
-{
- hfsp_cat_key key;
-
- if (parent->record.type == HFSP_FOLDER)
- key.parent_cnid = parent->record.u.folder.id;
- else if(parent->record.type == HFSP_FOLDER_THREAD)
- key.parent_cnid = parent->key.parent_cnid;
- else
- HFSP_ERROR(-1, "record_init_string_parent: parent is not a folder.");
-
- key.key_length = 6 + unicode_asc2uni(&key.name,name); // 6 for minumum size
- return record_init_key(r, parent->tree, &key);
-
- fail:
- return -1;
-}
-
-/* move record up in folder hierarchy (if possible) */
-int record_up(record* r)
-{
- if (r->record.type == HFSP_FOLDER)
- {
- // locate folder thread
- if (record_init_cnid(r, r->tree, r->record.u.folder.id))
- return -1;
- }
- else if(r->record.type == HFSP_FOLDER_THREAD)
- {
- // do nothing were are already where we want to be
- }
- else
- HFSP_ERROR(-1, "record_up: record is neither folder nor folder thread.");
-
- if(r->record.type != HFSP_FOLDER_THREAD)
- HFSP_ERROR(-1, "record_up: unable to locate parent");
- return record_init_cnid(r, r->tree, r->record.u.thread.parentID);
-
- fail:
- return -1;
-}
-
-#ifdef DEBUG
-
-/* print Quickdraw Point */
-static void record_print_Point(Point* p)
-{
- printf("[ v=%d, h=%d ]", p->v, p->h);
-}
-
-/* print Quickdraw Rect */
-static void record_print_Rect(Rect* r)
-{
- printf("[ top=%d, left=%d, bottom=%d, right=%d ]",
- r->top, r->left, r->bottom, r->right);
-}
-
-/* print the key of a record */
-static void record_print_key(hfsp_cat_key* key)
-{
- char buf[255]; // mh this _might_ overflow
- unicode_uni2asc(buf, &key->name, 255);
- printf("parent cnid : %ld\n", key->parent_cnid);
- printf("name : %s\n", buf);
-}
-
-/* print permissions */
-static void record_print_perm(hfsp_perm* perm)
-{
- printf("owner :\t%ld\n", perm->owner);
- printf("group :\t%ld\n", perm->group);
- printf("perm :\t0x%lX\n",perm->mode);
- printf("dev :\t%ld\n", perm->dev);
-}
-
-/* print Directory info */
-static void record_print_DInfo(DInfo* dinfo)
-{
- printf( "frRect :\t"); record_print_Rect(&dinfo->frRect);
- printf("\nfrFlags :\t0X%X\n", dinfo->frFlags);
- printf( "frLocation :\t");
record_print_Point(&dinfo->frLocation);
- printf("\nfrView :\t0X%X\n", dinfo->frView);
-}
-
-/* print extended Directory info */
-static void record_print_DXInfo(DXInfo* xinfo)
-{
- printf( "frScroll :\t");
record_print_Point(&xinfo->frScroll);
- printf("\nfrOpenChain :\t%ld\n", xinfo->frOpenChain);
- printf( "frUnused :\t%d\n", xinfo->frUnused);
- printf( "frComment :\t%d\n", xinfo->frComment);
- printf( "frPutAway :\t%ld\n", xinfo->frPutAway);
-}
-
-static void record_print_folder(hfsp_cat_folder* folder)
-{
- printf("flags :\t0x%X\n", folder->flags);
- printf("valence :\t0x%lX\n", folder->valence);
- printf("id :\t%ld\n", folder->id);
- record_print_perm (&folder->permissions);
- record_print_DInfo (&folder->user_info);
- record_print_DXInfo (&folder->finder_info);
- printf("text_encoding :\t0x%lX\n", folder->text_encoding);
- printf("reserved :\t0x%lX\n", folder->reserved);
-}
-
-/* print File info */
-static void record_print_FInfo(FInfo* finfo)
-{
- printf( "fdType :\t%4.4s\n", (char*) &finfo->fdType);
- printf( "fdCreator :\t%4.4s\n", (char*) &finfo->fdCreator);
- printf( "fdFlags :\t0X%X\n", finfo->fdFlags);
- printf( "fdLocation :\t");
record_print_Point(&finfo->fdLocation);
- printf("\nfdFldr :\t%d\n", finfo->fdFldr);
-}
-
-/* print extended File info */
-static void record_print_FXInfo(FXInfo* xinfo)
-{
- printf( "fdIconID :\t%d\n", xinfo->fdIconID);
- // xinfo -> fdUnused;
- printf( "fdComment :\t%d\n", xinfo->fdComment);
- printf( "fdPutAway :\t%ld\n", xinfo->fdPutAway);
-}
-
-/* print folder entry */
-
-/* print file entry */
-static void record_print_file(hfsp_cat_file* file)
-{
- printf("flags :\t0x%X\n", file->flags);
- printf("reserved1 :\t0x%lX\n", file->reserved1);
- printf("id :\t%ld\n", file->id);
- record_print_perm (&file->permissions);
- record_print_FInfo (&file->user_info);
- record_print_FXInfo (&file->finder_info);
- printf("text_encoding :\t0x%lX\n", file->text_encoding);
- printf("reserved :\t0x%lX\n", file->reserved2);
- printf("Datafork:\n");
- volume_print_fork (&file->data_fork);
- printf("Rsrcfork:\n");
- volume_print_fork (&file->res_fork);
-}
-
-/* print info for a file or folder thread */
-static void record_print_thread(hfsp_cat_thread* entry)
-{
- char buf[255]; // mh this _might_ overflow
- unicode_uni2asc(buf, &entry->nodeName, 255);
- printf("parent cnid :\t%ld\n", entry->parentID);
- printf("name :\t%s\n" , buf);
-}
-
-/* print the information for a record */
-static void record_print_entry(hfsp_cat_entry* entry)
-{
- switch (entry->type)
- {
- case HFSP_FOLDER:
- printf("=== Folder ===\n");
- return record_print_folder(&entry->u.folder);
- case HFSP_FILE:
- printf("=== File ===\n");
- return record_print_file (&entry->u.file);
- case HFSP_FOLDER_THREAD:
- printf("=== Folder Thread ===\n");
- return record_print_thread(&entry->u.thread);
- case HFSP_FILE_THREAD:
- printf("=== File Thread ==\n");
- return record_print_thread(&entry->u.thread);
- default:
- printf("=== Unknown Record Type ===\n");
- } ;
-}
-
- /* Dump all the record information to stdout */
-void record_print(record* r)
-{
- printf ("keyind : %u\n", r->keyind);
- record_print_key (&r->key);
- record_print_entry(&r->record);
-}
-
-#endif
diff --git a/fs/hfsplus/volume.c b/fs/hfsplus/volume.c
deleted file mode 100644
index 40b3eac..0000000
--- a/fs/hfsplus/volume.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * libhfs - library for reading and writing Macintosh HFS volumes
- *
- * Code to acces the basic volume information of a HFS+ volume.
- *
- * Copyright (C) 2000 Klaus Halfmann <khalfmann(a)libra.de>
- * Original work by 1996-1998 Robert Leslie <rob(a)mars.org>
- * other work 2000 from Brad Boyer (flar(a)pants.nu)
- *
- * 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., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * $Id: volume.c,v 1.21 2000/10/25 05:43:04 hasi Exp $
- */
-
-#include "config.h"
-#include "libhfsp.h"
-#include "volume.h"
-#include "record.h"
-#include "btree.h"
-#include "blockiter.h"
-#include "os.h"
-#include "swab.h"
-#include "hfstime.h"
-
-
-/* Fill a given buffer with the given block in volume.
- */
-int
-volume_readinbuf(volume * vol,void* buf, long block)
-{
- UInt16 blksize_bits;
- ASSERT( block < vol->maxblocks);
-
- blksize_bits = vol->blksize_bits;
- block += vol->startblock;
- if( os_seek(vol->os_fd, block, blksize_bits) == block)
- if( 1 == os_read(vol->os_fd, buf, 1, blksize_bits))
- return 0;
- return -1;
-}
-
-/* read multiple blocks into given memory.
- *
- * returns given pinter or NULL on failure.
- */
-void*
-volume_readfromfork(volume* vol, void* buf,
- hfsp_fork_raw* f, UInt32 block,
- UInt32 count, UInt8 forktype, UInt32 fileId)
-{
- blockiter iter;
- char *cbuf = buf;
-
- blockiter_init(&iter, vol, f, forktype, fileId);
- if( blockiter_skip(&iter, block))
- return NULL;
-
- while( count > 0) {
- --count;
- if( volume_readinbuf(vol, cbuf, blockiter_curr(&iter)))
- return NULL;
- cbuf += vol->blksize;
- if( count > 0 && blockiter_next(&iter))
- return NULL;
- }
- return buf;
-}
-
-
-/* Read a raw hfsp_extent_rec from memory.
- *
- * return pointer right after the structure.
- */
-void*
-volume_readextent(void *p, hfsp_extent_rec er)
-{
- int i;
- hfsp_extent *e;
-
- for( i=0; i < 8; i++) {
- e = &er[i];
- e->start_block = bswabU32_inc(p);
- e->block_count = bswabU32_inc(p);
- }
- return p;
-}
-
-/* Read a raw hfsp_fork from memory.
- *
- * return pointer right after the structure.
- */
-void*
-volume_readfork(void *p, hfsp_fork_raw* f)
-{
- f->total_size = bswabU64_inc(p);
- f->clump_size = bswabU32_inc(p);
- f->total_blocks = bswabU32_inc(p);
-
- return volume_readextent(p, f->extents);
-}
-
-/* Read the volume from the given buffer and swap the bytes.
- *
- * ToDo: add more consitency checks.
- */
-static int
-volume_readbuf(hfsp_vh* vh, char * p)
-{
- if( (vh->signature = bswabU16_inc(p)) != HFSP_VOLHEAD_SIG)
- HFSP_ERROR(-1, "This is not a HFS+ volume");
-
- vh->version = bswabU16_inc(p);
- vh->attributes = bswabU32_inc(p);
- vh->last_mount_vers = bswabU32_inc(p);
- vh->reserved = bswabU32_inc(p);
- vh->create_date = bswabU32_inc(p);
- vh->modify_date = bswabU32_inc(p);
- vh->backup_date = bswabU32_inc(p);
- vh->checked_date = bswabU32_inc(p);
- vh->file_count = bswabU32_inc(p);
- vh->folder_count = bswabU32_inc(p);
- vh->blocksize = bswabU32_inc(p);
- vh->total_blocks = bswabU32_inc(p);
- vh->free_blocks = bswabU32_inc(p);
- vh->next_alloc = bswabU32_inc(p);
- vh->rsrc_clump_sz = bswabU32_inc(p);
- vh->data_clump_sz = bswabU32_inc(p);
- vh->next_cnid = bswabU32_inc(p);
- vh->write_count = bswabU32_inc(p);
- vh->encodings_bmp = bswabU64_inc(p);
- memcpy(vh->finder_info, p, 32);
- p += 32; // So finderinfo must be swapped later, ***
- p = volume_readfork(p, &vh->alloc_file );
- p = volume_readfork(p, &vh->ext_file );
- p = volume_readfork(p, &vh->cat_file );
- p = volume_readfork(p, &vh->attr_file );
- volume_readfork(p, &vh->start_file );
- return 0;
- fail:
- return -1;
-}
-
-/* Read the volume from the given block */
-static int
-volume_read(volume * vol, hfsp_vh* vh, UInt32 block)
-{
- char buf[vol->blksize];
-
- if( volume_readinbuf(vol, buf, block))
- return -1;
- return volume_readbuf(vh, buf);
-}
-
-/* Find out wether the volume is wrapped and unwrap it eventually */
-static int
-volume_read_wrapper(volume * vol, hfsp_vh* vh)
-{
- UInt16 signature;
- char buf[vol->blksize];
- char *p = buf;
-
- if( volume_readinbuf(vol, buf, 2) ) // Wrapper or volume header starts here
- return -1;
-
- signature = bswabU16_inc(p);
- if( signature == HFS_VOLHEAD_SIG) { /* Wrapper */
- UInt32 drAlBlkSiz; /* size (in bytes) of allocation blocks */
- UInt32 sect_per_block; /* how may block build an hfs sector */
- UInt16 drAlBlSt; /* first allocation block in volume */
- UInt16 embeds, embedl; /* Start/lenght of embedded area in blocks */
-
- p += 0x12; /* skip unneded HFS vol fields */
- drAlBlkSiz = bswabU32_inc(p); /* offset 0x14 */
- p += 0x4; /* skip unneded HFS vol fields */
- drAlBlSt = bswabU16_inc(p); /* offset 0x1C */
-
- p += 0x5E; /* skip unneded HFS vol fields */
- signature = bswabU16_inc(p); /* offset 0x7C, drEmbedSigWord */
- if( signature != HFSP_VOLHEAD_SIG)
- HFSP_ERROR(-1, "This looks like a normal HFS volume");
- embeds = bswabU16_inc(p);
- embedl = bswabU16_inc(p);
- sect_per_block = (drAlBlkSiz / HFSP_BLOCKSZ);
- // end is absolute (not relative to HFS+ start)
- vol->maxblocks = embedl * sect_per_block;
- vol->startblock = drAlBlSt + embeds * sect_per_block;
- /* Now we can try to read the embedded HFS+ volume header */
- return volume_read(vol,vh,2);
- }
- else if( signature == HFSP_VOLHEAD_SIG) { /* Native HFS+ volume */
- p = buf; // Restore to begin of block
- return volume_readbuf(vh, p);
- } else
- HFSP_ERROR(-1, "Neither Wrapper nor native HFS+ volume header found");
-fail:
- return -1;
-}
-
-
-/* Open the device, read and verify the volume header
- (and its backup) */
-int
-volume_open( volume* vol, int os_fd )
-{
- hfsp_vh backup; /* backup volume found at second to last block */
- long sect_per_block;
- int shift;
-
- vol->blksize_bits = HFSP_BLOCKSZ_BITS;
- vol->blksize = HFSP_BLOCKSZ;
- vol->startblock = 0;
- vol->maxblocks = 3;
- /* this should be enough until we find the volume descriptor */
- vol->extents = NULL; /* Thanks to Jeremias Sauceda */
-
- btree_reset(&vol->catalog);
- vol->os_fd = os_fd;
-
- // vol->maxblocks = os_seek(vol->os_fd, -1, HFSP_BLOCKSZ_BITS);
- // This wont work for /dev/... but we do not really need it
-
- if( volume_read_wrapper(vol, &vol->vol))
- return -1;
- if( volume_read(vol, &backup, vol->maxblocks - 2))
- return -1;
-
- /* Now switch blksize from HFSP_BLOCKSZ (512) to value given in header
- and adjust depend values accordingly, after that a block always
- means a HFS+ allocation size */
-
- /* Usually 4096 / 512 == 8 */
- sect_per_block = vol->vol.blocksize / HFSP_BLOCKSZ;
- shift = 0;
- if( sect_per_block > 1) {
- shift = 1;
- while( sect_per_block > 2) {
- sect_per_block >>=1;
- shift++;
- } /* shift = 3 */
- }
- vol -> blksize_bits += shift;
- vol -> blksize = 1 << vol->blksize_bits;
- vol -> startblock >>= shift;
- vol -> maxblocks = vol->vol.total_blocks; /* cant calculate via shift ? */
-
- if( btree_init_cat(&vol->catalog, vol, &vol->vol.cat_file))
- return -1;
-
- return 0;
-}
-
-/* Write back all data eventually cached and close the device */
-int
-volume_close(volume* vol)
-{
- btree_close(&vol->catalog);
- if( vol->extents) {
- btree_close(vol->extents);
- FREE(vol->extents);
- }
- return 0;
-}
-
-/* internal fucntion used to create the extents btree,
- is called by inline function when needed */
-void
-volume_create_extents_tree(volume* vol)
-{
- btree* result = (btree*) ALLOC(btree*, sizeof(btree));
- if( !result)
- HFSP_ERROR(ENOMEM, "No memory for extents btree");
- if( !btree_init_extent(result, vol, &vol->vol.ext_file)) {
- vol->extents = result;
- return;
- }
- fail:
- vol->extents = NULL;
-}
-
-/* Determine whether the volume is a HFS-plus volume */
-int
-volume_probe(int fd, long long offset)
-{
- UInt16 *vol;
- int ret = 0;
-
- vol = (UInt16 *)malloc(2 * 1 << HFSP_BLOCKSZ_BITS);
- os_seek_offset( fd, 2 * (1 << HFSP_BLOCKSZ_BITS) + offset );
- os_read(fd, vol, 2, HFSP_BLOCKSZ_BITS);
-
- if (__be16_to_cpu(vol[0]) == HFS_VOLHEAD_SIG &&
- __be16_to_cpu(vol[0x7c]) == HFSP_VOLHEAD_SIG) {
- ret = -1;
- } else if (__be16_to_cpu(vol[0]) == HFSP_VOLHEAD_SIG) {
- ret = -1;
- }
-
- free(vol);
- return ret;
-}
-
--
1.6.2.4
3
9
Author: blueswirl
Date: Sun Nov 28 21:03:46 2010
New Revision: 978
URL: http://tracker.coreboot.org/trac/openbios/changeset/978
Log:
Rename conflicting hfsplus files
Files in fs/hfs and fs/hfsplus have same names, this causes problems
during linkage.
Use prefix 'hfsp_' for the conflicting files.
Acked-by: Andreas Färber <andreas.faerber(a)web.de>
Signed-off-by: Blue Swirl <blauwirbel(a)gmail.com>
Added:
trunk/openbios-devel/fs/hfsplus/hfsp_blockiter.c
- copied, changed from r977, trunk/openbios-devel/fs/hfsplus/blockiter.c
trunk/openbios-devel/fs/hfsplus/hfsp_btree.c
- copied, changed from r977, trunk/openbios-devel/fs/hfsplus/btree.c
trunk/openbios-devel/fs/hfsplus/hfsp_record.c
- copied, changed from r977, trunk/openbios-devel/fs/hfsplus/record.c
trunk/openbios-devel/fs/hfsplus/hfsp_unicode.c
- copied, changed from r977, trunk/openbios-devel/fs/hfsplus/unicode.c
trunk/openbios-devel/fs/hfsplus/hfsp_volume.c
- copied, changed from r977, trunk/openbios-devel/fs/hfsplus/volume.c
Deleted:
trunk/openbios-devel/fs/hfsplus/blockiter.c
trunk/openbios-devel/fs/hfsplus/btree.c
trunk/openbios-devel/fs/hfsplus/record.c
trunk/openbios-devel/fs/hfsplus/unicode.c
trunk/openbios-devel/fs/hfsplus/volume.c
Modified:
trunk/openbios-devel/fs/hfsplus/build.xml
Modified: trunk/openbios-devel/fs/hfsplus/build.xml
==============================================================================
--- trunk/openbios-devel/fs/hfsplus/build.xml Sun Nov 28 14:13:38 2010 (r977)
+++ trunk/openbios-devel/fs/hfsplus/build.xml Sun Nov 28 21:03:46 2010 (r978)
@@ -1,11 +1,11 @@
<build>
<library name="fs" type="static" target="target">
- <object source="blockiter.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="btree.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_blockiter.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_btree.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
<object source="libhfsp.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="record.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="unicode.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
- <object source="volume.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_record.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_unicode.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
+ <object source="hfsp_volume.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
<object source="hfsp_fs.c" flags="-I$(SRCDIR)/fs/hfsplus/include -I$(SRCDIR)/fs/ -fno-strict-aliasing" condition="HFSP"/>
</library>
</build>
Copied and modified: trunk/openbios-devel/fs/hfsplus/hfsp_blockiter.c (from r977, trunk/openbios-devel/fs/hfsplus/blockiter.c)
==============================================================================
Copied and modified: trunk/openbios-devel/fs/hfsplus/hfsp_btree.c (from r977, trunk/openbios-devel/fs/hfsplus/btree.c)
==============================================================================
--- trunk/openbios-devel/fs/hfsplus/btree.c Sun Nov 28 14:13:38 2010 (r977, copy source)
+++ trunk/openbios-devel/fs/hfsplus/hfsp_btree.c Sun Nov 28 21:03:46 2010 (r978)
@@ -287,7 +287,7 @@
UInt16 node_size = bt->head.node_size;
// The offsets are found at the end of the node ...
UInt16 off_pos = node_size - (index +1) * sizeof(btree_record_offset);
- // position of offset at end of node
+ // position of offset at end of node
btree_record_offset* offset =
(btree_record_offset*) (buf->node + off_pos);
Copied and modified: trunk/openbios-devel/fs/hfsplus/hfsp_record.c (from r977, trunk/openbios-devel/fs/hfsplus/record.c)
==============================================================================
Copied and modified: trunk/openbios-devel/fs/hfsplus/hfsp_unicode.c (from r977, trunk/openbios-devel/fs/hfsplus/unicode.c)
==============================================================================
Copied and modified: trunk/openbios-devel/fs/hfsplus/hfsp_volume.c (from r977, trunk/openbios-devel/fs/hfsplus/volume.c)
==============================================================================
--- trunk/openbios-devel/fs/hfsplus/volume.c Sun Nov 28 14:13:38 2010 (r977, copy source)
+++ trunk/openbios-devel/fs/hfsplus/hfsp_volume.c Sun Nov 28 21:03:46 2010 (r978)
@@ -180,7 +180,7 @@
UInt32 drAlBlkSiz; /* size (in bytes) of allocation blocks */
UInt32 sect_per_block; /* how may block build an hfs sector */
UInt16 drAlBlSt; /* first allocation block in volume */
- UInt16 embeds, embedl; /* Start/lenght of embedded area in blocks */
+ UInt16 embeds, embedl; /* Start/lenght of embedded area in blocks */
p += 0x12; /* skip unneded HFS vol fields */
drAlBlkSiz = bswabU32_inc(p); /* offset 0x14 */
@@ -303,7 +303,7 @@
if (__be16_to_cpu(vol[0]) == HFS_VOLHEAD_SIG &&
__be16_to_cpu(vol[0x7c]) == HFSP_VOLHEAD_SIG) {
- ret = -1;
+ ret = -1;
} else if (__be16_to_cpu(vol[0]) == HFSP_VOLHEAD_SIG) {
ret = -1;
}
1
0
[commit] r976 - in trunk/openbios-devel: arch/ppc/qemu include/arch/ppc
by repository service Nov. 28, 2010
by repository service Nov. 28, 2010
Nov. 28, 2010
Author: afaerber
Date: Sun Nov 28 12:40:42 2010
New Revision: 976
URL: http://tracker.coreboot.org/trac/openbios/changeset/976
Log:
ppc: Create function descriptors for global functions on ppc64
This should also fix linker errors observed by Blue.
v2:
* __divide_error is called from C code, too. Spotted by Blue.
Cc: Blue Swirl <blauwirbel(a)gmail.com>
Cc: Alexander Graf <agraf(a)suse.de>
Signed-off-by: Andreas Färber <andreas.faerber(a)web.de>
Modified:
trunk/openbios-devel/arch/ppc/qemu/start.S
trunk/openbios-devel/include/arch/ppc/asmdefs.h
Modified: trunk/openbios-devel/arch/ppc/qemu/start.S
==============================================================================
--- trunk/openbios-devel/arch/ppc/qemu/start.S Sat Nov 27 23:37:46 2010 (r975)
+++ trunk/openbios-devel/arch/ppc/qemu/start.S Sun Nov 28 12:40:42 2010 (r976)
@@ -285,8 +285,7 @@
exception_return:
EXCEPTION_EPILOGUE
- .globl __divide_error
-__divide_error:
+_GLOBAL(__divide_error):
trap_error:
mflr r3
b BRANCH_LABEL(unexpected_excep)
@@ -473,7 +472,7 @@
.long 0
.previous
/* void call_elf( arg1, arg2, entry ) */
-GLOBL(call_elf):
+_GLOBAL(call_elf):
mflr r0
stwu r1,-16(r1)
stw r0,20(r1)
@@ -633,7 +632,7 @@
#define LG_CACHE_LINE_SIZE 5
/* flush_icache_range( unsigned long start, unsigned long stop) */
-GLOBL(flush_icache_range):
+_GLOBAL(flush_icache_range):
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
Modified: trunk/openbios-devel/include/arch/ppc/asmdefs.h
==============================================================================
--- trunk/openbios-devel/include/arch/ppc/asmdefs.h Sat Nov 27 23:37:46 2010 (r975)
+++ trunk/openbios-devel/include/arch/ppc/asmdefs.h Sun Nov 28 12:40:42 2010 (r976)
@@ -118,6 +118,24 @@
#define EXTERN( name ) _##name
#endif
+#if defined(__powerpc64__) && !defined(__darwin__)
+#define _GLOBAL(name) \
+ .align 2 ; \
+ .section ".opd", "aw" ; \
+ .globl name ; \
+ .globl .##name ; \
+ name: \
+ .quad .##name ; \
+ .quad .TOC.@tocbase ; \
+ .quad 0 ; \
+ .previous ; \
+ .type .##name, @function ; \
+ .##name
+#else
+#define _GLOBAL(name) \
+ GLOBL(name)
+#endif
+
#define BIT(n) (1<<(31-(n)))
#endif /* _H_ASMDEFS */
3
7
Author: afaerber
Date: Sun Nov 28 14:13:38 2010
New Revision: 977
URL: http://tracker.coreboot.org/trac/openbios/changeset/977
Log:
ppc: Create some more function descriptors for ppc64
Fix an error in generic ppc code as well. Reported by Blue.
Signed-off-by: Andreas Färber <andreas.faerber(a)web.de>
Acked-by: Blue Swirl <blauwirbel(a)gmail.com>
Modified:
trunk/openbios-devel/arch/ppc/timebase.S
Modified: trunk/openbios-devel/arch/ppc/timebase.S
==============================================================================
--- trunk/openbios-devel/arch/ppc/timebase.S Sun Nov 28 12:40:42 2010 (r976)
+++ trunk/openbios-devel/arch/ppc/timebase.S Sun Nov 28 14:13:38 2010 (r977)
@@ -4,7 +4,7 @@
/*
* unsigned long long _get_ticks(void);
*/
-GLOBL(_get_ticks):
+_GLOBAL(_get_ticks):
1: mftbu r3
mftb r4
mftbu r5
@@ -15,16 +15,16 @@
/*
* Delay for a number of ticks
*/
-GLOBL(_wait_ticks):
+_GLOBAL(_wait_ticks):
mflr r8 /* save link register */
mr r7, r3 /* save tick count */
- bl _get_ticks /* Get start time */
+ bl BRANCH_LABEL(_get_ticks) /* Get start time */
/* Calculate end time */
addc r7, r4, r7 /* Compute end time lower */
addze r6, r3 /* and end time upper */
-1: bl _get_ticks /* Get current time */
+1: bl BRANCH_LABEL(_get_ticks) /* Get current time */
subfc r4, r4, r7 /* Subtract current time from end time */
subfe. r3, r3, r6
bge 1b /* Loop until time expired */
1
0