diff options
Diffstat (limited to 'packages')
50 files changed, 6328 insertions, 81 deletions
diff --git a/packages/alsa/alsa-fpu.inc b/packages/alsa/alsa-fpu.inc new file mode 100644 index 0000000000..ebd3493e6c --- /dev/null +++ b/packages/alsa/alsa-fpu.inc @@ -0,0 +1,6 @@ + +def get_alsa_fpu_setting(bb, d): + if bb.data.getVar('TARGET_FPU', d, 1) in [ 'soft' ]: + return "--with-softfloat" + return "" + diff --git a/packages/alsa/alsa-lib_1.0.14.bb b/packages/alsa/alsa-lib_1.0.14.bb index de805b9a4b..ba46342ae7 100644 --- a/packages/alsa/alsa-lib_1.0.14.bb +++ b/packages/alsa/alsa-lib_1.0.14.bb @@ -3,7 +3,7 @@ HOMEPAGE = "http://www.alsa-project.org" SECTION = "libs/multimedia" LICENSE = "GPL" -PR = "r1" +PR = "r2" # configure.in sets -D__arm__ on the command line for any arm system # (not just those with the ARM instruction set), this should be removed, @@ -17,6 +17,9 @@ SRC_URI = "ftp://ftp.alsa-project.org/pub/lib/alsa-lib-${PV}.tar.bz2 \ inherit autotools pkgconfig +require alsa-fpu.inc +EXTRA_OECONF += "${@get_alsa_fpu_setting(bb, d)} " + EXTRA_OECONF = "--with-cards=pdaudiocf --with-oss=yes" do_stage () { diff --git a/packages/alsa/alsa-state.bb b/packages/alsa/alsa-state.bb index 55541872fa..e2a92dcfc8 100644 --- a/packages/alsa/alsa-state.bb +++ b/packages/alsa/alsa-state.bb @@ -8,7 +8,7 @@ DESCRIPTION = "Default ALSA configuration" LICENSE = "GPL" RRECOMMENDS_alsa-state = "alsa-states" PV = "0.1.0" -PR = "r0" +PR = "r1" SRC_URI = " \ file://asoundrc \ diff --git a/packages/alsa/alsa-state/akita/.mtn2git_empty b/packages/alsa/alsa-state/akita/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/alsa/alsa-state/akita/.mtn2git_empty diff --git a/packages/alsa/alsa-state/akita/asound.state b/packages/alsa/alsa-state/akita/asound.state new file mode 100644 index 0000000000..ee5ef519c3 --- /dev/null +++ b/packages/alsa/alsa-state/akita/asound.state @@ -0,0 +1,619 @@ +state.Spitz { + control.1 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 63' + iface MIXER + name 'Capture Volume' + value.0 23 + value.1 23 + } + control.2 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Capture ZC Switch' + value.0 false + value.1 false + } + control.3 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Capture Switch' + value.0 false + value.1 false + } + control.4 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Headphone Playback ZC Switch' + value.0 false + value.1 false + } + control.5 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Speaker Playback ZC Switch' + value.0 false + value.1 false + } + control.6 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 None + comment.item.1 '32Khz' + comment.item.2 '44.1Khz' + comment.item.3 '48Khz' + iface MIXER + name 'Playback De-emphasis' + value None + } + control.7 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Normal + comment.item.1 'L Invert' + comment.item.2 'R Invert' + comment.item.3 'L + R Invert' + iface MIXER + name 'Capture Polarity' + value Normal + } + control.8 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Playback 6dB Attenuate' + value false + } + control.9 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Capture 6dB Attenuate' + value false + } + control.10 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 255' + iface MIXER + name 'PCM Volume' + value.0 255 + value.1 255 + } + control.11 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'Linear Control' + comment.item.1 'Adaptive Boost' + iface MIXER + name 'Bass Boost' + value 'Linear Control' + } + control.12 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 '130Hz @ 48kHz' + comment.item.1 '200Hz @ 48kHz' + iface MIXER + name 'Bass Filter' + value '130Hz @ 48kHz' + } + control.13 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name 'Bass Volume' + value 11 + } + control.14 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name 'Treble Volume' + value 11 + } + control.15 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 '8kHz' + comment.item.1 '4kHz' + iface MIXER + name 'Treble Cut-off' + value '8kHz' + } + control.16 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name '3D Switch' + value false + } + control.17 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name '3D Volume' + value 9 + } + control.18 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 '200Hz' + comment.item.1 '500Hz' + iface MIXER + name '3D Lower Cut-off' + value '200Hz' + } + control.19 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 '2.2kHz' + comment.item.1 '1.5kHz' + iface MIXER + name '3D Upper Cut-off' + value '2.2kHz' + } + control.20 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Capture + comment.item.1 Playback + iface MIXER + name '3D Mode' + value Playback + } + control.21 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 7' + iface MIXER + name 'ALC Capture Target Volume' + value 3 + } + control.22 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 7' + iface MIXER + name 'ALC Capture Max Volume' + value 7 + } + control.23 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Off + comment.item.1 Right + comment.item.2 Left + comment.item.3 Stereo + iface MIXER + name 'ALC Capture Function' + value Left + } + control.24 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'ALC Capture ZC Switch' + value false + } + control.25 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name 'ALC Capture Hold Time' + value 0 + } + control.26 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name 'ALC Capture Decay Time' + value 3 + } + control.27 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name 'ALC Capture Attack Time' + value 2 + } + control.28 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + iface MIXER + name 'ALC Capture NG Threshold' + value 0 + } + control.29 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 '2.2kHz' + comment.item.1 '1.5kHz' + iface MIXER + name 'ALC Capture NG Type' + value '2.2kHz' + } + control.30 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'ALC Capture NG Switch' + value false + } + control.31 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 255' + iface MIXER + name 'Left ADC Capture Volume' + value 195 + } + control.32 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 255' + iface MIXER + name 'Right ADC Capture Volume' + value 0 + } + control.33 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'ZC Timeout Switch' + value false + } + control.34 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Playback Invert Switch' + value false + } + control.35 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Right Speaker Playback Invert Switch' + value true + } + control.36 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 3' + iface MIXER + name 'Mic Boost' + value.0 0 + value.1 0 + } + control.37 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 7' + iface MIXER + name 'Bypass Left Playback Volume' + value.0 0 + value.1 0 + } + control.38 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 7' + iface MIXER + name 'Bypass Right Playback Volume' + value.0 0 + value.1 0 + } + control.39 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 7' + iface MIXER + name 'Bypass Mono Playback Volume' + value.0 0 + value.1 0 + } + control.40 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mono Playback ZC Switch' + value false + } + control.41 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 127' + iface MIXER + name 'Headphone Playback Volume' + value.0 121 + value.1 121 + } + control.42 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 127' + iface MIXER + name 'Speaker Playback Volume' + value.0 121 + value.1 121 + } + control.43 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 127' + iface MIXER + name 'Mono Playback Volume' + value 0 + } + control.44 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Stereo + comment.item.1 'Mono (Left)' + comment.item.2 'Mono (Right)' + comment.item.3 'Digital Mono' + iface MIXER + name 'Right ADC Mux' + value 'Mono (Left)' + } + control.45 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Stereo + comment.item.1 'Mono (Left)' + comment.item.2 'Mono (Right)' + comment.item.3 'Digital Mono' + iface MIXER + name 'Left ADC Mux' + value 'Mono (Left)' + } + control.46 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'Line 1' + comment.item.1 'Line 2' + iface MIXER + name 'Differential Mux' + value 'Line 1' + } + control.47 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 VREF + comment.item.1 'ROUT1 + Vol' + comment.item.2 MonoOut + comment.item.3 ROUT1 + iface MIXER + name 'Out3 Mux' + value VREF + } + control.48 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'Line 1' + comment.item.1 'Line 2' + comment.item.2 'Line 3' + comment.item.3 PGA + comment.item.4 Differential + iface MIXER + name 'Right Line Mux' + value 'Line 2' + } + control.49 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'Line 1' + comment.item.1 'Line 2' + comment.item.2 'Line 3' + comment.item.3 PGA + comment.item.4 Differential + iface MIXER + name 'Left Line Mux' + value 'Line 1' + } + control.50 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'Line 1' + comment.item.1 'Line 2' + comment.item.2 'Line 3' + comment.item.3 Differential + iface MIXER + name 'Right PGA Mux' + value 'Line 2' + } + control.51 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'Line 1' + comment.item.1 'Line 2' + comment.item.2 'Line 3' + comment.item.3 Differential + iface MIXER + name 'Left PGA Mux' + value 'Line 1' + } + control.52 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mono Mixer Left Playback Switch' + value false + } + control.53 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mono Mixer Left Bypass Switch' + value false + } + control.54 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mono Mixer Right Playback Switc' + value false + } + control.55 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mono Mixer Right Bypass Switch' + value false + } + control.56 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Right Mixer Left Playback Switc' + value false + } + control.57 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Right Mixer Left Bypass Switch' + value false + } + control.58 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Right Mixer Playback Switch' + value true + } + control.59 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Right Mixer Right Bypass Switch' + value false + } + control.60 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Left Mixer Playback Switch' + value true + } + control.61 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Left Mixer Left Bypass Switch' + value false + } + control.62 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Left Mixer Right Playback Switc' + value false + } + control.63 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Left Mixer Right Bypass Switch' + value false + } + control.64 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Headphone + comment.item.1 Mic + comment.item.2 Line + comment.item.3 Headset + comment.item.4 Off + iface MIXER + name 'Jack Function' + value Off + } + control.65 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 On + comment.item.1 Off + iface MIXER + name 'Speaker Function' + value On + } +} diff --git a/packages/alsa/alsa-state/c7x0/asound.state b/packages/alsa/alsa-state/c7x0/asound.state index 7fd648fcf6..caef65c120 100644 --- a/packages/alsa/alsa-state/c7x0/asound.state +++ b/packages/alsa/alsa-state/c7x0/asound.state @@ -5,16 +5,16 @@ state.Corgi { comment.count 2 comment.range '0 - 127' iface MIXER - name 'Playback Volume' - value.0 103 - value.1 103 + name 'Master Playback Volume' + value.0 98 + value.1 98 } control.2 { comment.access 'read write' comment.type BOOLEAN comment.count 2 iface MIXER - name 'Playback Switch' + name 'Master Playback ZC Switch' value.0 false value.1 false } @@ -25,15 +25,15 @@ state.Corgi { comment.range '0 - 31' iface MIXER name 'Capture Volume' - value.0 23 - value.1 23 + value.0 31 + value.1 31 } control.4 { comment.access 'read write' comment.type BOOLEAN comment.count 2 iface MIXER - name 'Capture Switch' + name 'Line Capture Switch' value.0 false value.1 false } @@ -51,7 +51,7 @@ state.Corgi { comment.count 1 iface MIXER name 'Capture Mic Switch' - value true + value false } control.7 { comment.access 'read write' @@ -106,7 +106,7 @@ state.Corgi { comment.count 1 iface MIXER name 'Output Mixer Line Bypass Switch' - value true + value false } control.13 { comment.access 'read write' @@ -122,7 +122,7 @@ state.Corgi { comment.count 1 iface MIXER name 'Output Mixer HiFi Playback Swit' - value false + value true } control.15 { comment.access 'read write' @@ -141,11 +141,10 @@ state.Corgi { comment.access 'read write' comment.type ENUMERATED comment.count 1 - comment.item.0 Auto - comment.item.1 On - comment.item.2 Off + comment.item.0 On + comment.item.1 Off iface MIXER name 'Speaker Function' - value On + value Off } } diff --git a/packages/bluez/bluez-cups-backend_3.18.bb b/packages/bluez/bluez-cups-backend_3.18.bb new file mode 100644 index 0000000000..64884fa904 --- /dev/null +++ b/packages/bluez/bluez-cups-backend_3.18.bb @@ -0,0 +1,26 @@ +require bluez-utils3.inc + +DEPENDS += "cups" + +# see bluez-utils3.inc for the explanation of these option +EXTRA_OECONF = " \ + --enable-bccmd \ + --enable-hid2hci \ + --disable-alsa \ + --enable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + +PACKAGES = "${PN}" + +FILES_${PN} = "${libdir}/cups/backend/bluetooth" +RDEPENDS_${PN} = "cups"
\ No newline at end of file diff --git a/packages/bluez/bluez-cups-backend_3.19.bb b/packages/bluez/bluez-cups-backend_3.19.bb new file mode 100644 index 0000000000..64884fa904 --- /dev/null +++ b/packages/bluez/bluez-cups-backend_3.19.bb @@ -0,0 +1,26 @@ +require bluez-utils3.inc + +DEPENDS += "cups" + +# see bluez-utils3.inc for the explanation of these option +EXTRA_OECONF = " \ + --enable-bccmd \ + --enable-hid2hci \ + --disable-alsa \ + --enable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + +PACKAGES = "${PN}" + +FILES_${PN} = "${libdir}/cups/backend/bluetooth" +RDEPENDS_${PN} = "cups"
\ No newline at end of file diff --git a/packages/bluez/bluez-libs_3.18.bb b/packages/bluez/bluez-libs_3.18.bb new file mode 100644 index 0000000000..6ddf62a4fb --- /dev/null +++ b/packages/bluez/bluez-libs_3.18.bb @@ -0,0 +1 @@ +require bluez-libs.inc diff --git a/packages/bluez/bluez-libs_3.19.bb b/packages/bluez/bluez-libs_3.19.bb new file mode 100644 index 0000000000..6ddf62a4fb --- /dev/null +++ b/packages/bluez/bluez-libs_3.19.bb @@ -0,0 +1 @@ +require bluez-libs.inc diff --git a/packages/bluez/bluez-utils-alsa_3.18.bb b/packages/bluez/bluez-utils-alsa_3.18.bb new file mode 100644 index 0000000000..e2f48fba49 --- /dev/null +++ b/packages/bluez/bluez-utils-alsa_3.18.bb @@ -0,0 +1,24 @@ +require bluez-utils3.inc + +DEPENDS += "alsa-lib" + +# see bluez-utils3.inc for the explanation of these option +EXTRA_OECONF = " \ + --enable-bccmd \ + --disable-hid2hci \ + --enable-alsa \ + --disable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + +PACKAGES = "${PN}" +FILES_${PN} = "${libdir}/alsa-lib/libasound*" diff --git a/packages/bluez/bluez-utils-alsa_3.19.bb b/packages/bluez/bluez-utils-alsa_3.19.bb new file mode 100644 index 0000000000..e2f48fba49 --- /dev/null +++ b/packages/bluez/bluez-utils-alsa_3.19.bb @@ -0,0 +1,24 @@ +require bluez-utils3.inc + +DEPENDS += "alsa-lib" + +# see bluez-utils3.inc for the explanation of these option +EXTRA_OECONF = " \ + --enable-bccmd \ + --disable-hid2hci \ + --enable-alsa \ + --disable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + +PACKAGES = "${PN}" +FILES_${PN} = "${libdir}/alsa-lib/libasound*" diff --git a/packages/bluez/bluez-utils3.inc b/packages/bluez/bluez-utils3.inc new file mode 100644 index 0000000000..ddf90a2248 --- /dev/null +++ b/packages/bluez/bluez-utils3.inc @@ -0,0 +1,143 @@ +DESCRIPTION = "Linux Bluetooth Stack Userland Utilities." +SECTION = "console" +PRIORITY = "optional" +DEPENDS = "gstreamer gst-plugins-base bluez-libs-${PV} libusb dbus glib-2.0" +PROVIDES = "bluez-utils-dbus" +RPROVIDES_${PN} = "bluez-pan bluez-sdp bluez-utils-dbus" +RREPLACES = "bluez-utils-dbus" +RCONFLICTS_${PN} = "bluez-utils-nodbus" +LICENSE = "GPL" + +# ti patch doesn't apply, people using it should rediff it and send it upstream +SRC_URI = "http://bluez.sourceforge.net/download/bluez-utils-${PV}.tar.gz \ + file://hcid.conf " +# file://hciattach-ti-bts.patch;patch=1 \ + +S = "${WORKDIR}/bluez-utils-${PV}" + +inherit autotools update-rc.d + +EXTRA_OECONF = " \ + --enable-bccmd \ + --enable-hid2hci \ + --enable-alsa \ + --enable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + +# The config options are explained below: + +# --enable-obex enable OBEX support +# --enable-alsa enable ALSA support, not needed for nokia770, nokia800 and fic-gtao1 +# --enable-cups install CUPS backend support +# --enable-bccmd install BCCMD interface utility +# --enable-avctrl install Audio/Video control utility +# --enable-hid2hci install HID mode switching utility +# --enable-dfutool install DFU firmware upgrade utility + +# --enable-glib For systems that use and install GLib anyway +# --disable-sdpd The sdpd is obsolete and should no longer be used. This of course requires that hcid will be started with -s to enable the SDP server + +#Following services can be enabled so far: +# --enable-network +# --enable-serial +# --enable-input +# --enable-audio +# --enable-echo + +#There is no need to modify any init script. They will be started +#automatically or on demand. Only /etc/bluetooth/*.service files should +#be patched to change name or the autostart value. +# --enable-configfile +# --enable-initscripts + +#For even smaller -doc packages +# --disable-manpages +# --disable-pcmciarules + +#I haven't seen any embedded device with HID proxy support. So simply +#disable it: +# --disable-hid2hci + + +do_install_append() { + install -d ${D}${base_sbindir} ${D}${base_bindir}/ ${D}${sysconfdir}/apm/event.d/ + mv ${D}${sbindir}/* ${D}${base_sbindir}/ + mv ${D}${bindir}/* ${D}${base_bindir}/ + rmdir ${D}${bindir} ${D}${sbindir} + chmod u+s ${D}${base_sbindir}/hciattach ${D}${base_sbindir}/hciconfig + install -m 0644 ${WORKDIR}/hcid.conf ${D}${sysconfdir}/bluetooth/ + install -m 0755 ${S}/daemon/.libs/passkey-agent ${D}${base_bindir}/ +} + + +INITSCRIPT_NAME = "bluetooth" +INITSCRIPT_PARAMS = "defaults 23 19" + + +PACKAGES =+ "${PN}-compat" + +CONFFILES_${PN} = " \ + ${sysconfdir}/bluetooth/hcid.conf \ + ${sysconfdir}/default/bluetooth \ + " + +CONFFILES_${PN}-compat = " \ + ${sysconfdir}/bluetooth/rfcomm.conf \ + " + +FILES_${PN} = " \ + ${base_sbindir}/hcid \ + ${libdir}/bluetooth \ + ${sysconfdir}/init.d/bluetooth \ + ${sysconfdir}/bluetooth/*.service \ + ${sysconfdir}/bluetooth/hcid.conf \ + ${sysconfdir}/default \ + ${sysconfdir}/dbus-1 \ + ${base_sbindir}/hciattach \ + " + +FILES_${PN}-dbg += " \ + ${libdir}/bluetooth/.debug \ + ${libdir}/cups/backend/.debug \ + ${libdir}/alsa-lib/.debug \ + " + +FILES_${PN}-compat = " \ + ${base_bindir}/sdptool \ + ${base_bindir}/dund \ + ${base_bindir}/rctest \ + ${base_bindir}/ciptool \ + ${base_bindir}/l2test \ + ${base_bindir}/rfcomm \ + ${base_bindir}/hcitool \ + ${base_bindir}/pand \ + ${base_bindir}/hidd \ + ${base_bindir}/l2ping \ + ${base_sbindir}/hciconfig \ + ${base_sbindir}/bccmd \ + ${base_sbindir}/hciemu \ + ${base_sbindir}/hid2hci \ + ${base_bindir}/passkey-agent \ + ${sysconfdir}/bluetooth/rfcomm.conf \ + " + + + + + + + + + + + diff --git a/packages/bluez/bluez-utils_3.18.bb b/packages/bluez/bluez-utils_3.18.bb new file mode 100644 index 0000000000..c0a4f460ba --- /dev/null +++ b/packages/bluez/bluez-utils_3.18.bb @@ -0,0 +1,23 @@ +require bluez-utils3.inc + +# see bluez-utils3.inc for the explanation of these option +EXTRA_OECONF = " \ + --enable-bccmd \ + --enable-hid2hci \ + --disable-alsa \ + --disable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + + +CONFFILES_${PN} = "${sysconfdir}/bluetooth/hcid.conf ${sysconfdir}/bluetooth/rfcomm.conf \ + ${sysconfdir}/default/bluetooth"
\ No newline at end of file diff --git a/packages/bluez/bluez-utils_3.19.bb b/packages/bluez/bluez-utils_3.19.bb new file mode 100644 index 0000000000..c0a4f460ba --- /dev/null +++ b/packages/bluez/bluez-utils_3.19.bb @@ -0,0 +1,23 @@ +require bluez-utils3.inc + +# see bluez-utils3.inc for the explanation of these option +EXTRA_OECONF = " \ + --enable-bccmd \ + --enable-hid2hci \ + --disable-alsa \ + --disable-cups \ + --enable-glib \ + --disable-sdpd \ + --enable-network \ + --enable-serial \ + --enable-input \ + --enable-audio \ + --enable-echo \ + --enable-configfile \ + --enable-initscripts \ + --enable-test \ + " + + +CONFFILES_${PN} = "${sysconfdir}/bluetooth/hcid.conf ${sysconfdir}/bluetooth/rfcomm.conf \ + ${sysconfdir}/default/bluetooth"
\ No newline at end of file diff --git a/packages/gnome/epiphany_2.19.6.bb b/packages/gnome/epiphany_2.19.6.bb index 8d405628ae..cebd39637d 100644 --- a/packages/gnome/epiphany_2.19.6.bb +++ b/packages/gnome/epiphany_2.19.6.bb @@ -1,5 +1,5 @@ DESCRIPTION = "GNOME default webbrowser" -DEPENDS = "gnome-desktop gnome-vfs libgnomeui webkit-gtk" +DEPENDS = "gnome-desktop gnome-vfs libgnomeui webkit-gtk iso-codes" RDEPENDS = "gnome-vfs-plugin-http" PR = "r1" diff --git a/packages/gnome/libwnck_2.10.2.bb b/packages/gnome/libwnck_2.10.2.bb deleted file mode 100644 index 17f5c673d6..0000000000 --- a/packages/gnome/libwnck_2.10.2.bb +++ /dev/null @@ -1,9 +0,0 @@ -LICENSE = "LGPL" -DESCRIPTION = "Window navigation construction toolkit" -HOMEPAGE = "" - -inherit gnome - -do_stage() { - autotools_stage_all -} diff --git a/packages/gnome/libwnck_2.12.1.bb b/packages/gnome/libwnck_2.12.1.bb deleted file mode 100644 index 1830a7540a..0000000000 --- a/packages/gnome/libwnck_2.12.1.bb +++ /dev/null @@ -1,10 +0,0 @@ -LICENSE = "LGPL" -DEPENDS = "gtk+" -DESCRIPTION = "Window navigation construction toolkit" -HOMEPAGE = "" - -inherit gnome - -do_stage() { - autotools_stage_all -} diff --git a/packages/gnome/libwnck_2.13.5.bb b/packages/gnome/libwnck_2.13.5.bb index 5ad3e00cbf..b176493b93 100644 --- a/packages/gnome/libwnck_2.13.5.bb +++ b/packages/gnome/libwnck_2.13.5.bb @@ -1,6 +1,7 @@ -LICENSE = "LGPL" -DEPENDS = "gtk+" -DESCRIPTION = "Window navigation construction toolkit" +DESCRIPTION = "Window navigation construction toolkit" +LICENSE = "LGPL" +SECTION = "x11/libs" +DEPENDS = "gtk+ gdk-pixbuf-csource-native" inherit gnome diff --git a/packages/gnome/libwnck_2.8.1.bb b/packages/gnome/libwnck_2.8.1.bb deleted file mode 100644 index 052e20fe32..0000000000 --- a/packages/gnome/libwnck_2.8.1.bb +++ /dev/null @@ -1,11 +0,0 @@ -LICENSE = "LGPL" -DESCRIPTION = "Window navigation construction toolkit" -HOMEPAGE = "" - -inherit gnome - -do_stage() { - autotools_stage_includes - install -d ${STAGING_LIBDIR} - install -m 755 libwnck/.libs/libwnck-1.so.4.9.0 ${STAGING_LIBDIR}/libwnck-1.so -} diff --git a/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb b/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb index 51fb846ce9..6fbc7d936f 100644 --- a/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb +++ b/packages/gtk+/gdk-pixbuf-csource-native_2.10.14.bb @@ -1,6 +1,6 @@ require gtk+_${PV}.bb inherit native -DEPENDS = "" +DEPENDS = "jpeg-native libpng-native" S = "${WORKDIR}/gtk+-${PV}" FILESPATH = "${FILE_DIRNAME}/gdk-pixbuf-csource:${FILE_DIRNAME}/gtk+-${PV}:${FILE_DIRNAME}/files" SRC_URI += "file://reduce-dependencies.patch;patch=1" @@ -14,6 +14,8 @@ EXTRA_OECONF = "\ --without-x \ --with-gdktarget=linux-fb \ --without-libtiff \ + --with-libjpeg \ + --with-libpng \ " do_compile() { diff --git a/packages/gtk+/gtk+.inc b/packages/gtk+/gtk+.inc index 0805b99f39..14b5026cc6 100644 --- a/packages/gtk+/gtk+.inc +++ b/packages/gtk+/gtk+.inc @@ -4,7 +4,7 @@ HOMEPAGE = "http://www.gtk.org" SECTION = "libs" LICENSE = "LGPL" PRIORITY = "optional" -DEPENDS = "glib-2.0 pango atk jpeg libpng libxext libxcursor gtk-doc libgcrypt" +DEPENDS = "glib-2.0 tiff pango atk jpeg libpng libxext libxcursor gtk-doc libgcrypt" inherit autotools pkgconfig diff --git a/packages/gtk+/gtk+_2.12.0.bb b/packages/gtk+/gtk+_2.12.0.bb index 6b724bab80..57ba24e796 100644 --- a/packages/gtk+/gtk+_2.12.0.bb +++ b/packages/gtk+/gtk+_2.12.0.bb @@ -1,5 +1,7 @@ require gtk+.inc +PR = "r1" + DEPENDS += "cairo" # disable per default - untested and not all patches included. @@ -22,7 +24,7 @@ SRC_URI = "http://download.gnome.org/sources/gtk+/2.12/gtk+-${PV}.tar.bz2 \ # die die die # file://pangoxft2.10.6.diff;patch=1" -EXTRA_OECONF = "--without-libtiff --disable-xkb --disable-glibtest --enable-display-migration" +EXTRA_OECONF = "--with-libtiff --disable-xkb --disable-glibtest --enable-display-migration" LIBV = "2.10.0" diff --git a/packages/libetpan/libetpan_0.52.bb b/packages/libetpan/libetpan_0.52.bb new file mode 100644 index 0000000000..77b2cca39b --- /dev/null +++ b/packages/libetpan/libetpan_0.52.bb @@ -0,0 +1,22 @@ +DESCRIPTION = "libetpan is a library for communicating with mail and news servers. \ +It supports the protocols SMTP, POP3, IMAP and NNTP." +HOMEPAGE = "http://www.etpan.org" +SECTION = "libs" +DEPENDS = "gnutls" +LICENSE = "BSD" +PR = "r0" + +SRC_URI = "${SOURCEFORGE_MIRROR}/libetpan/libetpan-${PV}.tar.gz" + +inherit autotools pkgconfig gettext binconfig + +EXTRA_OECONF = "--without-openssl --with-gnutls --disable-db" + +PARALLEL_MAKE = "" + +do_stage() { + autotools_stage_all +} + +FILES_${PN} = "${libdir}/lib*.so.*" +FILES_${PN}-dev = "${bindir} ${includedir} ${libdir}/lib*.so ${libdir}/*.la ${libdir}/*.a ${libdir}/pkgconfig" diff --git a/packages/libglade/libglade-2.6.2/.mtn2git_empty b/packages/libglade/libglade-2.6.2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/libglade/libglade-2.6.2/.mtn2git_empty diff --git a/packages/libglade/libglade-2.6.2/glade-cruft.patch b/packages/libglade/libglade-2.6.2/glade-cruft.patch new file mode 100644 index 0000000000..0fceccf0c4 --- /dev/null +++ b/packages/libglade/libglade-2.6.2/glade-cruft.patch @@ -0,0 +1,100 @@ +diff -ur libglade-2.4.0~/configure.in libglade-2.4.0/configure.in +--- libglade-2.4.0~/configure.in 2004-05-17 12:38:31.000000000 +0100 ++++ libglade-2.4.0/configure.in 2004-07-28 16:53:09.000000000 +0100 +@@ -147,6 +147,18 @@ + AM_CONDITIONAL(HAVE_PYTHON, $have_python) + AC_SUBST(PYTHON) + ++AC_MSG_CHECKING([for cruft in libgtk]) ++AC_TRY_LINK([ ++#include <gtk/gtk.h> ++#include <stdio.h> ++], [ gtk_tree_get_type (); return 0; ], ++ [ AC_MSG_RESULT(yes) ++ have_cruft=yes ], ++ [ AC_MSG_RESULT(no) ++ AC_DEFINE(DISABLE_CRUFT,,[leave out support for old, broken widgets]) ++ have_cruft=no ]) ++AC_SUBST(DISABLE_CRUFT) ++ + dnl add debugging options ... + changequote(,)dnl + if test "x$GCC" = xyes; then +Only in libglade-2.4.0: configure.in.orig +diff -ur libglade-2.4.0~/glade/glade-gtk.c libglade-2.4.0/glade/glade-gtk.c +--- libglade-2.4.0~/glade/glade-gtk.c 2004-03-13 13:47:35.000000000 +0000 ++++ libglade-2.4.0/glade/glade-gtk.c 2004-07-28 16:53:52.000000000 +0100 +@@ -213,6 +213,8 @@ + gtk_clist_column_titles_hide (GTK_CLIST (w)); + } + ++#ifndef DISABLE_CRUFT ++ + static void + tree_set_selection_mode (GladeXML *xml, GtkWidget *w, + const char *name, const char *value) +@@ -238,6 +240,8 @@ + gtk_tree_set_view_lines (GTK_TREE (w), BOOL (value)); + } + ++#endif ++ + static void + list_set_selection_mode (GladeXML *xml, GtkWidget *w, + const char *name, const char *value) +@@ -254,6 +258,7 @@ + gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (w), BOOL (value)); + } + ++#ifndef DISABLE_CRUFT + static void + text_set_text (GladeXML *xml, GtkWidget *w, + const char *name, const char *value) +@@ -262,6 +267,7 @@ + + gtk_editable_insert_text (GTK_EDITABLE (w), value, -1, &pos); + } ++#endif + + static void + radio_menu_item_set_group (GladeXML *xml, GtkWidget *w, +@@ -1125,13 +1131,17 @@ + glade_register_custom_prop (GTK_TYPE_CLIST, "selection_mode", clist_set_selection_mode); + glade_register_custom_prop (GTK_TYPE_CLIST, "shadow_type", clist_set_shadow_type); + glade_register_custom_prop (GTK_TYPE_CLIST, "show_titles", clist_set_show_titles); ++#ifndef DISABLE_CRUFT + glade_register_custom_prop (GTK_TYPE_TREE, "selection_mode", tree_set_selection_mode); + glade_register_custom_prop (GTK_TYPE_TREE, "view_mode", tree_set_view_mode); + glade_register_custom_prop (GTK_TYPE_TREE, "view_line", tree_set_view_line); ++#endif + glade_register_custom_prop (GTK_TYPE_LIST, "selection_mode", list_set_selection_mode); + glade_register_custom_prop (GTK_TYPE_CHECK_MENU_ITEM, "always_show_toggle", + check_menu_item_set_always_show_toggle); ++#ifndef DISABLE_CRUFT + glade_register_custom_prop (GTK_TYPE_TEXT, "text", text_set_text); ++#endif + glade_register_custom_prop (GTK_TYPE_RADIO_MENU_ITEM, "group", + radio_menu_item_set_group); + glade_register_custom_prop (GTK_TYPE_TOOLBAR, "tooltips", toolbar_set_tooltips); +@@ -1288,8 +1298,10 @@ + glade_standard_build_children, NULL); + glade_register_widget (GTK_TYPE_TEAROFF_MENU_ITEM, glade_standard_build_widget, + NULL, NULL); ++#ifndef DISABLE_CRUFT + glade_register_widget (GTK_TYPE_TEXT, glade_standard_build_widget, + NULL, NULL); ++#endif + glade_register_widget (GTK_TYPE_TEXT_VIEW, glade_standard_build_widget, + NULL, NULL); + glade_register_widget (GTK_TYPE_TIPS_QUERY, glade_standard_build_widget, +@@ -1304,8 +1316,10 @@ + glade_standard_build_children, NULL); + glade_register_widget (GTK_TYPE_TOOL_BUTTON, glade_standard_build_widget, + NULL, NULL); ++#ifndef DISABLE_CRUFT + glade_register_widget (GTK_TYPE_TREE, glade_standard_build_widget, + NULL, NULL); ++#endif + glade_register_widget (GTK_TYPE_TREE_VIEW, glade_standard_build_widget, + NULL, NULL); + glade_register_widget (GTK_TYPE_VBUTTON_BOX, glade_standard_build_widget, diff --git a/packages/libglade/libglade-2.6.2/no-xml2.patch b/packages/libglade/libglade-2.6.2/no-xml2.patch new file mode 100644 index 0000000000..1c2e215b8d --- /dev/null +++ b/packages/libglade/libglade-2.6.2/no-xml2.patch @@ -0,0 +1,499 @@ +diff -urN libglade-2.4.2.orig/configure.in libglade-2.4.2/configure.in +--- libglade-2.4.2.orig/configure.in 2005-02-11 12:42:58.000000000 +0100 ++++ libglade-2.4.2/configure.in 2005-03-22 01:22:00.000000000 +0100 +@@ -52,11 +52,33 @@ + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + + PKG_CHECK_MODULES(LIBGLADE, [dnl +- libxml-2.0 >= required_libxml_version dnl + atk >= required_atk_version dnl + gtk+-2.0 >= required_gtk_version dnl + glib-2.0 >= required_glib_version]) + ++disable_xml2=no ++AC_ARG_WITH([libxml2], ++ AC_HELP_STRING([--without-libxml2], [Don't use libxml2, use Glib's GMarkupParser instead]), ++ [disable_xml2=yes], ++ [disable_xml2=no]) ++ ++AC_MSG_CHECKING([if we are using libxml2]) ++if test "x$disable_xml2" == "xno"; then ++ AC_MSG_RESULT(yes) ++ PKG_CHECK_MODULES(XML2, libxml-2.0 >= 2.4.10) ++ PKGCFG_REQUIRE_LIBXML2="libxml-2.0" ++ LIBGLADE_CFLAGS="$LIBGLADE_CFLAGS $XML2_CFLAGS" ++ LIBGLADE_LIBS="$LIBGLADE_LIBS $XML2_LIBS" ++else ++ LIBGLADE_CFLAGS="$LIBGLADE_CFLAGS -DUSE_GMARKUP_PARSER" ++ PKGCFG_REQUIRE_LIBXML2="" ++ AC_MSG_RESULT(no) ++fi ++ ++AC_SUBST(XML2_LIBS) ++AC_SUBST(XML2_CFLAGS) ++AC_SUBST(PKGCFG_REQUIRE_LIBXML2) ++ + AC_MSG_CHECKING([for native Win32]) + case "$host" in + *-*-mingw*) +@@ -116,6 +138,21 @@ + fi + fi + ++if test "x$disable_xml2" == "xyes"; then ++ echo "*****************************************************" ++ echo " You chose to disable libxml2 and use Glib's" ++ echo " GMarkupParser instead." ++ echo ++ echo " Please bear in mind that using libglade with" ++ echo " GMarkupParser is an experimental feature only." ++ echo ++ echo " Please post problems or success stories to" ++ echo " the glade-devel mailing list. Thank you." ++ echo "*****************************************************" ++fi ++ ++ ++ + GTK_DOC_CHECK(1.0) + + dnl gettext stuff ... there is no message catalog for libglade -- libglade +diff -urN libglade-2.4.2.orig/glade/glade-parser.c libglade-2.4.2/glade/glade-parser.c +--- libglade-2.4.2.orig/glade/glade-parser.c 2004-11-11 11:56:13.000000000 +0100 ++++ libglade-2.4.2/glade/glade-parser.c 2005-03-22 01:20:00.000000000 +0100 +@@ -34,7 +34,15 @@ + # define dgettext(Domain, String) (String) + #endif + +-#include <libxml/parser.h> ++#ifdef USE_GMARKUP_PARSER ++# include <zlib.h> ++#else ++# include <libxml/parser.h> ++#endif ++ ++#ifdef USE_GMARKUP_PARSER ++# define xmlChar gchar ++#endif + + #include "glade-parser.h" + #include "glade-private.h" +@@ -508,7 +516,9 @@ + case PARSER_START: + if (!strcmp(name, "glade-interface")) { + state->state = PARSER_GLADE_INTERFACE; +-#if 0 ++ ++#ifndef USE_GMARKUP_PARSER ++ #if 0 + /* check for correct XML namespace */ + for (i = 0; attrs && attrs[i] != NULL; i += 2) { + if (!strcmp(attrs[i], "xmlns") && +@@ -518,7 +528,9 @@ + g_warning("unknown attribute `%s' for <glade-interface>", + attrs[i]); + } ++ #endif + #endif ++ + } else { + g_warning("Expected <glade-interface>. Got <%s>.", name); + state->prev_state = state->state; +@@ -1063,12 +1075,18 @@ + } + } + ++#ifndef USE_GMARKUP_PARSER ++ + static xmlEntityPtr + glade_parser_get_entity(GladeParseState *state, const xmlChar *name) + { + return xmlGetPredefinedEntity(name); + } + ++#endif /* !defined(USE_GMARKUP_PARSER) */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + static void + glade_parser_warning(GladeParseState *state, const char *msg, ...) + { +@@ -1079,6 +1097,10 @@ + va_end(args); + } + ++#endif /* !defined(USE_GMARKUP_PARSER) */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + static void + glade_parser_error(GladeParseState *state, const char *msg, ...) + { +@@ -1089,6 +1111,10 @@ + va_end(args); + } + ++#endif /* !defined(USE_GMARKUP_PARSER) */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + static void + glade_parser_fatal_error(GladeParseState *state, const char *msg, ...) + { +@@ -1099,6 +1125,10 @@ + va_end(args); + } + ++#endif /* !defined(USE_GMARKUP_PARSER) */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + static xmlSAXHandler glade_parser = { + (internalSubsetSAXFunc)NULL, /* internalSubset */ + (isStandaloneSAXFunc)NULL, /* isStandalone */ +@@ -1126,6 +1156,82 @@ + (fatalErrorSAXFunc)glade_parser_fatal_error, /* fatalError */ + }; + ++#else /* USE_GMARKUP_PARSER */ ++ ++static void ++glade_parser_start_element_wrapper(GMarkupParseContext *context, ++ const gchar *name, ++ const gchar **attr_names, ++ const gchar **attr_values, ++ gpointer state, ++ GError **error) ++{ ++ guint i = 0; ++ ++ /* Pack attribute names/values from two separate ++ * arrays (GMarkupParser style) into one single ++ * array (libxml SAXParser style). This is not ++ * very efficient, but we do it to make the ++ * GMarkupParser code as little invasive as ++ * possible. */ ++ ++ while (attr_names[i] != NULL) { ++ ++i; ++ } ++ ++ if (1) ++ { ++ const gchar *attr[(i*2)+1]; ++ guint j, k; ++ ++ for (j=0, k=0; k < i; j += 2) ++ { ++ attr[j] = attr_names[k]; ++ attr[j+1] = attr_values[k]; ++ ++k; ++ } ++ attr[i*2] = NULL; ++ ++ glade_parser_start_element((GladeParseState*)state, name, attr); ++ } ++} ++ ++static void ++glade_parser_end_element_wrapper(GMarkupParseContext *context, ++ const gchar *name, ++ gpointer state, ++ GError **err) ++{ ++ glade_parser_end_element((GladeParseState*)state, name); ++} ++ ++static void ++glade_parser_characters_wrapper(GMarkupParseContext *context, ++ const gchar *chars, ++ gsize len, ++ gpointer state, ++ GError **err) ++{ ++ glade_parser_characters((GladeParseState*)state, chars, (int) len); ++} ++ ++static void ++glade_parser_error(GMarkupParseContext *context, GError *err, gpointer data) ++{ ++ g_log("Glade-Parser", G_LOG_LEVEL_CRITICAL, "%s", err->message); ++} ++ ++static const GMarkupParser glade_parser = { ++ glade_parser_start_element_wrapper, /* element open */ ++ glade_parser_end_element_wrapper, /* element close */ ++ glade_parser_characters_wrapper, /* text content */ ++ NULL, /* passthrough */ ++ glade_parser_error, /* parse error */ ++}; ++ ++#endif /* USE_GMARKUP_PARSER */ ++ ++ + static void + widget_info_free(GladeWidgetInfo *info) + { +@@ -1191,6 +1297,9 @@ + * + * Returns: the GladeInterface structure for the XML file. + */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + GladeInterface * + glade_parser_parse_file(const gchar *file, const gchar *domain) + { +@@ -1222,6 +1331,31 @@ + return state.interface; + } + ++#else /* defined(USE_GMARKUP_PARSER) */ ++ ++GladeInterface * ++glade_parser_parse_file(const gchar *file, const gchar *domain) ++{ ++ GladeInterface *interface; ++ GError *err = NULL; ++ gchar *content = NULL; ++ gsize clen; ++ ++ if (!g_file_get_contents(file, &content, &clen, &err)) { ++ g_warning("could not load glade file: %s", err->message); ++ g_error_free(err); ++ return NULL; ++ } ++ ++ interface = glade_parser_parse_buffer(content, (gint) clen, domain); ++ ++ g_free(content); ++ ++ return interface; ++} ++ ++#endif /* USE_GMARKUP_PARSER */ ++ + /** + * glade_parser_parse_buffer + * @buffer: a buffer in memory containing XML data. +@@ -1237,6 +1371,9 @@ + * + * Returns: the GladeInterface structure for the XML buffer. + */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + GladeInterface * + glade_parser_parse_buffer(const gchar *buffer, gint len, const gchar *domain) + { +@@ -1263,6 +1400,161 @@ + return state.interface; + } + ++#else /* defined(USE_GMARKUP_PARSER) */ ++ ++ ++static GladeInterface * ++glade_parser_parse_buffer_internal(const gchar *buffer, gint len, const gchar *domain) ++{ ++ GMarkupParseContext *context; ++ GladeParseState state = { 0 }; ++ GError *err = NULL; ++ ++ state.interface = NULL; ++ if (domain) ++ state.domain = domain; ++ else ++ state.domain = textdomain(NULL); ++ ++ /* FIXME: This strstr() is not safe, as it ignores the len ++ * argument and assumes the buffer is NUL-terminated */ ++ if (strstr(buffer, "<?xml") == NULL) { ++ g_warning("No XML header found in document!"); ++ return NULL; ++ } ++ ++ context = g_markup_parse_context_new(&glade_parser, (GMarkupParseFlags) 0, &state, NULL); ++ ++ glade_parser_start_document(&state); ++ ++ if (!g_markup_parse_context_parse(context, buffer, (gssize) len, &err)) { ++ g_warning("document not well formed: %s", err->message); ++ g_error_free(err); ++ if (state.interface) ++ glade_interface_destroy (state.interface); ++ return NULL; ++ } ++ ++ glade_parser_end_document(&state); ++ ++ if (state.state != PARSER_FINISH) { ++ g_warning("did not finish in PARSER_FINISH state!"); ++ ++ if (state.interface) ++ glade_interface_destroy(state.interface); ++ ++ return NULL; ++ } ++ ++ return state.interface; ++} ++ ++struct _gzip_rfc1952_hdr ++{ ++ guint8 id1, id2, cm, flags; ++ guint32 mtime; ++ guint8 xflags; ++ guint8 os; ++}; ++ ++static GladeInterface * ++glade_parser_parse_gzipped_buffer(const gchar *buffer, gint len, const gchar *domain) ++{ ++ struct _gzip_rfc1952_hdr *hdr = (struct _gzip_rfc1952_hdr*)buffer; ++ struct z_stream_s zstream; ++ GladeInterface *interface; ++ const guint8 *cbuf; /* start of compressed data */ ++ guint8 *decompress_buf; ++ gulong decompress_len = 0; ++ gint ret; ++ ++ g_assert(hdr != NULL && hdr->id1 == 0x1f && hdr->id2 == 0x8b); ++ ++ if (hdr->cm != Z_DEFLATED) { ++ g_warning("Unknown decompression method %u", (guint) hdr->cm); ++ return NULL; ++ } ++ ++ /* Uncompressed size (modulo 2^32) is last ++ * 4 bytes of gzipped file, and little endian. ++ * See RFC 1952 */ ++ decompress_len = GUINT32_FROM_LE(*((guint32*)(((guint8*)buffer) + len - 4))); ++ ++ /* paranoid mode: glade files > 5MB are unlikely */ ++ g_return_val_if_fail(decompress_len < 5*1024*1024, NULL); ++ ++ decompress_buf = g_malloc0(decompress_len + 1); /* +1 for NUL-terminator */ ++ ++ /* find start of compressed data, skipping header stuff */ ++ cbuf = (guint8*)buffer + 10; ++ if (hdr->flags & 0x04) { ++ guint16 xlen = GUINT16_FROM_LE(*((guint16*)cbuf)); ++ cbuf += xlen + 2; ++ } ++ if (hdr->flags & 0x08) { ++ guint16 onamelen = strlen(cbuf); ++ cbuf += onamelen + 1; ++ } ++ if (hdr->flags & 0x10) { ++ guint16 commentlen = strlen(cbuf); ++ cbuf += commentlen + 1; ++ } ++ if (hdr->flags & 0x02) ++ { ++ cbuf += 2; /* skip header CRC16 */ ++ } ++ ++ zstream.next_in = (void*)cbuf; ++ zstream.avail_in = (uLongf) len - ((void*)cbuf-(void*)buffer) - 4 - 4 +1; ++ zstream.next_out = decompress_buf; ++ zstream.avail_out= decompress_len; ++ zstream.zalloc = Z_NULL; ++ zstream.zfree = Z_NULL; ++ zstream.opaque = Z_NULL; ++ ++ ret = inflateInit2(&zstream, -MAX_WBITS); ++ ++ if (ret != Z_OK) { ++ g_warning("inflateInit2() failed. zlib error code: %d", ret); ++ g_free(decompress_buf); ++ return NULL; ++ } ++ ++ ret = inflate(&zstream, Z_FINISH); ++ ++ if (ret != Z_STREAM_END) { ++ g_warning("zlib decompression failed. zlib error code: %d", ret); ++ g_free(decompress_buf); ++ return NULL; ++ } ++ ++ interface = glade_parser_parse_buffer_internal(decompress_buf, decompress_len, domain); ++ ++ g_free(decompress_buf); ++ ++ return interface; ++} ++ ++GladeInterface * ++glade_parser_parse_buffer(const gchar *buffer, gint len, const gchar *domain) ++{ ++ g_return_val_if_fail(buffer != NULL, NULL); ++ g_return_val_if_fail(len > 0, NULL); ++ ++ /* Check if buffer is gzipped */ ++ if (buffer[0] == 0x1f && buffer[1] == (gchar)0x8b) { ++ return glade_parser_parse_gzipped_buffer(buffer, len, domain); ++ } ++ ++ /* Buffer is cleartext. */ ++ return glade_parser_parse_buffer_internal(buffer, len, domain); ++} ++ ++#endif /* USE_GMARKUP_PARSER */ ++ ++ ++#ifndef USE_GMARKUP_PARSER ++ + static void + dump_widget(xmlNode *parent, GladeWidgetInfo *info, gint indent) + { +@@ -1382,6 +1674,8 @@ + xmlNodeAddContent(widget, " "); + } + ++#endif /* !defined(USE_GMARKUP_PARSER) */ ++ + /** + * glade_interface_dump + * @interface: the GladeInterface +@@ -1390,6 +1684,9 @@ + * This function dumps the contents of a GladeInterface into a file as + * XML. It is intended mainly as a debugging tool. + */ ++ ++#ifndef USE_GMARKUP_PARSER ++ + void + glade_interface_dump(GladeInterface *interface, const gchar *filename) + { +@@ -1428,6 +1725,17 @@ + xmlFreeDoc(doc); + } + ++#else /* defined(USE_GMARKUP_PARSER) */ ++ ++void ++glade_interface_dump(GladeInterface *interface, const gchar *filename) ++{ ++ g_warning("glade_interface_dump() is only available with libxml2."); ++} ++ ++#endif /* USE_GMARKUP_PARSER */ ++ ++ + #if 0 + int + main(int argc, char **argv) { +diff -urN libglade-2.4.2.orig/libglade-2.0.pc.in libglade-2.4.2/libglade-2.0.pc.in +--- libglade-2.4.2.orig/libglade-2.0.pc.in 2001-12-12 15:28:23.000000000 +0100 ++++ libglade-2.4.2/libglade-2.0.pc.in 2005-03-22 01:20:00.000000000 +0100 +@@ -11,7 +11,7 @@ + Name: Libglade + Description: a library for dynamically loading GLADE interface files + Version: @VERSION@ +-Requires: gtk+-2.0 libxml-2.0 ++Requires: gtk+-2.0 @PKGCFG_REQUIRE_LIBXML2@ + Libs: -L${libdir} -lglade-2.0 + Cflags: -I${includedir}/libglade-2.0 + diff --git a/packages/libglade/libglade_2.6.2.bb b/packages/libglade/libglade_2.6.2.bb new file mode 100644 index 0000000000..f0450e644d --- /dev/null +++ b/packages/libglade/libglade_2.6.2.bb @@ -0,0 +1,32 @@ +LICENSE = "LGPL" +DESCRIPTION = "Runtime support for GTK interface builder" +SECTION = "libs" +PRIORITY = "optional" +DEPENDS = "gtk+ gtk-doc" + +inherit autotools pkgconfig gnome + +PR = "r1" + +SRC_URI += "file://glade-cruft.patch;patch=1 file://no-xml2.patch;patch=1" + +EXTRA_OECONF += "--without-libxml2" + +LDFLAGS += "-lz" + +PACKAGES += " ${PN}-data" +FILES_${PN} = "${libdir}/lib*.so.*" +FILES_${PN}-data = "${datadir}/xml/libglade/glade-2.0.dtd" +FILES_${PN}-dev += "${bindir}/libglade-convert" +#RDEPENDS_${PN} = "${PN}-data" + +headers = "glade-build.h glade-init.h glade-parser.h glade-xml.h glade.h" + +do_stage () { + oe_libinstall -a -so -C glade libglade-2.0 ${STAGING_LIBDIR} + + mkdir -p ${STAGING_INCDIR}/libglade-2.0/glade + for i in ${headers}; do + install -m 0644 ${S}/glade/$i ${STAGING_INCDIR}/libglade-2.0/glade/$i + done +} diff --git a/packages/links/links-x11_2.0+2.1pre26.bb b/packages/links/links-x11_2.0+2.1pre30.bb index 9ee70d9ad4..9ee70d9ad4 100644 --- a/packages/links/links-x11_2.0+2.1pre26.bb +++ b/packages/links/links-x11_2.0+2.1pre30.bb diff --git a/packages/links/links_2.0+2.1pre26.bb b/packages/links/links_2.0+2.1pre30.bb index c46a64f380..c46a64f380 100644 --- a/packages/links/links_2.0+2.1pre26.bb +++ b/packages/links/links_2.0+2.1pre30.bb diff --git a/packages/linux/linux-openmoko-devel/defconfig b/packages/linux/linux-openmoko-devel/defconfig index 1d12b6ec36..f7274016c8 100644 --- a/packages/linux/linux-openmoko-devel/defconfig +++ b/packages/linux/linux-openmoko-devel/defconfig @@ -1604,6 +1604,10 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SQUASHFS_VMALLOC is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set diff --git a/packages/linux/linux-openmoko-devel/printascii.patch b/packages/linux/linux-openmoko-devel/printascii.patch new file mode 100644 index 0000000000..13a014db39 --- /dev/null +++ b/packages/linux/linux-openmoko-devel/printascii.patch @@ -0,0 +1,12 @@ +Index: linux-2.6.22.5/kernel/printk.c +=================================================================== +--- linux-2.6.22.5.orig/kernel/printk.c ++++ linux-2.6.22.5/kernel/printk.c +@@ -535,6 +535,7 @@ asmlinkage int vprintk(const char *fmt, + + /* Emit the output into the temporary buffer */ + printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); ++ printascii(printk_buf); + + /* + * Copy the output into log_buf. If the caller didn't provide diff --git a/packages/linux/linux-openmoko-devel/squashfs.patch b/packages/linux/linux-openmoko-devel/squashfs.patch new file mode 100644 index 0000000000..51efd6b3c9 --- /dev/null +++ b/packages/linux/linux-openmoko-devel/squashfs.patch @@ -0,0 +1,4386 @@ +diff -x .gitignore -Nurp linux-2.6.20/fs/Kconfig linux-2.6.20-squashfs3.2-r2/fs/Kconfig +--- linux-2.6.20/fs/Kconfig 2006-12-25 01:13:12.000000000 +0000 ++++ linux-2.6.20-squashfs3.2-r2/fs/Kconfig 2007-01-16 02:06:03.000000000 +0000 +@@ -1404,6 +1404,71 @@ config CRAMFS + + If unsure, say N. + ++config SQUASHFS ++ tristate "SquashFS 3.2 - Squashed file system support" ++ select ZLIB_INFLATE ++ help ++ Saying Y here includes support for SquashFS 3.2 (a Compressed Read-Only File ++ System). Squashfs is a highly compressed read-only filesystem for Linux. ++ It uses zlib compression to compress both files, inodes and directories. ++ Inodes in the system are very small and all blocks are packed to minimise ++ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K. ++ SquashFS 3.1 supports 64 bit filesystems and files (larger than 4GB), full ++ uid/gid information, hard links and timestamps. ++ ++ Squashfs is intended for general read-only filesystem use, for archival ++ use (i.e. in cases where a .tar.gz file may be used), and in embedded ++ systems where low overhead is needed. Further information and filesystem tools ++ are available from http://squashfs.sourceforge.net. ++ ++ If you want to compile this as a module ( = code which can be ++ inserted in and removed from the running kernel whenever you want), ++ say M here and read <file:Documentation/modules.txt>. The module ++ will be called squashfs. Note that the root file system (the one ++ containing the directory /) cannot be compiled as a module. ++ ++ If unsure, say N. ++ ++config SQUASHFS_EMBEDDED ++ ++ bool "Additional options for memory-constrained systems" ++ depends on SQUASHFS ++ default n ++ help ++ Saying Y here allows you to specify cache sizes and how Squashfs ++ allocates memory. This is only intended for memory constrained ++ systems. ++ ++ If unsure, say N. ++ ++config SQUASHFS_FRAGMENT_CACHE_SIZE ++ int "Number of fragments cached" if SQUASHFS_EMBEDDED ++ depends on SQUASHFS ++ default "3" ++ help ++ By default SquashFS caches the last 3 fragments read from ++ the filesystem. Increasing this amount may mean SquashFS ++ has to re-read fragments less often from disk, at the expense ++ of extra system memory. Decreasing this amount will mean ++ SquashFS uses less memory at the expense of extra reads from disk. ++ ++ Note there must be at least one cached fragment. Anything ++ much more than three will probably not make much difference. ++ ++config SQUASHFS_VMALLOC ++ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED ++ depends on SQUASHFS ++ default n ++ help ++ By default SquashFS uses kmalloc to obtain fragment cache memory. ++ Kmalloc memory is the standard kernel allocator, but it can fail ++ on memory constrained systems. Because of the way Vmalloc works, ++ Vmalloc can succeed when kmalloc fails. Specifying this option ++ will make SquashFS always use Vmalloc to allocate the ++ fragment cache memory. ++ ++ If unsure, say N. ++ + config VXFS_FS + tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" + depends on BLOCK +diff -x .gitignore -Nurp linux-2.6.20/fs/Makefile linux-2.6.20-squashfs3.2-r2/fs/Makefile +--- linux-2.6.20/fs/Makefile 2006-12-25 01:13:12.000000000 +0000 ++++ linux-2.6.20-squashfs3.2-r2/fs/Makefile 2007-01-16 02:06:03.000000000 +0000 +@@ -68,6 +68,7 @@ obj-$(CONFIG_JBD) += jbd/ + obj-$(CONFIG_JBD2) += jbd2/ + obj-$(CONFIG_EXT2_FS) += ext2/ + obj-$(CONFIG_CRAMFS) += cramfs/ ++obj-$(CONFIG_SQUASHFS) += squashfs/ + obj-$(CONFIG_RAMFS) += ramfs/ + obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ + obj-$(CONFIG_CODA_FS) += coda/ +diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/inode.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c +--- linux-2.6.20/fs/squashfs/inode.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c 2007-01-16 02:28:36.000000000 +0000 +@@ -0,0 +1,2329 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * inode.c ++ */ ++ ++#include <linux/squashfs_fs.h> ++#include <linux/module.h> ++#include <linux/zlib.h> ++#include <linux/fs.h> ++#include <linux/squashfs_fs_sb.h> ++#include <linux/squashfs_fs_i.h> ++#include <linux/buffer_head.h> ++#include <linux/vfs.h> ++#include <linux/vmalloc.h> ++#include <linux/smp_lock.h> ++ ++#include "squashfs.h" ++ ++static void vfs_read_inode(struct inode *i); ++static struct dentry *squashfs_get_parent(struct dentry *child); ++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); ++static int squashfs_statfs(struct dentry *, struct kstatfs *); ++static int squashfs_symlink_readpage(struct file *file, struct page *page); ++static long long read_blocklist(struct inode *inode, int index, ++ int readahead_blks, char *block_list, ++ unsigned short **block_p, unsigned int *bsize); ++static int squashfs_readpage(struct file *file, struct page *page); ++static int squashfs_readpage4K(struct file *file, struct page *page); ++static int squashfs_readdir(struct file *, void *, filldir_t); ++static struct dentry *squashfs_lookup(struct inode *, struct dentry *, ++ struct nameidata *); ++static int squashfs_remount(struct super_block *s, int *flags, char *data); ++static void squashfs_put_super(struct super_block *); ++static int squashfs_get_sb(struct file_system_type *,int, const char *, void *, ++ struct vfsmount *); ++static struct inode *squashfs_alloc_inode(struct super_block *sb); ++static void squashfs_destroy_inode(struct inode *inode); ++static int init_inodecache(void); ++static void destroy_inodecache(void); ++ ++static struct file_system_type squashfs_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "squashfs", ++ .get_sb = squashfs_get_sb, ++ .kill_sb = kill_block_super, ++ .fs_flags = FS_REQUIRES_DEV ++}; ++ ++static const unsigned char squashfs_filetype_table[] = { ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK ++}; ++ ++static struct super_operations squashfs_super_ops = { ++ .alloc_inode = squashfs_alloc_inode, ++ .destroy_inode = squashfs_destroy_inode, ++ .statfs = squashfs_statfs, ++ .put_super = squashfs_put_super, ++ .remount_fs = squashfs_remount ++}; ++ ++static struct super_operations squashfs_export_super_ops = { ++ .alloc_inode = squashfs_alloc_inode, ++ .destroy_inode = squashfs_destroy_inode, ++ .statfs = squashfs_statfs, ++ .put_super = squashfs_put_super, ++ .read_inode = vfs_read_inode ++}; ++ ++static struct export_operations squashfs_export_ops = { ++ .get_parent = squashfs_get_parent ++}; ++ ++SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = { ++ .readpage = squashfs_symlink_readpage ++}; ++ ++SQSH_EXTERN const struct address_space_operations squashfs_aops = { ++ .readpage = squashfs_readpage ++}; ++ ++SQSH_EXTERN const struct address_space_operations squashfs_aops_4K = { ++ .readpage = squashfs_readpage4K ++}; ++ ++static const struct file_operations squashfs_dir_ops = { ++ .read = generic_read_dir, ++ .readdir = squashfs_readdir ++}; ++ ++SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = { ++ .lookup = squashfs_lookup ++}; ++ ++ ++static struct buffer_head *get_block_length(struct super_block *s, ++ int *cur_index, int *offset, int *c_byte) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ unsigned short temp; ++ struct buffer_head *bh; ++ ++ if (!(bh = sb_bread(s, *cur_index))) ++ goto out; ++ ++ if (msblk->devblksize - *offset == 1) { ++ if (msblk->swap) ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ else ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ brelse(bh); ++ if (!(bh = sb_bread(s, ++(*cur_index)))) ++ goto out; ++ if (msblk->swap) ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ bh->b_data); ++ else ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ bh->b_data); ++ *c_byte = temp; ++ *offset = 1; ++ } else { ++ if (msblk->swap) { ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ (bh->b_data + *offset + 1)); ++ } else { ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ (bh->b_data + *offset + 1)); ++ } ++ *c_byte = temp; ++ *offset += 2; ++ } ++ ++ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) { ++ if (*offset == msblk->devblksize) { ++ brelse(bh); ++ if (!(bh = sb_bread(s, ++(*cur_index)))) ++ goto out; ++ *offset = 0; ++ } ++ if (*((unsigned char *) (bh->b_data + *offset)) != ++ SQUASHFS_MARKER_BYTE) { ++ ERROR("Metadata block marker corrupt @ %x\n", ++ *cur_index); ++ brelse(bh); ++ goto out; ++ } ++ (*offset)++; ++ } ++ return bh; ++ ++out: ++ return NULL; ++} ++ ++ ++SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, ++ long long index, unsigned int length, ++ long long *next_index, int srclength) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >> ++ msblk->devblksize_log2) + 2]; ++ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1); ++ unsigned int cur_index = index >> msblk->devblksize_log2; ++ int bytes, avail_bytes, b = 0, k = 0; ++ unsigned int compressed; ++ unsigned int c_byte = length; ++ ++ if (c_byte) { ++ bytes = msblk->devblksize - offset; ++ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte); ++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); ++ ++ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed ++ ? "" : "un", (unsigned int) c_byte, srclength); ++ ++ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) ++ goto read_failure; ++ ++ if (!(bh[0] = sb_getblk(s, cur_index))) ++ goto block_release; ++ ++ for (b = 1; bytes < c_byte; b++) { ++ if (!(bh[b] = sb_getblk(s, ++cur_index))) ++ goto block_release; ++ bytes += msblk->devblksize; ++ } ++ ll_rw_block(READ, b, bh); ++ } else { ++ if (index < 0 || (index + 2) > sblk->bytes_used) ++ goto read_failure; ++ ++ if (!(bh[0] = get_block_length(s, &cur_index, &offset, ++ &c_byte))) ++ goto read_failure; ++ ++ bytes = msblk->devblksize - offset; ++ compressed = SQUASHFS_COMPRESSED(c_byte); ++ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); ++ ++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed ++ ? "" : "un", (unsigned int) c_byte); ++ ++ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) ++ goto read_failure; ++ ++ for (b = 1; bytes < c_byte; b++) { ++ if (!(bh[b] = sb_getblk(s, ++cur_index))) ++ goto block_release; ++ bytes += msblk->devblksize; ++ } ++ ll_rw_block(READ, b - 1, bh + 1); ++ } ++ ++ if (compressed) { ++ int zlib_err = 0; ++ ++ /* ++ * uncompress block ++ */ ++ ++ mutex_lock(&msblk->read_data_mutex); ++ ++ msblk->stream.next_out = buffer; ++ msblk->stream.avail_out = srclength; ++ ++ for (bytes = 0; k < b; k++) { ++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ? ++ msblk->devblksize - offset : ++ c_byte - bytes; ++ wait_on_buffer(bh[k]); ++ if (!buffer_uptodate(bh[k])) ++ goto release_mutex; ++ ++ msblk->stream.next_in = bh[k]->b_data + offset; ++ msblk->stream.avail_in = avail_bytes; ++ ++ if (k == 0) { ++ zlib_err = zlib_inflateInit(&msblk->stream); ++ if (zlib_err != Z_OK) { ++ ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n", ++ zlib_err, srclength); ++ goto release_mutex; ++ } ++ ++ if (avail_bytes == 0) { ++ offset = 0; ++ brelse(bh[k]); ++ continue; ++ } ++ } ++ ++ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); ++ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { ++ ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n", ++ zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out); ++ goto release_mutex; ++ } ++ ++ bytes += avail_bytes; ++ offset = 0; ++ brelse(bh[k]); ++ } ++ ++ if (zlib_err != Z_STREAM_END) ++ goto release_mutex; ++ ++ zlib_err = zlib_inflateEnd(&msblk->stream); ++ if (zlib_err != Z_OK) { ++ ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n", ++ zlib_err, srclength); ++ goto release_mutex; ++ } ++ bytes = msblk->stream.total_out; ++ mutex_unlock(&msblk->read_data_mutex); ++ } else { ++ int i; ++ ++ for(i = 0; i < b; i++) { ++ wait_on_buffer(bh[i]); ++ if(!buffer_uptodate(bh[i])) ++ goto block_release; ++ } ++ ++ for (bytes = 0; k < b; k++) { ++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ? ++ msblk->devblksize - offset : ++ c_byte - bytes; ++ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes); ++ bytes += avail_bytes; ++ offset = 0; ++ brelse(bh[k]); ++ } ++ } ++ ++ if (next_index) ++ *next_index = index + c_byte + (length ? 0 : ++ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ++ ? 3 : 2)); ++ return bytes; ++ ++release_mutex: ++ mutex_unlock(&msblk->read_data_mutex); ++ ++block_release: ++ for (; k < b; k++) ++ brelse(bh[k]); ++ ++read_failure: ++ ERROR("sb_bread failed reading block 0x%x\n", cur_index); ++ return 0; ++} ++ ++ ++SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer, ++ long long block, unsigned int offset, ++ int length, long long *next_block, ++ unsigned int *next_offset) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ int n, i, bytes, return_length = length; ++ long long next_index; ++ ++ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset); ++ ++ while ( 1 ) { ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ if (msblk->block_cache[i].block == block) ++ break; ++ ++ mutex_lock(&msblk->block_cache_mutex); ++ ++ if (i == SQUASHFS_CACHED_BLKS) { ++ /* read inode header block */ ++ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS; ++ n ; n --, i = (i + 1) % ++ SQUASHFS_CACHED_BLKS) ++ if (msblk->block_cache[i].block != ++ SQUASHFS_USED_BLK) ++ break; ++ ++ if (n == 0) { ++ wait_queue_t wait; ++ ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&msblk->waitq, &wait); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ mutex_unlock(&msblk->block_cache_mutex); ++ schedule(); ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&msblk->waitq, &wait); ++ continue; ++ } ++ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS; ++ ++ if (msblk->block_cache[i].block == ++ SQUASHFS_INVALID_BLK) { ++ if (!(msblk->block_cache[i].data = ++ kmalloc(SQUASHFS_METADATA_SIZE, ++ GFP_KERNEL))) { ++ ERROR("Failed to allocate cache" ++ "block\n"); ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto out; ++ } ++ } ++ ++ msblk->block_cache[i].block = SQUASHFS_USED_BLK; ++ mutex_unlock(&msblk->block_cache_mutex); ++ ++ msblk->block_cache[i].length = squashfs_read_data(s, ++ msblk->block_cache[i].data, block, 0, &next_index, SQUASHFS_METADATA_SIZE); ++ if (msblk->block_cache[i].length == 0) { ++ ERROR("Unable to read cache block [%llx:%x]\n", ++ block, offset); ++ mutex_lock(&msblk->block_cache_mutex); ++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; ++ kfree(msblk->block_cache[i].data); ++ wake_up(&msblk->waitq); ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto out; ++ } ++ ++ mutex_lock(&msblk->block_cache_mutex); ++ wake_up(&msblk->waitq); ++ msblk->block_cache[i].block = block; ++ msblk->block_cache[i].next_index = next_index; ++ TRACE("Read cache block [%llx:%x]\n", block, offset); ++ } ++ ++ if (msblk->block_cache[i].block != block) { ++ mutex_unlock(&msblk->block_cache_mutex); ++ continue; ++ } ++ ++ bytes = msblk->block_cache[i].length - offset; ++ ++ if (bytes < 1) { ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto out; ++ } else if (bytes >= length) { ++ if (buffer) ++ memcpy(buffer, msblk->block_cache[i].data + ++ offset, length); ++ if (msblk->block_cache[i].length - offset == length) { ++ *next_block = msblk->block_cache[i].next_index; ++ *next_offset = 0; ++ } else { ++ *next_block = block; ++ *next_offset = offset + length; ++ } ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto finish; ++ } else { ++ if (buffer) { ++ memcpy(buffer, msblk->block_cache[i].data + ++ offset, bytes); ++ buffer += bytes; ++ } ++ block = msblk->block_cache[i].next_index; ++ mutex_unlock(&msblk->block_cache_mutex); ++ length -= bytes; ++ offset = 0; ++ } ++ } ++ ++finish: ++ return return_length; ++out: ++ return 0; ++} ++ ++ ++static int get_fragment_location(struct super_block *s, unsigned int fragment, ++ long long *fragment_start_block, ++ unsigned int *fragment_size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ long long start_block = ++ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); ++ struct squashfs_fragment_entry fragment_entry; ++ ++ if (msblk->swap) { ++ struct squashfs_fragment_entry sfragment_entry; ++ ++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, ++ start_block, offset, ++ sizeof(sfragment_entry), &start_block, ++ &offset)) ++ goto out; ++ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, ++ start_block, offset, ++ sizeof(fragment_entry), &start_block, ++ &offset)) ++ goto out; ++ ++ *fragment_start_block = fragment_entry.start_block; ++ *fragment_size = fragment_entry.size; ++ ++ return 1; ++ ++out: ++ return 0; ++} ++ ++ ++SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct ++ squashfs_fragment_cache *fragment) ++{ ++ mutex_lock(&msblk->fragment_mutex); ++ fragment->locked --; ++ wake_up(&msblk->fragment_wait_queue); ++ mutex_unlock(&msblk->fragment_mutex); ++} ++ ++ ++SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block ++ *s, long long start_block, ++ int length) ++{ ++ int i, n; ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ while ( 1 ) { ++ mutex_lock(&msblk->fragment_mutex); ++ ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS && ++ msblk->fragment[i].block != start_block; i++); ++ ++ if (i == SQUASHFS_CACHED_FRAGMENTS) { ++ for (i = msblk->next_fragment, n = ++ SQUASHFS_CACHED_FRAGMENTS; n && ++ msblk->fragment[i].locked; n--, i = (i + 1) % ++ SQUASHFS_CACHED_FRAGMENTS); ++ ++ if (n == 0) { ++ wait_queue_t wait; ++ ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&msblk->fragment_wait_queue, ++ &wait); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ mutex_unlock(&msblk->fragment_mutex); ++ schedule(); ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&msblk->fragment_wait_queue, ++ &wait); ++ continue; ++ } ++ msblk->next_fragment = (msblk->next_fragment + 1) % ++ SQUASHFS_CACHED_FRAGMENTS; ++ ++ if (msblk->fragment[i].data == NULL) ++ if (!(msblk->fragment[i].data = SQUASHFS_ALLOC ++ (SQUASHFS_FILE_MAX_SIZE))) { ++ ERROR("Failed to allocate fragment " ++ "cache block\n"); ++ mutex_unlock(&msblk->fragment_mutex); ++ goto out; ++ } ++ ++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK; ++ msblk->fragment[i].locked = 1; ++ mutex_unlock(&msblk->fragment_mutex); ++ ++ if (!(msblk->fragment[i].length = squashfs_read_data(s, ++ msblk->fragment[i].data, ++ start_block, length, NULL, sblk->block_size))) { ++ ERROR("Unable to read fragment cache block " ++ "[%llx]\n", start_block); ++ msblk->fragment[i].locked = 0; ++ smp_mb(); ++ goto out; ++ } ++ ++ mutex_lock(&msblk->fragment_mutex); ++ msblk->fragment[i].block = start_block; ++ TRACE("New fragment %d, start block %lld, locked %d\n", ++ i, msblk->fragment[i].block, ++ msblk->fragment[i].locked); ++ mutex_unlock(&msblk->fragment_mutex); ++ break; ++ } ++ ++ msblk->fragment[i].locked++; ++ mutex_unlock(&msblk->fragment_mutex); ++ TRACE("Got fragment %d, start block %lld, locked %d\n", i, ++ msblk->fragment[i].block, ++ msblk->fragment[i].locked); ++ break; ++ } ++ ++ return &msblk->fragment[i]; ++ ++out: ++ return NULL; ++} ++ ++ ++static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, ++ struct squashfs_base_inode_header *inodeb) ++{ ++ i->i_ino = inodeb->inode_number; ++ i->i_mtime.tv_sec = inodeb->mtime; ++ i->i_atime.tv_sec = inodeb->mtime; ++ i->i_ctime.tv_sec = inodeb->mtime; ++ i->i_uid = msblk->uid[inodeb->uid]; ++ i->i_mode = inodeb->mode; ++ i->i_size = 0; ++ if (inodeb->guid == SQUASHFS_GUIDS) ++ i->i_gid = i->i_uid; ++ else ++ i->i_gid = msblk->guid[inodeb->guid]; ++} ++ ++ ++static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)]; ++ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1); ++ squashfs_inode_t inode; ++ ++ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino); ++ ++ if (msblk->swap) { ++ squashfs_inode_t sinode; ++ ++ if (!squashfs_get_cached_block(s, (char *) &sinode, start, offset, ++ sizeof(sinode), &start, &offset)) ++ goto out; ++ SQUASHFS_SWAP_INODE_T((&inode), &sinode); ++ } else if (!squashfs_get_cached_block(s, (char *) &inode, start, offset, ++ sizeof(inode), &start, &offset)) ++ goto out; ++ ++ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode); ++ ++ return inode; ++ ++out: ++ return SQUASHFS_INVALID_BLK; ++} ++ ++ ++static void vfs_read_inode(struct inode *i) ++{ ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino); ++ ++ TRACE("Entered vfs_read_inode\n"); ++ ++ if(inode != SQUASHFS_INVALID_BLK) ++ (msblk->read_inode)(i, inode); ++} ++ ++ ++static struct dentry *squashfs_get_parent(struct dentry *child) ++{ ++ struct inode *i = child->d_inode; ++ struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode); ++ struct dentry *rv; ++ ++ TRACE("Entered squashfs_get_parent\n"); ++ ++ if(parent == NULL) { ++ rv = ERR_PTR(-EACCES); ++ goto out; ++ } ++ ++ rv = d_alloc_anon(parent); ++ if(rv == NULL) ++ rv = ERR_PTR(-ENOMEM); ++ ++out: ++ return rv; ++} ++ ++ ++SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct inode *i = iget_locked(s, inode_number); ++ ++ TRACE("Entered squashfs_iget\n"); ++ ++ if(i && (i->i_state & I_NEW)) { ++ (msblk->read_inode)(i, inode); ++ unlock_new_inode(i); ++ } ++ ++ return i; ++} ++ ++ ++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode) ++{ ++ struct super_block *s = i->i_sb; ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long block = SQUASHFS_INODE_BLK(inode) + ++ sblk->inode_table_start; ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); ++ long long next_block; ++ unsigned int next_offset; ++ union squashfs_inode_header id, sid; ++ struct squashfs_base_inode_header *inodeb = &id.base, ++ *sinodeb = &sid.base; ++ ++ TRACE("Entered squashfs_read_inode\n"); ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, ++ offset, sizeof(*sinodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, ++ sizeof(*sinodeb)); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) inodeb, block, ++ offset, sizeof(*inodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ squashfs_new_inode(msblk, i, inodeb); ++ ++ switch(inodeb->inode_type) { ++ case SQUASHFS_FILE_TYPE: { ++ unsigned int frag_size; ++ long long frag_blk; ++ struct squashfs_reg_inode_header *inodep = &id.reg; ++ struct squashfs_reg_inode_header *sinodep = &sid.reg; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ frag_blk = SQUASHFS_INVALID_BLK; ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG && ++ !get_fragment_location(s, ++ inodep->fragment, &frag_blk, &frag_size)) ++ goto failed_read; ++ ++ i->i_nlink = 1; ++ i->i_size = inodep->file_size; ++ i->i_fop = &generic_ro_fops; ++ i->i_mode |= S_IFREG; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ if (sblk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ ++ TRACE("File inode %x:%x, start_block %llx, " ++ "block_list_start %llx, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, next_block, ++ next_offset); ++ break; ++ } ++ case SQUASHFS_LREG_TYPE: { ++ unsigned int frag_size; ++ long long frag_blk; ++ struct squashfs_lreg_inode_header *inodep = &id.lreg; ++ struct squashfs_lreg_inode_header *sinodep = &sid.lreg; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ frag_blk = SQUASHFS_INVALID_BLK; ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG && ++ !get_fragment_location(s, ++ inodep->fragment, &frag_blk, &frag_size)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->file_size; ++ i->i_fop = &generic_ro_fops; ++ i->i_mode |= S_IFREG; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ if (sblk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ ++ TRACE("File inode %x:%x, start_block %llx, " ++ "block_list_start %llx, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, next_block, ++ next_offset); ++ break; ++ } ++ case SQUASHFS_DIR_TYPE: { ++ struct squashfs_dir_inode_header *inodep = &id.dir; ++ struct squashfs_dir_inode_header *sinodep = &sid.dir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops; ++ i->i_fop = &squashfs_dir_ops; ++ i->i_mode |= S_IFDIR; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = 0; ++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; ++ ++ TRACE("Directory inode %x:%x, start_block %x, offset " ++ "%x\n", SQUASHFS_INODE_BLK(inode), ++ offset, inodep->start_block, ++ inodep->offset); ++ break; ++ } ++ case SQUASHFS_LDIR_TYPE: { ++ struct squashfs_ldir_inode_header *inodep = &id.ldir; ++ struct squashfs_ldir_inode_header *sinodep = &sid.ldir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops; ++ i->i_fop = &squashfs_dir_ops; ++ i->i_mode |= S_IFDIR; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; ++ SQUASHFS_I(i)->u.s2.directory_index_offset = ++ next_offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = ++ inodep->i_count; ++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; ++ ++ TRACE("Long directory inode %x:%x, start_block %x, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, inodep->offset); ++ break; ++ } ++ case SQUASHFS_SYMLINK_TYPE: { ++ struct squashfs_symlink_inode_header *inodep = ++ &id.symlink; ++ struct squashfs_symlink_inode_header *sinodep = ++ &sid.symlink; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->symlink_size; ++ i->i_op = &page_symlink_inode_operations; ++ i->i_data.a_ops = &squashfs_symlink_aops; ++ i->i_mode |= S_IFLNK; ++ SQUASHFS_I(i)->start_block = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ ++ TRACE("Symbolic link inode %x:%x, start_block %llx, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_BLKDEV_TYPE: ++ case SQUASHFS_CHRDEV_TYPE: { ++ struct squashfs_dev_inode_header *inodep = &id.dev; ++ struct squashfs_dev_inode_header *sinodep = &sid.dev; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_mode |= (inodeb->inode_type == ++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : ++ S_IFBLK; ++ init_special_inode(i, i->i_mode, ++ old_decode_dev(inodep->rdev)); ++ ++ TRACE("Device inode %x:%x, rdev %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->rdev); ++ break; ++ } ++ case SQUASHFS_FIFO_TYPE: ++ case SQUASHFS_SOCKET_TYPE: { ++ struct squashfs_ipc_inode_header *inodep = &id.ipc; ++ struct squashfs_ipc_inode_header *sinodep = &sid.ipc; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) ++ ? S_IFIFO : S_IFSOCK; ++ init_special_inode(i, i->i_mode, 0); ++ break; ++ } ++ default: ++ ERROR("Unknown inode type %d in squashfs_iget!\n", ++ inodeb->inode_type); ++ goto failed_read1; ++ } ++ ++ return 1; ++ ++failed_read: ++ ERROR("Unable to read inode [%llx:%x]\n", block, offset); ++ ++failed_read1: ++ make_bad_inode(i); ++ return 0; ++} ++ ++ ++static int read_inode_lookup_table(struct super_block *s) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes); ++ ++ TRACE("In read_inode_lookup_table, length %d\n", length); ++ ++ /* Allocate inode lookup table */ ++ if (!(msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL))) { ++ ERROR("Failed to allocate inode lookup table\n"); ++ return 0; ++ } ++ ++ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table, ++ sblk->lookup_table_start, length | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { ++ ERROR("unable to read inode lookup table\n"); ++ return 0; ++ } ++ ++ if (msblk->swap) { ++ int i; ++ long long block; ++ ++ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) { ++ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block), ++ &msblk->inode_lookup_table[i], 1); ++ msblk->inode_lookup_table[i] = block; ++ } ++ } ++ ++ return 1; ++} ++ ++ ++static int read_fragment_index_table(struct super_block *s) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments); ++ ++ if(length == 0) ++ return 1; ++ ++ /* Allocate fragment index table */ ++ if (!(msblk->fragment_index = kmalloc(length, GFP_KERNEL))) { ++ ERROR("Failed to allocate fragment index table\n"); ++ return 0; ++ } ++ ++ if (!squashfs_read_data(s, (char *) msblk->fragment_index, ++ sblk->fragment_table_start, length | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { ++ ERROR("unable to read fragment index table\n"); ++ return 0; ++ } ++ ++ if (msblk->swap) { ++ int i; ++ long long fragment; ++ ++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) { ++ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), ++ &msblk->fragment_index[i], 1); ++ msblk->fragment_index[i] = fragment; ++ } ++ } ++ ++ return 1; ++} ++ ++ ++static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent) ++{ ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ msblk->read_inode = squashfs_read_inode; ++ msblk->read_blocklist = read_blocklist; ++ msblk->read_fragment_index_table = read_fragment_index_table; ++ ++ if (sblk->s_major == 1) { ++ if (!squashfs_1_0_supported(msblk)) { ++ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems " ++ "are unsupported\n"); ++ SERROR("Please recompile with " ++ "Squashfs 1.0 support enabled\n"); ++ return 0; ++ } ++ } else if (sblk->s_major == 2) { ++ if (!squashfs_2_0_supported(msblk)) { ++ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems " ++ "are unsupported\n"); ++ SERROR("Please recompile with " ++ "Squashfs 2.0 support enabled\n"); ++ return 0; ++ } ++ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor > ++ SQUASHFS_MINOR) { ++ SERROR("Major/Minor mismatch, trying to mount newer %d.%d " ++ "filesystem\n", sblk->s_major, sblk->s_minor); ++ SERROR("Please update your kernel\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++ ++static int squashfs_fill_super(struct super_block *s, void *data, int silent) ++{ ++ struct squashfs_sb_info *msblk; ++ struct squashfs_super_block *sblk; ++ int i; ++ char b[BDEVNAME_SIZE]; ++ struct inode *root; ++ ++ TRACE("Entered squashfs_read_superblock\n"); ++ ++ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info), ++ GFP_KERNEL))) { ++ ERROR("Failed to allocate superblock\n"); ++ goto failure; ++ } ++ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info)); ++ msblk = s->s_fs_info; ++ if (!(msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()))) { ++ ERROR("Failed to allocate zlib workspace\n"); ++ goto failure; ++ } ++ sblk = &msblk->sblk; ++ ++ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); ++ msblk->devblksize_log2 = ffz(~msblk->devblksize); ++ ++ mutex_init(&msblk->read_data_mutex); ++ mutex_init(&msblk->read_page_mutex); ++ mutex_init(&msblk->block_cache_mutex); ++ mutex_init(&msblk->fragment_mutex); ++ mutex_init(&msblk->meta_index_mutex); ++ ++ init_waitqueue_head(&msblk->waitq); ++ init_waitqueue_head(&msblk->fragment_wait_queue); ++ ++ sblk->bytes_used = sizeof(struct squashfs_super_block); ++ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, ++ sizeof(struct squashfs_super_block) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) { ++ SERROR("unable to read superblock\n"); ++ goto failed_mount; ++ } ++ ++ /* Check it is a SQUASHFS superblock */ ++ msblk->swap = 0; ++ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { ++ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { ++ struct squashfs_super_block ssblk; ++ ++ WARNING("Mounting a different endian SQUASHFS " ++ "filesystem on %s\n", bdevname(s->s_bdev, b)); ++ ++ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); ++ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); ++ msblk->swap = 1; ++ } else { ++ SERROR("Can't find a SQUASHFS superblock on %s\n", ++ bdevname(s->s_bdev, b)); ++ goto failed_mount; ++ } ++ } ++ ++ /* Check the MAJOR & MINOR versions */ ++ if(!supported_squashfs_filesystem(msblk, silent)) ++ goto failed_mount; ++ ++ /* Check the filesystem does not extend beyond the end of the ++ block device */ ++ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) ++ goto failed_mount; ++ ++ /* Check the root inode for sanity */ ++ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) ++ goto failed_mount; ++ ++ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); ++ TRACE("Inodes are %scompressed\n", ++ SQUASHFS_UNCOMPRESSED_INODES ++ (sblk->flags) ? "un" : ""); ++ TRACE("Data is %scompressed\n", ++ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags) ++ ? "un" : ""); ++ TRACE("Check data is %s present in the filesystem\n", ++ SQUASHFS_CHECK_DATA(sblk->flags) ? ++ "" : "not"); ++ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used); ++ TRACE("Block size %d\n", sblk->block_size); ++ TRACE("Number of inodes %d\n", sblk->inodes); ++ if (sblk->s_major > 1) ++ TRACE("Number of fragments %d\n", sblk->fragments); ++ TRACE("Number of uids %d\n", sblk->no_uids); ++ TRACE("Number of gids %d\n", sblk->no_guids); ++ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start); ++ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start); ++ if (sblk->s_major > 1) ++ TRACE("sblk->fragment_table_start %llx\n", ++ sblk->fragment_table_start); ++ TRACE("sblk->uid_start %llx\n", sblk->uid_start); ++ ++ s->s_flags |= MS_RDONLY; ++ s->s_op = &squashfs_super_ops; ++ ++ /* Init inode_table block pointer array */ ++ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) * ++ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) { ++ ERROR("Failed to allocate block cache\n"); ++ goto failed_mount; ++ } ++ ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; ++ ++ msblk->next_cache = 0; ++ ++ /* Allocate read_page block */ ++ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) { ++ ERROR("Failed to allocate read_page block\n"); ++ goto failed_mount; ++ } ++ ++ /* Allocate uid and gid tables */ ++ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) * ++ sizeof(unsigned int), GFP_KERNEL))) { ++ ERROR("Failed to allocate uid/gid table\n"); ++ goto failed_mount; ++ } ++ msblk->guid = msblk->uid + sblk->no_uids; ++ ++ if (msblk->swap) { ++ unsigned int suid[sblk->no_uids + sblk->no_guids]; ++ ++ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, ++ ((sblk->no_uids + sblk->no_guids) * ++ sizeof(unsigned int)) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { ++ ERROR("unable to read uid/gid table\n"); ++ goto failed_mount; ++ } ++ ++ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + ++ sblk->no_guids), (sizeof(unsigned int) * 8)); ++ } else ++ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, ++ ((sblk->no_uids + sblk->no_guids) * ++ sizeof(unsigned int)) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { ++ ERROR("unable to read uid/gid table\n"); ++ goto failed_mount; ++ } ++ ++ ++ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) ++ goto allocate_root; ++ ++ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) * ++ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) { ++ ERROR("Failed to allocate fragment block cache\n"); ++ goto failed_mount; ++ } ++ ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { ++ msblk->fragment[i].locked = 0; ++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK; ++ msblk->fragment[i].data = NULL; ++ } ++ ++ msblk->next_fragment = 0; ++ ++ /* Allocate and read fragment index table */ ++ if (msblk->read_fragment_index_table(s) == 0) ++ goto failed_mount; ++ ++ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK) ++ goto allocate_root; ++ ++ /* Allocate and read inode lookup table */ ++ if (read_inode_lookup_table(s) == 0) ++ goto failed_mount; ++ ++ s->s_op = &squashfs_export_super_ops; ++ s->s_export_op = &squashfs_export_ops; ++ ++allocate_root: ++ root = new_inode(s); ++ if ((msblk->read_inode)(root, sblk->root_inode) == 0) ++ goto failed_mount; ++ insert_inode_hash(root); ++ ++ if ((s->s_root = d_alloc_root(root)) == NULL) { ++ ERROR("Root inode create failed\n"); ++ iput(root); ++ goto failed_mount; ++ } ++ ++ TRACE("Leaving squashfs_read_super\n"); ++ return 0; ++ ++failed_mount: ++ kfree(msblk->inode_lookup_table); ++ kfree(msblk->fragment_index); ++ kfree(msblk->fragment); ++ kfree(msblk->uid); ++ kfree(msblk->read_page); ++ kfree(msblk->block_cache); ++ kfree(msblk->fragment_index_2); ++ vfree(msblk->stream.workspace); ++ kfree(s->s_fs_info); ++ s->s_fs_info = NULL; ++ return -EINVAL; ++ ++failure: ++ return -ENOMEM; ++} ++ ++ ++static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ TRACE("Entered squashfs_statfs\n"); ++ ++ buf->f_type = SQUASHFS_MAGIC; ++ buf->f_bsize = sblk->block_size; ++ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; ++ buf->f_bfree = buf->f_bavail = 0; ++ buf->f_files = sblk->inodes; ++ buf->f_ffree = 0; ++ buf->f_namelen = SQUASHFS_NAME_LEN; ++ ++ return 0; ++} ++ ++ ++static int squashfs_symlink_readpage(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ int index = page->index << PAGE_CACHE_SHIFT, length, bytes; ++ long long block = SQUASHFS_I(inode)->start_block; ++ int offset = SQUASHFS_I(inode)->offset; ++ void *pageaddr = kmap(page); ++ ++ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " ++ "%llx, offset %x\n", page->index, ++ SQUASHFS_I(inode)->start_block, ++ SQUASHFS_I(inode)->offset); ++ ++ for (length = 0; length < index; length += bytes) { ++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL, ++ block, offset, PAGE_CACHE_SIZE, &block, ++ &offset))) { ++ ERROR("Unable to read symbolic link [%llx:%x]\n", block, ++ offset); ++ goto skip_read; ++ } ++ } ++ ++ if (length != index) { ++ ERROR("(squashfs_symlink_readpage) length != index\n"); ++ bytes = 0; ++ goto skip_read; ++ } ++ ++ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : ++ i_size_read(inode) - length; ++ ++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, ++ offset, bytes, &block, &offset))) ++ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); ++ ++skip_read: ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ return 0; ++} ++ ++ ++struct meta_index *locate_meta_index(struct inode *inode, int index, int offset) ++{ ++ struct meta_index *meta = NULL; ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ int i; ++ ++ mutex_lock(&msblk->meta_index_mutex); ++ ++ TRACE("locate_meta_index: index %d, offset %d\n", index, offset); ++ ++ if(msblk->meta_index == NULL) ++ goto not_allocated; ++ ++ for (i = 0; i < SQUASHFS_META_NUMBER; i ++) ++ if (msblk->meta_index[i].inode_number == inode->i_ino && ++ msblk->meta_index[i].offset >= offset && ++ msblk->meta_index[i].offset <= index && ++ msblk->meta_index[i].locked == 0) { ++ TRACE("locate_meta_index: entry %d, offset %d\n", i, ++ msblk->meta_index[i].offset); ++ meta = &msblk->meta_index[i]; ++ offset = meta->offset; ++ } ++ ++ if (meta) ++ meta->locked = 1; ++ ++not_allocated: ++ mutex_unlock(&msblk->meta_index_mutex); ++ ++ return meta; ++} ++ ++ ++struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip) ++{ ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct meta_index *meta = NULL; ++ int i; ++ ++ mutex_lock(&msblk->meta_index_mutex); ++ ++ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip); ++ ++ if(msblk->meta_index == NULL) { ++ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) * ++ SQUASHFS_META_NUMBER, GFP_KERNEL))) { ++ ERROR("Failed to allocate meta_index\n"); ++ goto failed; ++ } ++ for(i = 0; i < SQUASHFS_META_NUMBER; i++) { ++ msblk->meta_index[i].inode_number = 0; ++ msblk->meta_index[i].locked = 0; ++ } ++ msblk->next_meta_index = 0; ++ } ++ ++ for(i = SQUASHFS_META_NUMBER; i && ++ msblk->meta_index[msblk->next_meta_index].locked; i --) ++ msblk->next_meta_index = (msblk->next_meta_index + 1) % ++ SQUASHFS_META_NUMBER; ++ ++ if(i == 0) { ++ TRACE("empty_meta_index: failed!\n"); ++ goto failed; ++ } ++ ++ TRACE("empty_meta_index: returned meta entry %d, %p\n", ++ msblk->next_meta_index, ++ &msblk->meta_index[msblk->next_meta_index]); ++ ++ meta = &msblk->meta_index[msblk->next_meta_index]; ++ msblk->next_meta_index = (msblk->next_meta_index + 1) % ++ SQUASHFS_META_NUMBER; ++ ++ meta->inode_number = inode->i_ino; ++ meta->offset = offset; ++ meta->skip = skip; ++ meta->entries = 0; ++ meta->locked = 1; ++ ++failed: ++ mutex_unlock(&msblk->meta_index_mutex); ++ return meta; ++} ++ ++ ++void release_meta_index(struct inode *inode, struct meta_index *meta) ++{ ++ meta->locked = 0; ++ smp_mb(); ++} ++ ++ ++static int read_block_index(struct super_block *s, int blocks, char *block_list, ++ long long *start_block, int *offset) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ unsigned int *block_listp; ++ int block = 0; ++ ++ if (msblk->swap) { ++ char sblock_list[blocks << 2]; ++ ++ if (!squashfs_get_cached_block(s, sblock_list, *start_block, ++ *offset, blocks << 2, start_block, offset)) { ++ ERROR("Unable to read block list [%llx:%x]\n", ++ *start_block, *offset); ++ goto failure; ++ } ++ SQUASHFS_SWAP_INTS(((unsigned int *)block_list), ++ ((unsigned int *)sblock_list), blocks); ++ } else ++ if (!squashfs_get_cached_block(s, block_list, *start_block, ++ *offset, blocks << 2, start_block, offset)) { ++ ERROR("Unable to read block list [%llx:%x]\n", ++ *start_block, *offset); ++ goto failure; ++ } ++ ++ for (block_listp = (unsigned int *) block_list; blocks; ++ block_listp++, blocks --) ++ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); ++ ++ return block; ++ ++failure: ++ return -1; ++} ++ ++ ++#define SIZE 256 ++ ++static inline int calculate_skip(int blocks) { ++ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES); ++ return skip >= 7 ? 7 : skip + 1; ++} ++ ++ ++static int get_meta_index(struct inode *inode, int index, ++ long long *index_block, int *index_offset, ++ long long *data_block, char *block_list) ++{ ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log); ++ int offset = 0; ++ struct meta_index *meta; ++ struct meta_entry *meta_entry; ++ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start; ++ int cur_offset = SQUASHFS_I(inode)->offset; ++ long long cur_data_block = SQUASHFS_I(inode)->start_block; ++ int i; ++ ++ index /= SQUASHFS_META_INDEXES * skip; ++ ++ while ( offset < index ) { ++ meta = locate_meta_index(inode, index, offset + 1); ++ ++ if (meta == NULL) { ++ if ((meta = empty_meta_index(inode, offset + 1, ++ skip)) == NULL) ++ goto all_done; ++ } else { ++ if(meta->entries == 0) ++ goto failed; ++ offset = index < meta->offset + meta->entries ? index : ++ meta->offset + meta->entries - 1; ++ meta_entry = &meta->meta_entry[offset - meta->offset]; ++ cur_index_block = meta_entry->index_block + sblk->inode_table_start; ++ cur_offset = meta_entry->offset; ++ cur_data_block = meta_entry->data_block; ++ TRACE("get_meta_index: offset %d, meta->offset %d, " ++ "meta->entries %d\n", offset, meta->offset, ++ meta->entries); ++ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x" ++ " data_block 0x%llx\n", cur_index_block, ++ cur_offset, cur_data_block); ++ } ++ ++ for (i = meta->offset + meta->entries; i <= index && ++ i < meta->offset + SQUASHFS_META_ENTRIES; i++) { ++ int blocks = skip * SQUASHFS_META_INDEXES; ++ ++ while (blocks) { ++ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : ++ blocks; ++ int res = read_block_index(inode->i_sb, block, ++ block_list, &cur_index_block, ++ &cur_offset); ++ ++ if (res == -1) ++ goto failed; ++ ++ cur_data_block += res; ++ blocks -= block; ++ } ++ ++ meta_entry = &meta->meta_entry[i - meta->offset]; ++ meta_entry->index_block = cur_index_block - sblk->inode_table_start; ++ meta_entry->offset = cur_offset; ++ meta_entry->data_block = cur_data_block; ++ meta->entries ++; ++ offset ++; ++ } ++ ++ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n", ++ meta->offset, meta->entries); ++ ++ release_meta_index(inode, meta); ++ } ++ ++all_done: ++ *index_block = cur_index_block; ++ *index_offset = cur_offset; ++ *data_block = cur_data_block; ++ ++ return offset * SQUASHFS_META_INDEXES * skip; ++ ++failed: ++ release_meta_index(inode, meta); ++ return -1; ++} ++ ++ ++static long long read_blocklist(struct inode *inode, int index, ++ int readahead_blks, char *block_list, ++ unsigned short **block_p, unsigned int *bsize) ++{ ++ long long block_ptr; ++ int offset; ++ long long block; ++ int res = get_meta_index(inode, index, &block_ptr, &offset, &block, ++ block_list); ++ ++ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset" ++ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, ++ block); ++ ++ if(res == -1) ++ goto failure; ++ ++ index -= res; ++ ++ while ( index ) { ++ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index; ++ int res = read_block_index(inode->i_sb, blocks, block_list, ++ &block_ptr, &offset); ++ if (res == -1) ++ goto failure; ++ block += res; ++ index -= blocks; ++ } ++ ++ if (read_block_index(inode->i_sb, 1, block_list, ++ &block_ptr, &offset) == -1) ++ goto failure; ++ *bsize = *((unsigned int *) block_list); ++ ++ return block; ++ ++failure: ++ return 0; ++} ++ ++ ++static int squashfs_readpage(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned char *block_list; ++ long long block; ++ unsigned int bsize, i = 0, bytes = 0, byte_offset = 0; ++ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT); ++ void *pageaddr; ++ struct squashfs_fragment_cache *fragment = NULL; ++ char *data_ptr = msblk->read_page; ++ ++ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1; ++ int start_index = page->index & ~mask; ++ int end_index = start_index | mask; ++ ++ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", ++ page->index, ++ SQUASHFS_I(inode)->start_block); ++ ++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) { ++ ERROR("Failed to allocate block_list\n"); ++ goto skip_read; ++ } ++ ++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> ++ PAGE_CACHE_SHIFT)) ++ goto skip_read; ++ ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK ++ || index < (i_size_read(inode) >> ++ sblk->block_log)) { ++ if ((block = (msblk->read_blocklist)(inode, index, 1, ++ block_list, NULL, &bsize)) == 0) ++ goto skip_read; ++ ++ mutex_lock(&msblk->read_page_mutex); ++ ++ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page, ++ block, bsize, NULL, sblk->block_size))) { ++ ERROR("Unable to read page, block %llx, size %x\n", block, ++ bsize); ++ mutex_unlock(&msblk->read_page_mutex); ++ goto skip_read; ++ } ++ } else { ++ if ((fragment = get_cached_fragment(inode->i_sb, ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, ++ SQUASHFS_I(inode)->u.s1.fragment_size)) ++ == NULL) { ++ ERROR("Unable to read page, block %llx, size %x\n", ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, ++ (int) SQUASHFS_I(inode)-> ++ u.s1.fragment_size); ++ goto skip_read; ++ } ++ bytes = SQUASHFS_I(inode)->u.s1.fragment_offset + ++ (i_size_read(inode) & (sblk->block_size ++ - 1)); ++ byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset; ++ data_ptr = fragment->data; ++ } ++ ++ for (i = start_index; i <= end_index && byte_offset < bytes; ++ i++, byte_offset += PAGE_CACHE_SIZE) { ++ struct page *push_page; ++ int avail = (bytes - byte_offset) > PAGE_CACHE_SIZE ? ++ PAGE_CACHE_SIZE : bytes - byte_offset; ++ ++ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n", ++ bytes, i, byte_offset, avail); ++ ++ push_page = (i == page->index) ? page : ++ grab_cache_page_nowait(page->mapping, i); ++ ++ if (!push_page) ++ continue; ++ ++ if (PageUptodate(push_page)) ++ goto skip_page; ++ ++ pageaddr = kmap_atomic(push_page, KM_USER0); ++ memcpy(pageaddr, data_ptr + byte_offset, avail); ++ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail); ++ kunmap_atomic(pageaddr, KM_USER0); ++ flush_dcache_page(push_page); ++ SetPageUptodate(push_page); ++skip_page: ++ unlock_page(push_page); ++ if(i != page->index) ++ page_cache_release(push_page); ++ } ++ ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK ++ || index < (i_size_read(inode) >> ++ sblk->block_log)) ++ mutex_unlock(&msblk->read_page_mutex); ++ else ++ release_cached_fragment(msblk, fragment); ++ ++ kfree(block_list); ++ return 0; ++ ++skip_read: ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ kfree(block_list); ++ return 0; ++} ++ ++ ++static int squashfs_readpage4K(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned char *block_list; ++ long long block; ++ unsigned int bsize, bytes = 0; ++ void *pageaddr; ++ ++ TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n", ++ page->index, ++ SQUASHFS_I(inode)->start_block); ++ ++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> ++ PAGE_CACHE_SHIFT)) { ++ block_list = NULL; ++ goto skip_read; ++ } ++ ++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) { ++ ERROR("Failed to allocate block_list\n"); ++ goto skip_read; ++ } ++ ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK ++ || page->index < (i_size_read(inode) >> ++ sblk->block_log)) { ++ block = (msblk->read_blocklist)(inode, page->index, 1, ++ block_list, NULL, &bsize); ++ if(block == 0) ++ goto skip_read; ++ ++ mutex_lock(&msblk->read_page_mutex); ++ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, ++ bsize, NULL, sblk->block_size); ++ if (bytes) { ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memcpy(pageaddr, msblk->read_page, bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ } else ++ ERROR("Unable to read page, block %llx, size %x\n", ++ block, bsize); ++ mutex_unlock(&msblk->read_page_mutex); ++ } else { ++ struct squashfs_fragment_cache *fragment = ++ get_cached_fragment(inode->i_sb, ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, ++ SQUASHFS_I(inode)-> u.s1.fragment_size); ++ if (fragment) { ++ bytes = i_size_read(inode) & (sblk->block_size - 1); ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)-> ++ u.s1.fragment_offset, bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ release_cached_fragment(msblk, fragment); ++ } else ++ ERROR("Unable to read page, block %llx, size %x\n", ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, (int) ++ SQUASHFS_I(inode)-> u.s1.fragment_size); ++ } ++ ++skip_read: ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ kfree(block_list); ++ return 0; ++} ++ ++ ++static int get_dir_index_using_offset(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ long long f_pos) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index index; ++ ++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", ++ i_count, (unsigned int) f_pos); ++ ++ f_pos =- 3; ++ if (f_pos == 0) ++ goto finish; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) &index, ++ index_start, index_offset, ++ sizeof(index), &index_start, ++ &index_offset); ++ ++ if (index.index > f_pos) ++ break; ++ ++ squashfs_get_cached_block(s, NULL, index_start, index_offset, ++ index.size + 1, &index_start, ++ &index_offset); ++ ++ length = index.index; ++ *next_block = index.start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ ++finish: ++ return length + 3; ++} ++ ++ ++static int get_dir_index_using_name(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ const char *name, int size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index *index; ++ char *str; ++ ++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); ++ ++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + ++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_index\n"); ++ goto failure; ++ } ++ ++ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1); ++ strncpy(str, name, size); ++ str[size] = '\0'; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX(index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) index, ++ index_start, index_offset, ++ sizeof(struct squashfs_dir_index), ++ &index_start, &index_offset); ++ ++ squashfs_get_cached_block(s, index->name, index_start, ++ index_offset, index->size + 1, ++ &index_start, &index_offset); ++ ++ index->name[index->size + 1] = '\0'; ++ ++ if (strcmp(index->name, str) > 0) ++ break; ++ ++ length = index->index; ++ *next_block = index->start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ kfree(str); ++failure: ++ return length + 3; ++} ++ ++ ++static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) ++{ ++ struct inode *i = file->f_dentry->d_inode; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header dirh; ++ struct squashfs_dir_entry *dire; ++ ++ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto finish; ++ } ++ ++ while(file->f_pos < 3) { ++ char *name; ++ int size, i_ino; ++ ++ if(file->f_pos == 0) { ++ name = "."; ++ size = 1; ++ i_ino = i->i_ino; ++ } else { ++ name = ".."; ++ size = 2; ++ i_ino = SQUASHFS_I(i)->u.s2.parent_inode; ++ } ++ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n", ++ (unsigned int) dirent, name, size, (int) ++ file->f_pos, i_ino, ++ squashfs_filetype_table[1]); ++ ++ if (filldir(dirent, name, size, ++ file->f_pos, i_ino, ++ squashfs_filetype_table[1]) < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ goto finish; ++ } ++ file->f_pos += size; ++ } ++ ++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, ++ file->f_pos); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header sdirh; ++ ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block, next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block, next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, ++ dire->size + 1, &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (file->f_pos >= length) ++ continue; ++ ++ dire->name[dire->size + 1] = '\0'; ++ ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n", ++ (unsigned int) dirent, dire->name, ++ dire->size + 1, (int) file->f_pos, ++ dirh.start_block, dire->offset, ++ dirh.inode_number + dire->inode_number, ++ squashfs_filetype_table[dire->type]); ++ ++ if (filldir(dirent, dire->name, dire->size + 1, ++ file->f_pos, ++ dirh.inode_number + dire->inode_number, ++ squashfs_filetype_table[dire->type]) ++ < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ goto finish; ++ } ++ file->f_pos = length; ++ } ++ } ++ ++finish: ++ kfree(dire); ++ return 0; ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ kfree(dire); ++ return 0; ++} ++ ++ ++static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ const unsigned char *name = dentry->d_name.name; ++ int len = dentry->d_name.len; ++ struct inode *inode = NULL; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header dirh; ++ struct squashfs_dir_entry *dire; ++ ++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto exit_lookup; ++ } ++ ++ if (len > SQUASHFS_NAME_LEN) ++ goto exit_lookup; ++ ++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, name, ++ len); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header sdirh; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block,next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block,next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, dire->size + 1, ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (name[0] < dire->name[0]) ++ goto exit_lookup; ++ ++ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) { ++ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, ++ dire->offset); ++ ++ TRACE("calling squashfs_iget for directory " ++ "entry %s, inode %x:%x, %d\n", name, ++ dirh.start_block, dire->offset, ++ dirh.inode_number + dire->inode_number); ++ ++ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number); ++ ++ goto exit_lookup; ++ } ++ } ++ } ++ ++exit_lookup: ++ kfree(dire); ++ if (inode) ++ return d_splice_alias(inode, dentry); ++ d_add(dentry, inode); ++ return ERR_PTR(0); ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ goto exit_lookup; ++} ++ ++ ++static int squashfs_remount(struct super_block *s, int *flags, char *data) ++{ ++ *flags |= MS_RDONLY; ++ return 0; ++} ++ ++ ++static void squashfs_put_super(struct super_block *s) ++{ ++ int i; ++ ++ if (s->s_fs_info) { ++ struct squashfs_sb_info *sbi = s->s_fs_info; ++ if (sbi->block_cache) ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ if (sbi->block_cache[i].block != ++ SQUASHFS_INVALID_BLK) ++ kfree(sbi->block_cache[i].data); ++ if (sbi->fragment) ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) ++ SQUASHFS_FREE(sbi->fragment[i].data); ++ kfree(sbi->fragment); ++ kfree(sbi->block_cache); ++ kfree(sbi->read_page); ++ kfree(sbi->uid); ++ kfree(sbi->fragment_index); ++ kfree(sbi->fragment_index_2); ++ kfree(sbi->meta_index); ++ vfree(sbi->stream.workspace); ++ kfree(s->s_fs_info); ++ s->s_fs_info = NULL; ++ } ++} ++ ++ ++static int squashfs_get_sb(struct file_system_type *fs_type, int flags, ++ const char *dev_name, void *data, ++ struct vfsmount *mnt) ++{ ++ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, ++ mnt); ++} ++ ++ ++static int __init init_squashfs_fs(void) ++{ ++ int err = init_inodecache(); ++ if (err) ++ goto out; ++ ++ printk(KERN_INFO "squashfs: version 3.2-r2 (2007/01/15) " ++ "Phillip Lougher\n"); ++ ++ if ((err = register_filesystem(&squashfs_fs_type))) ++ destroy_inodecache(); ++ ++out: ++ return err; ++} ++ ++ ++static void __exit exit_squashfs_fs(void) ++{ ++ unregister_filesystem(&squashfs_fs_type); ++ destroy_inodecache(); ++} ++ ++ ++static struct kmem_cache * squashfs_inode_cachep; ++ ++ ++static struct inode *squashfs_alloc_inode(struct super_block *sb) ++{ ++ struct squashfs_inode_info *ei; ++ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); ++ if (!ei) ++ return NULL; ++ return &ei->vfs_inode; ++} ++ ++ ++static void squashfs_destroy_inode(struct inode *inode) ++{ ++ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode)); ++} ++ ++ ++static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) ++{ ++ struct squashfs_inode_info *ei = foo; ++ ++ ++ ++ inode_init_once(&ei->vfs_inode); ++} ++ ++ ++static int __init init_inodecache(void) ++{ ++ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", ++ sizeof(struct squashfs_inode_info), ++ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, ++ init_once, NULL); ++ if (squashfs_inode_cachep == NULL) ++ return -ENOMEM; ++ return 0; ++} ++ ++ ++static void destroy_inodecache(void) ++{ ++ kmem_cache_destroy(squashfs_inode_cachep); ++} ++ ++ ++module_init(init_squashfs_fs); ++module_exit(exit_squashfs_fs); ++MODULE_DESCRIPTION("squashfs 3.2-r2, a compressed read-only filesystem"); ++MODULE_AUTHOR("Phillip Lougher <phillip@lougher.org.uk>"); ++MODULE_LICENSE("GPL"); +diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/Makefile linux-2.6.20-squashfs3.2-r2/fs/squashfs/Makefile +--- linux-2.6.20/fs/squashfs/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/Makefile 2007-01-12 00:06:09.000000000 +0000 +@@ -0,0 +1,7 @@ ++# ++# Makefile for the linux squashfs routines. ++# ++ ++obj-$(CONFIG_SQUASHFS) += squashfs.o ++squashfs-y += inode.o ++squashfs-y += squashfs2_0.o +diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/squashfs2_0.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs2_0.c +--- linux-2.6.20/fs/squashfs/squashfs2_0.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs2_0.c 2007-01-12 02:27:20.000000000 +0000 +@@ -0,0 +1,742 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs2_0.c ++ */ ++ ++#include <linux/squashfs_fs.h> ++#include <linux/module.h> ++#include <linux/zlib.h> ++#include <linux/fs.h> ++#include <linux/squashfs_fs_sb.h> ++#include <linux/squashfs_fs_i.h> ++ ++#include "squashfs.h" ++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir); ++static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *, ++ struct nameidata *); ++ ++static struct file_operations squashfs_dir_ops_2 = { ++ .read = generic_read_dir, ++ .readdir = squashfs_readdir_2 ++}; ++ ++static struct inode_operations squashfs_dir_inode_ops_2 = { ++ .lookup = squashfs_lookup_2 ++}; ++ ++static unsigned char squashfs_filetype_table[] = { ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK ++}; ++ ++static int read_fragment_index_table_2(struct super_block *s) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2 ++ (sblk->fragments), GFP_KERNEL))) { ++ ERROR("Failed to allocate uid/gid table\n"); ++ return 0; ++ } ++ ++ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && ++ !squashfs_read_data(s, (char *) ++ msblk->fragment_index_2, ++ sblk->fragment_table_start, ++ SQUASHFS_FRAGMENT_INDEX_BYTES_2 ++ (sblk->fragments) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { ++ ERROR("unable to read fragment index table\n"); ++ return 0; ++ } ++ ++ if (msblk->swap) { ++ int i; ++ unsigned int fragment; ++ ++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments); ++ i++) { ++ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment), ++ &msblk->fragment_index_2[i], 1); ++ msblk->fragment_index_2[i] = fragment; ++ } ++ } ++ ++ return 1; ++} ++ ++ ++static int get_fragment_location_2(struct super_block *s, unsigned int fragment, ++ long long *fragment_start_block, ++ unsigned int *fragment_size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ long long start_block = ++ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)]; ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment); ++ struct squashfs_fragment_entry_2 fragment_entry; ++ ++ if (msblk->swap) { ++ struct squashfs_fragment_entry_2 sfragment_entry; ++ ++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, ++ start_block, offset, ++ sizeof(sfragment_entry), &start_block, ++ &offset)) ++ goto out; ++ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, ++ start_block, offset, ++ sizeof(fragment_entry), &start_block, ++ &offset)) ++ goto out; ++ ++ *fragment_start_block = fragment_entry.start_block; ++ *fragment_size = fragment_entry.size; ++ ++ return 1; ++ ++out: ++ return 0; ++} ++ ++ ++static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, ++ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) ++{ ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ i->i_ino = ino; ++ i->i_mtime.tv_sec = sblk->mkfs_time; ++ i->i_atime.tv_sec = sblk->mkfs_time; ++ i->i_ctime.tv_sec = sblk->mkfs_time; ++ i->i_uid = msblk->uid[inodeb->uid]; ++ i->i_mode = inodeb->mode; ++ i->i_nlink = 1; ++ i->i_size = 0; ++ if (inodeb->guid == SQUASHFS_GUIDS) ++ i->i_gid = i->i_uid; ++ else ++ i->i_gid = msblk->guid[inodeb->guid]; ++} ++ ++ ++static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode) ++{ ++ struct super_block *s = i->i_sb; ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned int block = SQUASHFS_INODE_BLK(inode) + ++ sblk->inode_table_start; ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); ++ unsigned int ino = i->i_ino; ++ long long next_block; ++ unsigned int next_offset; ++ union squashfs_inode_header_2 id, sid; ++ struct squashfs_base_inode_header_2 *inodeb = &id.base, ++ *sinodeb = &sid.base; ++ ++ TRACE("Entered squashfs_iget\n"); ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, ++ offset, sizeof(*sinodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb, ++ sizeof(*sinodeb)); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) inodeb, block, ++ offset, sizeof(*inodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ squashfs_new_inode(msblk, i, inodeb, ino); ++ ++ switch(inodeb->inode_type) { ++ case SQUASHFS_FILE_TYPE: { ++ struct squashfs_reg_inode_header_2 *inodep = &id.reg; ++ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg; ++ long long frag_blk; ++ unsigned int frag_size = 0; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ frag_blk = SQUASHFS_INVALID_BLK; ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG && ++ !get_fragment_location_2(s, ++ inodep->fragment, &frag_blk, &frag_size)) ++ goto failed_read; ++ ++ i->i_size = inodep->file_size; ++ i->i_fop = &generic_ro_fops; ++ i->i_mode |= S_IFREG; ++ i->i_mtime.tv_sec = inodep->mtime; ++ i->i_atime.tv_sec = inodep->mtime; ++ i->i_ctime.tv_sec = inodep->mtime; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ if (sblk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ ++ TRACE("File inode %x:%x, start_block %x, " ++ "block_list_start %llx, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, next_block, ++ next_offset); ++ break; ++ } ++ case SQUASHFS_DIR_TYPE: { ++ struct squashfs_dir_inode_header_2 *inodep = &id.dir; ++ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops_2; ++ i->i_fop = &squashfs_dir_ops_2; ++ i->i_mode |= S_IFDIR; ++ i->i_mtime.tv_sec = inodep->mtime; ++ i->i_atime.tv_sec = inodep->mtime; ++ i->i_ctime.tv_sec = inodep->mtime; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = 0; ++ SQUASHFS_I(i)->u.s2.parent_inode = 0; ++ ++ TRACE("Directory inode %x:%x, start_block %x, offset " ++ "%x\n", SQUASHFS_INODE_BLK(inode), ++ offset, inodep->start_block, ++ inodep->offset); ++ break; ++ } ++ case SQUASHFS_LDIR_TYPE: { ++ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir; ++ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops_2; ++ i->i_fop = &squashfs_dir_ops_2; ++ i->i_mode |= S_IFDIR; ++ i->i_mtime.tv_sec = inodep->mtime; ++ i->i_atime.tv_sec = inodep->mtime; ++ i->i_ctime.tv_sec = inodep->mtime; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; ++ SQUASHFS_I(i)->u.s2.directory_index_offset = ++ next_offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = ++ inodep->i_count; ++ SQUASHFS_I(i)->u.s2.parent_inode = 0; ++ ++ TRACE("Long directory inode %x:%x, start_block %x, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, inodep->offset); ++ break; ++ } ++ case SQUASHFS_SYMLINK_TYPE: { ++ struct squashfs_symlink_inode_header_2 *inodep = ++ &id.symlink; ++ struct squashfs_symlink_inode_header_2 *sinodep = ++ &sid.symlink; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep->symlink_size; ++ i->i_op = &page_symlink_inode_operations; ++ i->i_data.a_ops = &squashfs_symlink_aops; ++ i->i_mode |= S_IFLNK; ++ SQUASHFS_I(i)->start_block = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ ++ TRACE("Symbolic link inode %x:%x, start_block %llx, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_BLKDEV_TYPE: ++ case SQUASHFS_CHRDEV_TYPE: { ++ struct squashfs_dev_inode_header_2 *inodep = &id.dev; ++ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_mode |= (inodeb->inode_type == ++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : ++ S_IFBLK; ++ init_special_inode(i, i->i_mode, ++ old_decode_dev(inodep->rdev)); ++ ++ TRACE("Device inode %x:%x, rdev %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->rdev); ++ break; ++ } ++ case SQUASHFS_FIFO_TYPE: ++ case SQUASHFS_SOCKET_TYPE: { ++ ++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) ++ ? S_IFIFO : S_IFSOCK; ++ init_special_inode(i, i->i_mode, 0); ++ break; ++ } ++ default: ++ ERROR("Unknown inode type %d in squashfs_iget!\n", ++ inodeb->inode_type); ++ goto failed_read1; ++ } ++ ++ return 1; ++ ++failed_read: ++ ERROR("Unable to read inode [%x:%x]\n", block, offset); ++ ++failed_read1: ++ return 0; ++} ++ ++ ++static int get_dir_index_using_offset(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ long long f_pos) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index_2 index; ++ ++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", ++ i_count, (unsigned int) f_pos); ++ ++ if (f_pos == 0) ++ goto finish; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index_2 sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) &index, ++ index_start, index_offset, ++ sizeof(index), &index_start, ++ &index_offset); ++ ++ if (index.index > f_pos) ++ break; ++ ++ squashfs_get_cached_block(s, NULL, index_start, index_offset, ++ index.size + 1, &index_start, ++ &index_offset); ++ ++ length = index.index; ++ *next_block = index.start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ ++finish: ++ return length; ++} ++ ++ ++static int get_dir_index_using_name(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ const char *name, int size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index_2 *index; ++ char *str; ++ ++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); ++ ++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + ++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_index\n"); ++ goto failure; ++ } ++ ++ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1); ++ strncpy(str, name, size); ++ str[size] = '\0'; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index_2 sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) index, ++ index_start, index_offset, ++ sizeof(struct squashfs_dir_index_2), ++ &index_start, &index_offset); ++ ++ squashfs_get_cached_block(s, index->name, index_start, ++ index_offset, index->size + 1, ++ &index_start, &index_offset); ++ ++ index->name[index->size + 1] = '\0'; ++ ++ if (strcmp(index->name, str) > 0) ++ break; ++ ++ length = index->index; ++ *next_block = index->start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ kfree(str); ++failure: ++ return length; ++} ++ ++ ++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir) ++{ ++ struct inode *i = file->f_dentry->d_inode; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header_2 dirh; ++ struct squashfs_dir_entry_2 *dire; ++ ++ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto finish; ++ } ++ ++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, ++ file->f_pos); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header_2 sdirh; ++ ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry_2 sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block, next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block, next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, ++ dire->size + 1, &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (file->f_pos >= length) ++ continue; ++ ++ dire->name[dire->size + 1] = '\0'; ++ ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", ++ (unsigned int) dirent, dire->name, ++ dire->size + 1, (int) file->f_pos, ++ dirh.start_block, dire->offset, ++ squashfs_filetype_table[dire->type]); ++ ++ if (filldir(dirent, dire->name, dire->size + 1, ++ file->f_pos, SQUASHFS_MK_VFS_INODE( ++ dirh.start_block, dire->offset), ++ squashfs_filetype_table[dire->type]) ++ < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ goto finish; ++ } ++ file->f_pos = length; ++ } ++ } ++ ++finish: ++ kfree(dire); ++ return 0; ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ kfree(dire); ++ return 0; ++} ++ ++ ++static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ const unsigned char *name = dentry->d_name.name; ++ int len = dentry->d_name.len; ++ struct inode *inode = NULL; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header_2 dirh; ++ struct squashfs_dir_entry_2 *dire; ++ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; ++ ++ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto exit_loop; ++ } ++ ++ if (len > SQUASHFS_NAME_LEN) ++ goto exit_loop; ++ ++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, name, ++ len); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header_2 sdirh; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry_2 sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block,next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block,next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, dire->size + 1, ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (sorted && name[0] < dire->name[0]) ++ goto exit_loop; ++ ++ if ((len == dire->size + 1) && !strncmp(name, ++ dire->name, len)) { ++ squashfs_inode_t ino = ++ SQUASHFS_MKINODE(dirh.start_block, ++ dire->offset); ++ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block, ++ dire->offset); ++ ++ TRACE("calling squashfs_iget for directory " ++ "entry %s, inode %x:%x, %lld\n", name, ++ dirh.start_block, dire->offset, ino); ++ ++ inode = squashfs_iget(i->i_sb, ino, inode_number); ++ ++ goto exit_loop; ++ } ++ } ++ } ++ ++exit_loop: ++ kfree(dire); ++ d_add(dentry, inode); ++ return ERR_PTR(0); ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ goto exit_loop; ++} ++ ++ ++int squashfs_2_0_supported(struct squashfs_sb_info *msblk) ++{ ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ msblk->read_inode = squashfs_read_inode_2; ++ msblk->read_fragment_index_table = read_fragment_index_table_2; ++ ++ sblk->bytes_used = sblk->bytes_used_2; ++ sblk->uid_start = sblk->uid_start_2; ++ sblk->guid_start = sblk->guid_start_2; ++ sblk->inode_table_start = sblk->inode_table_start_2; ++ sblk->directory_table_start = sblk->directory_table_start_2; ++ sblk->fragment_table_start = sblk->fragment_table_start_2; ++ ++ return 1; ++} +diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/squashfs.h linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs.h +--- linux-2.6.20/fs/squashfs/squashfs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs.h 2007-01-12 01:42:11.000000000 +0000 +@@ -0,0 +1,87 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs.h ++ */ ++ ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++#endif ++ ++#ifdef SQUASHFS_TRACE ++#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) ++#else ++#define TRACE(s, args...) {} ++#endif ++ ++#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) ++ ++#define SERROR(s, args...) do { \ ++ if (!silent) \ ++ printk(KERN_ERR "SQUASHFS error: "s, ## args);\ ++ } while(0) ++ ++#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) ++ ++static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode) ++{ ++ return list_entry(inode, struct squashfs_inode_info, vfs_inode); ++} ++ ++#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY) ++#define SQSH_EXTERN ++extern unsigned int squashfs_read_data(struct super_block *s, char *buffer, ++ long long index, unsigned int length, ++ long long *next_index, int srclength); ++extern int squashfs_get_cached_block(struct super_block *s, char *buffer, ++ long long block, unsigned int offset, ++ int length, long long *next_block, ++ unsigned int *next_offset); ++extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct ++ squashfs_fragment_cache *fragment); ++extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block ++ *s, long long start_block, ++ int length); ++extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number); ++extern const struct address_space_operations squashfs_symlink_aops; ++extern const struct address_space_operations squashfs_aops; ++extern const struct address_space_operations squashfs_aops_4K; ++extern struct inode_operations squashfs_dir_inode_ops; ++#else ++#define SQSH_EXTERN static ++#endif ++ ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk); ++#else ++static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY ++extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk); ++#else ++static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk) ++{ ++ return 0; ++} ++#endif +diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs.h +--- linux-2.6.20/include/linux/squashfs_fs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs.h 2007-01-12 00:06:09.000000000 +0000 +@@ -0,0 +1,934 @@ ++#ifndef SQUASHFS_FS ++#define SQUASHFS_FS ++ ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs.h ++ */ ++ ++#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY ++#define CONFIG_SQUASHFS_2_0_COMPATIBILITY ++#endif ++ ++#ifdef CONFIG_SQUASHFS_VMALLOC ++#define SQUASHFS_ALLOC(a) vmalloc(a) ++#define SQUASHFS_FREE(a) vfree(a) ++#else ++#define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL) ++#define SQUASHFS_FREE(a) kfree(a) ++#endif ++#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE ++#define SQUASHFS_MAJOR 3 ++#define SQUASHFS_MINOR 0 ++#define SQUASHFS_MAGIC 0x73717368 ++#define SQUASHFS_MAGIC_SWAP 0x68737173 ++#define SQUASHFS_START 0 ++ ++/* size of metadata (inode and directory) blocks */ ++#define SQUASHFS_METADATA_SIZE 8192 ++#define SQUASHFS_METADATA_LOG 13 ++ ++/* default size of data blocks */ ++#define SQUASHFS_FILE_SIZE 65536 ++#define SQUASHFS_FILE_LOG 16 ++ ++#define SQUASHFS_FILE_MAX_SIZE 65536 ++ ++/* Max number of uids and gids */ ++#define SQUASHFS_UIDS 256 ++#define SQUASHFS_GUIDS 255 ++ ++/* Max length of filename (not 255) */ ++#define SQUASHFS_NAME_LEN 256 ++ ++#define SQUASHFS_INVALID ((long long) 0xffffffffffff) ++#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) ++#define SQUASHFS_INVALID_BLK ((long long) -1) ++#define SQUASHFS_USED_BLK ((long long) -2) ++ ++/* Filesystem flags */ ++#define SQUASHFS_NOI 0 ++#define SQUASHFS_NOD 1 ++#define SQUASHFS_CHECK 2 ++#define SQUASHFS_NOF 3 ++#define SQUASHFS_NO_FRAG 4 ++#define SQUASHFS_ALWAYS_FRAG 5 ++#define SQUASHFS_DUPLICATE 6 ++#define SQUASHFS_EXPORT 7 ++ ++#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) ++ ++#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NOI) ++ ++#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NOD) ++ ++#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NOF) ++ ++#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NO_FRAG) ++ ++#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_ALWAYS_FRAG) ++ ++#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_DUPLICATE) ++ ++#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_EXPORT) ++ ++#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_CHECK) ++ ++#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ ++ duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \ ++ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ ++ (duplicate_checking << 6) | (exportable << 7)) ++ ++/* Max number of types and file types */ ++#define SQUASHFS_DIR_TYPE 1 ++#define SQUASHFS_FILE_TYPE 2 ++#define SQUASHFS_SYMLINK_TYPE 3 ++#define SQUASHFS_BLKDEV_TYPE 4 ++#define SQUASHFS_CHRDEV_TYPE 5 ++#define SQUASHFS_FIFO_TYPE 6 ++#define SQUASHFS_SOCKET_TYPE 7 ++#define SQUASHFS_LDIR_TYPE 8 ++#define SQUASHFS_LREG_TYPE 9 ++ ++/* 1.0 filesystem type definitions */ ++#define SQUASHFS_TYPES 5 ++#define SQUASHFS_IPC_TYPE 0 ++ ++/* Flag whether block is compressed or uncompressed, bit is set if block is ++ * uncompressed */ ++#define SQUASHFS_COMPRESSED_BIT (1 << 15) ++ ++#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ ++ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) ++ ++#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) ++ ++#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) ++ ++#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \ ++ ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \ ++ ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) ++ ++#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) ++ ++/* ++ * Inode number ops. Inodes consist of a compressed block number, and an ++ * uncompressed offset within that block ++ */ ++#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) ++ ++#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) ++ ++#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ ++ << 16) + (B))) ++ ++/* Compute 32 bit VFS inode number from squashfs inode number */ ++#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ ++ ((b) >> 2) + 1)) ++/* XXX */ ++ ++/* Translate between VFS mode and squashfs mode */ ++#define SQUASHFS_MODE(a) ((a) & 0xfff) ++ ++/* fragment and fragment table defines */ ++#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry)) ++ ++#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ ++ SQUASHFS_METADATA_SIZE - 1) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ ++ sizeof(long long)) ++ ++/* inode lookup table defines */ ++#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t)) ++ ++#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \ ++ SQUASHFS_METADATA_SIZE - 1) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\ ++ sizeof(long long)) ++ ++/* cached data constants for filesystem */ ++#define SQUASHFS_CACHED_BLKS 8 ++ ++#define SQUASHFS_MAX_FILE_SIZE_LOG 64 ++ ++#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ ++ (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) ++ ++#define SQUASHFS_MARKER_BYTE 0xff ++ ++/* meta index cache */ ++#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) ++#define SQUASHFS_META_ENTRIES 31 ++#define SQUASHFS_META_NUMBER 8 ++#define SQUASHFS_SLOTS 4 ++ ++struct meta_entry { ++ long long data_block; ++ unsigned int index_block; ++ unsigned short offset; ++ unsigned short pad; ++}; ++ ++struct meta_index { ++ unsigned int inode_number; ++ unsigned int offset; ++ unsigned short entries; ++ unsigned short skip; ++ unsigned short locked; ++ unsigned short pad; ++ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES]; ++}; ++ ++ ++/* ++ * definitions for structures on disk ++ */ ++ ++typedef long long squashfs_block_t; ++typedef long long squashfs_inode_t; ++ ++struct squashfs_super_block { ++ unsigned int s_magic; ++ unsigned int inodes; ++ unsigned int bytes_used_2; ++ unsigned int uid_start_2; ++ unsigned int guid_start_2; ++ unsigned int inode_table_start_2; ++ unsigned int directory_table_start_2; ++ unsigned int s_major:16; ++ unsigned int s_minor:16; ++ unsigned int block_size_1:16; ++ unsigned int block_log:16; ++ unsigned int flags:8; ++ unsigned int no_uids:8; ++ unsigned int no_guids:8; ++ unsigned int mkfs_time /* time of filesystem creation */; ++ squashfs_inode_t root_inode; ++ unsigned int block_size; ++ unsigned int fragments; ++ unsigned int fragment_table_start_2; ++ long long bytes_used; ++ long long uid_start; ++ long long guid_start; ++ long long inode_table_start; ++ long long directory_table_start; ++ long long fragment_table_start; ++ long long lookup_table_start; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_index { ++ unsigned int index; ++ unsigned int start_block; ++ unsigned char size; ++ unsigned char name[0]; ++} __attribute__ ((packed)); ++ ++#define SQUASHFS_BASE_INODE_HEADER \ ++ unsigned int inode_type:4; \ ++ unsigned int mode:12; \ ++ unsigned int uid:8; \ ++ unsigned int guid:8; \ ++ unsigned int mtime; \ ++ unsigned int inode_number; ++ ++struct squashfs_base_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++} __attribute__ ((packed)); ++ ++struct squashfs_ipc_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++} __attribute__ ((packed)); ++ ++struct squashfs_dev_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned short rdev; ++} __attribute__ ((packed)); ++ ++struct squashfs_symlink_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_reg_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ squashfs_block_t start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ unsigned int file_size; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_lreg_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ squashfs_block_t start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ long long file_size; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ unsigned int start_block; ++ unsigned int parent_inode; ++} __attribute__ ((packed)); ++ ++struct squashfs_ldir_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned int file_size:27; ++ unsigned int offset:13; ++ unsigned int start_block; ++ unsigned int i_count:16; ++ unsigned int parent_inode; ++ struct squashfs_dir_index index[0]; ++} __attribute__ ((packed)); ++ ++union squashfs_inode_header { ++ struct squashfs_base_inode_header base; ++ struct squashfs_dev_inode_header dev; ++ struct squashfs_symlink_inode_header symlink; ++ struct squashfs_reg_inode_header reg; ++ struct squashfs_lreg_inode_header lreg; ++ struct squashfs_dir_inode_header dir; ++ struct squashfs_ldir_inode_header ldir; ++ struct squashfs_ipc_inode_header ipc; ++}; ++ ++struct squashfs_dir_entry { ++ unsigned int offset:13; ++ unsigned int type:3; ++ unsigned int size:8; ++ int inode_number:16; ++ char name[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_header { ++ unsigned int count:8; ++ unsigned int start_block; ++ unsigned int inode_number; ++} __attribute__ ((packed)); ++ ++struct squashfs_fragment_entry { ++ long long start_block; ++ unsigned int size; ++ unsigned int pending; ++} __attribute__ ((packed)); ++ ++extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); ++extern int squashfs_uncompress_init(void); ++extern int squashfs_uncompress_exit(void); ++ ++/* ++ * macros to convert each packed bitfield structure from little endian to big ++ * endian and vice versa. These are needed when creating or using a filesystem ++ * on a machine with different byte ordering to the target architecture. ++ * ++ */ ++ ++#define SQUASHFS_SWAP_START \ ++ int bits;\ ++ int b_pos;\ ++ unsigned long long val;\ ++ unsigned char *s;\ ++ unsigned char *d; ++ ++#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ ++ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ ++ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ ++ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ ++ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ ++ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ ++ SQUASHFS_SWAP((s)->flags, d, 288, 8);\ ++ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ ++ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ ++ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ ++ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ ++ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ ++ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ ++ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ ++ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ ++ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ ++ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ ++ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ ++ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ ++ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ ++ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\ ++} ++ ++#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->inode_number, d, 64, 32); ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_ipc_inode_header))\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_dev_inode_header)); \ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_symlink_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_reg_inode_header));\ ++ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ ++ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ ++} ++ ++#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_lreg_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ ++ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 224, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_dir_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 147, 13);\ ++ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ ++} ++ ++#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_ldir_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ ++ SQUASHFS_SWAP((s)->offset, d, 155, 13);\ ++ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ ++ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ ++ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ ++ SQUASHFS_SWAP((s)->index, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->size, d, 64, 8);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\ ++ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ ++ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\ ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ ++ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ ++ SQUASHFS_SWAP((s)->size, d, 64, 32);\ ++} ++ ++#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1) ++ ++#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * 2);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ 16)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ ++} ++ ++#define SQUASHFS_SWAP_INTS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * 4);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ 32)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ ++} ++ ++#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * 8);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ 64)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ ++} ++ ++#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * bits / 8);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ bits)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) ++#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) ++ ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++ ++struct squashfs_base_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++} __attribute__ ((packed)); ++ ++struct squashfs_ipc_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int type:4; ++ unsigned int offset:4; ++} __attribute__ ((packed)); ++ ++struct squashfs_dev_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned short rdev; ++} __attribute__ ((packed)); ++ ++struct squashfs_symlink_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_reg_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int mtime; ++ unsigned int start_block; ++ unsigned int file_size:32; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ unsigned int mtime; ++ unsigned int start_block:24; ++} __attribute__ ((packed)); ++ ++#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ ++ SQUASHFS_SWAP((s)->guid, d, 20, 4); ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_ipc_inode_header_1));\ ++ SQUASHFS_SWAP((s)->type, d, 24, 4);\ ++ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ ++} ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_dev_inode_header_1));\ ++ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_symlink_inode_header_1));\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_reg_inode_header_1));\ ++ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_dir_inode_header_1));\ ++ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ ++} ++ ++#endif ++ ++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY ++ ++struct squashfs_dir_index_2 { ++ unsigned int index:27; ++ unsigned int start_block:29; ++ unsigned char size; ++ unsigned char name[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_base_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++} __attribute__ ((packed)); ++ ++struct squashfs_ipc_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++} __attribute__ ((packed)); ++ ++struct squashfs_dev_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned short rdev; ++} __attribute__ ((packed)); ++ ++struct squashfs_symlink_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_reg_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int mtime; ++ unsigned int start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ unsigned int file_size:32; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ unsigned int mtime; ++ unsigned int start_block:24; ++} __attribute__ ((packed)); ++ ++struct squashfs_ldir_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int file_size:27; ++ unsigned int offset:13; ++ unsigned int mtime; ++ unsigned int start_block:24; ++ unsigned int i_count:16; ++ struct squashfs_dir_index_2 index[0]; ++} __attribute__ ((packed)); ++ ++union squashfs_inode_header_2 { ++ struct squashfs_base_inode_header_2 base; ++ struct squashfs_dev_inode_header_2 dev; ++ struct squashfs_symlink_inode_header_2 symlink; ++ struct squashfs_reg_inode_header_2 reg; ++ struct squashfs_dir_inode_header_2 dir; ++ struct squashfs_ldir_inode_header_2 ldir; ++ struct squashfs_ipc_inode_header_2 ipc; ++}; ++ ++struct squashfs_dir_header_2 { ++ unsigned int count:8; ++ unsigned int start_block:24; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_entry_2 { ++ unsigned int offset:13; ++ unsigned int type:3; ++ unsigned int size:8; ++ char name[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_fragment_entry_2 { ++ unsigned int start_block; ++ unsigned int size; ++} __attribute__ ((packed)); ++ ++#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ ++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_dev_inode_header_2)); \ ++ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_symlink_inode_header_2));\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_reg_inode_header_2));\ ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 128, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_dir_inode_header_2));\ ++ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 51, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ ++} ++ ++#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_ldir_inode_header_2));\ ++ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ ++ SQUASHFS_SWAP((s)->offset, d, 59, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ ++ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ ++ SQUASHFS_SWAP((s)->index, d, 0, 27);\ ++ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ ++ SQUASHFS_SWAP((s)->size, d, 56, 8);\ ++} ++#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\ ++ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\ ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ ++ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->size, d, 32, 32);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) ++ ++/* fragment and fragment table defines */ ++#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) ++ ++#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ ++ SQUASHFS_METADATA_SIZE - 1) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ ++ sizeof(int)) ++ ++#endif ++ ++#ifdef __KERNEL__ ++ ++/* ++ * macros used to swap each structure entry, taking into account ++ * bitfields and different bitfield placing conventions on differing ++ * architectures ++ */ ++ ++#include <asm/byteorder.h> ++ ++#ifdef __BIG_ENDIAN ++ /* convert from little endian to big endian */ ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ ++ tbits, b_pos) ++#else ++ /* convert from big endian to little endian */ ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ ++ tbits, 64 - tbits - b_pos) ++#endif ++ ++#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ ++ b_pos = pos % 8;\ ++ val = 0;\ ++ s = (unsigned char *)p + (pos / 8);\ ++ d = ((unsigned char *) &val) + 7;\ ++ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ ++ *d-- = *s++;\ ++ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ ++} ++ ++#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); ++ ++#endif ++#endif +diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs_i.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_i.h +--- linux-2.6.20/include/linux/squashfs_fs_i.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_i.h 2007-01-12 00:06:09.000000000 +0000 +@@ -0,0 +1,45 @@ ++#ifndef SQUASHFS_FS_I ++#define SQUASHFS_FS_I ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs_i.h ++ */ ++ ++struct squashfs_inode_info { ++ long long start_block; ++ unsigned int offset; ++ union { ++ struct { ++ long long fragment_start_block; ++ unsigned int fragment_size; ++ unsigned int fragment_offset; ++ long long block_list_start; ++ } s1; ++ struct { ++ long long directory_index_start; ++ unsigned int directory_index_offset; ++ unsigned int directory_index_count; ++ unsigned int parent_inode; ++ } s2; ++ } u; ++ struct inode vfs_inode; ++}; ++#endif +diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs_sb.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_sb.h +--- linux-2.6.20/include/linux/squashfs_fs_sb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_sb.h 2007-01-12 01:23:47.000000000 +0000 +@@ -0,0 +1,74 @@ ++#ifndef SQUASHFS_FS_SB ++#define SQUASHFS_FS_SB ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs_sb.h ++ */ ++ ++#include <linux/squashfs_fs.h> ++ ++struct squashfs_cache { ++ long long block; ++ int length; ++ long long next_index; ++ char *data; ++}; ++ ++struct squashfs_fragment_cache { ++ long long block; ++ int length; ++ unsigned int locked; ++ char *data; ++}; ++ ++struct squashfs_sb_info { ++ struct squashfs_super_block sblk; ++ int devblksize; ++ int devblksize_log2; ++ int swap; ++ struct squashfs_cache *block_cache; ++ struct squashfs_fragment_cache *fragment; ++ int next_cache; ++ int next_fragment; ++ int next_meta_index; ++ unsigned int *uid; ++ unsigned int *guid; ++ long long *fragment_index; ++ unsigned int *fragment_index_2; ++ char *read_page; ++ struct mutex read_data_mutex; ++ struct mutex read_page_mutex; ++ struct mutex block_cache_mutex; ++ struct mutex fragment_mutex; ++ struct mutex meta_index_mutex; ++ wait_queue_head_t waitq; ++ wait_queue_head_t fragment_wait_queue; ++ struct meta_index *meta_index; ++ z_stream stream; ++ long long *inode_lookup_table; ++ int (*read_inode)(struct inode *i, squashfs_inode_t \ ++ inode); ++ long long (*read_blocklist)(struct inode *inode, int \ ++ index, int readahead_blks, char *block_list, \ ++ unsigned short **block_p, unsigned int *bsize); ++ int (*read_fragment_index_table)(struct super_block *s); ++}; ++#endif +diff -x .gitignore -Nurp linux-2.6.20/init/do_mounts_rd.c linux-2.6.20-squashfs3.2-r2/init/do_mounts_rd.c +--- linux-2.6.20/init/do_mounts_rd.c 2006-11-29 21:57:37.000000000 +0000 ++++ linux-2.6.20-squashfs3.2-r2/init/do_mounts_rd.c 2007-01-16 02:06:03.000000000 +0000 +@@ -5,6 +5,7 @@ + #include <linux/ext2_fs.h> + #include <linux/romfs_fs.h> + #include <linux/cramfs_fs.h> ++#include <linux/squashfs_fs.h> + #include <linux/initrd.h> + #include <linux/string.h> + +@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in + * numbers could not be found. + * + * We currently check for the following magic numbers: ++ * squashfs + * minix + * ext2 + * romfs +@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start + struct ext2_super_block *ext2sb; + struct romfs_super_block *romfsb; + struct cramfs_super *cramfsb; ++ struct squashfs_super_block *squashfsb; + int nblocks = -1; + unsigned char *buf; + +@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start + ext2sb = (struct ext2_super_block *) buf; + romfsb = (struct romfs_super_block *) buf; + cramfsb = (struct cramfs_super *) buf; ++ squashfsb = (struct squashfs_super_block *) buf; + memset(buf, 0xe5, size); + + /* +@@ -101,6 +105,18 @@ identify_ramdisk_image(int fd, int start + goto done; + } + ++ /* squashfs is at block zero too */ ++ if (squashfsb->s_magic == SQUASHFS_MAGIC) { ++ printk(KERN_NOTICE ++ "RAMDISK: squashfs filesystem found at block %d\n", ++ start_block); ++ if (squashfsb->s_major < 3) ++ nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; ++ else ++ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; ++ goto done; ++ } ++ + /* + * Read block 1 to test for minix and ext2 superblock + */ diff --git a/packages/linux/linux-openmoko-devel_svn.bb b/packages/linux/linux-openmoko-devel_svn.bb index f93f11f082..6fae5da9ef 100644 --- a/packages/linux/linux-openmoko-devel_svn.bb +++ b/packages/linux/linux-openmoko-devel_svn.bb @@ -1,7 +1,7 @@ DESCRIPTION = "Linux 2.6.x (development) kernel for FIC SmartPhones shipping w/ OpenMoko" VANILLA_VERSION = "2.6.22.5" PV = "${VANILLA_VERSION}-moko11+svnr${SRCREV}" -PR = "r0" +PR = "r1" KERNEL_IMAGETYPE = "uImage" UBOOT_ENTRYPOINT = "30008000" @@ -15,7 +15,9 @@ SRCREV_FORMAT = "patches" SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${VANILLA_VERSION}.tar.bz2 \ svn://svn.openmoko.org/trunk/src/target/kernel;module=patches;proto=http;name=patches \ + file://squashfs.patch;patch=1 \ file://fix-EVIOCGRAB-semantics-2.6.22.5.patch;patch=1 \ +# file://printascii.patch;patch=1 \ file://defconfig \ file://logo_linux_clut224.ppm" S = "${WORKDIR}/linux-${VANILLA_VERSION}" @@ -52,3 +54,19 @@ do_prepatch() { addtask prepatch after do_unpack before do_patch +############################################################### +# put into deploy directory and append u-boot header +# +do_deploy() { + install -d ${DEPLOY_DIR_IMAGE} + install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}.bin + tar -cvzf ${DEPLOY_DIR_IMAGE}/modules-${KERNEL_RELEASE}-${PR}-${MACHINE}.tgz -C ${D} lib + ${OBJCOPY} -O binary -R .note -R .comment -S vmlinux linux.bin + rm -f linux.bin.gz + gzip -9 linux.bin + ${STAGING_BINDIR_NATIVE}/uboot-mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "OpenMoko Kernel Image Neo1973" \ + -d linux.bin.gz ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin + ln -sf ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin ${DEPLOY_DIR_IMAGE}/uImage-${MACHINE}-latest.bin + rm -f linux.bin.gz +} + diff --git a/packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch b/packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch new file mode 100644 index 0000000000..c8cb76d99e --- /dev/null +++ b/packages/matchbox-keyboard/files/matchbox-keyboard-hide-delay.patch @@ -0,0 +1,99 @@ +Index: matchbox-keyboard/src/matchbox-keyboard.h +=================================================================== +--- matchbox-keyboard/src/matchbox-keyboard.h (revision 1669) ++++ matchbox-keyboard/src/matchbox-keyboard.h (working copy) +@@ -285,7 +285,7 @@ + void + mb_kbd_remote_init (MBKeyboardUI *ui); + +-void ++int + mb_kbd_remote_process_xevents (MBKeyboardUI *ui, XEvent *xevent); + + /**** Keyboard ****/ +Index: matchbox-keyboard/src/matchbox-keyboard-ui.c +=================================================================== +--- matchbox-keyboard/src/matchbox-keyboard-ui.c (revision 1669) ++++ matchbox-keyboard/src/matchbox-keyboard-ui.c (working copy) +@@ -1096,6 +1096,8 @@ + /* Key repeat - values for standard xorg install ( xset q) */ + int repeat_delay = 100 * 10000; + int repeat_rate = 30 * 1000; ++ int hide_delay = 100 * 1000; ++ int to_hide = 0; + + int press_x = 0, press_y = 0; + +@@ -1182,11 +1184,42 @@ + mb_kbd_xembed_process_xevents (ui, &xev); + + if (ui->is_daemon) +- mb_kbd_remote_process_xevents (ui, &xev); +- ++ { ++ switch (mb_kbd_remote_process_xevents (ui, &xev)) ++ { ++ case 0: ++ if (to_hide == 1) { ++ mb_kbd_ui_hide(ui); ++ } ++ tvt.tv_usec = hide_delay; ++ to_hide = 1; ++ break; ++ case 1: ++ mb_kbd_ui_show(ui); ++ tvt.tv_usec = repeat_delay; ++ to_hide = 0; ++ break; ++ default: ++ if (to_hide == 1) { ++ mb_kbd_ui_hide(ui); ++ tvt.tv_usec = repeat_delay; ++ to_hide = 0; ++ } ++ break; ++ } ++ } + } + else + { ++ /* Hide timed out */ ++ if (to_hide == 1) ++ { ++ DBG("Hide timed out, calling mb_kbd_ui_hide"); ++ mb_kbd_ui_hide(ui); ++ tvt.tv_usec = repeat_delay; ++ to_hide = 0; ++ } ++ + /* Keyrepeat */ + if (mb_kbd_get_held_key(ui->kbd) != NULL) + { +Index: matchbox-keyboard/src/matchbox-keyboard-remote.c +=================================================================== +--- matchbox-keyboard/src/matchbox-keyboard-remote.c (revision 1669) ++++ matchbox-keyboard/src/matchbox-keyboard-remote.c (working copy) +@@ -28,7 +28,7 @@ + "_MB_IM_INVOKER_COMMAND", False); + } + +-void ++int + mb_kbd_remote_process_xevents (MBKeyboardUI *ui, XEvent *xevent) + { + DBG("got a message\n"); +@@ -42,9 +42,12 @@ + DBG("got a message of type _MB_IM_INVOKER_COMMAND, val %i\n", + xevent->xclient.data.l[0]); + if (xevent->xclient.data.l[0] == 1) +- mb_kbd_ui_show (ui); ++ { ++ return 1; ++ } + else +- mb_kbd_ui_hide (ui); ++ return 0; + } + } ++ return -1; + } diff --git a/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb b/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb index b7ef698938..16d5f0e2e6 100644 --- a/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb +++ b/packages/matchbox-keyboard/matchbox-keyboard-inputmethod_svn.bb @@ -6,11 +6,12 @@ RPROVIDES_${PN} = matchbox-keyboard #DEFAULT_PREFERENCE = "-1" SECTION = "x11" PV = "0.0+svnr${SRCREV}" -PR = "r4" +PR = "r5" SRC_URI = "svn://svn.o-hand.com/repos/matchbox/trunk;module=matchbox-keyboard;proto=http \ file://matchbox-keyboard-applet.patch;patch=1;pnum=0 \ - file://80matchboxkeyboard" + file://80matchboxkeyboard \ + file://matchbox-keyboard-hide-delay.patch;patch=1" SRC_URI_append_fic-gta01 = " file://fic-gta01-font-size.patch;patch=1" diff --git a/packages/navit/.mtn2git_empty b/packages/navit/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/navit/.mtn2git_empty diff --git a/packages/navit/files/.mtn2git_empty b/packages/navit/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/navit/files/.mtn2git_empty diff --git a/packages/navit/files/compile-fix.patch b/packages/navit/files/compile-fix.patch new file mode 100644 index 0000000000..86274d8aa8 --- /dev/null +++ b/packages/navit/files/compile-fix.patch @@ -0,0 +1,8 @@ +diff -Naur navit-0.0.1.old/src/fib-1.1/Makefile.am navit-0.0.1/src/fib-1.1/Makefile.am +--- navit-0.0.1.old/src/fib-1.1/Makefile.am 2007-07-05 19:16:20.000000000 +0200 ++++ navit-0.0.1/src/fib-1.1/Makefile.am 2007-09-18 00:48:08.000000000 +0200 +@@ -1,4 +1,3 @@ + noinst_LTLIBRARIES = libfib.la + libfib_la_SOURCES = fib.c fib.h fibpriv.h +-libfib_la_LDFLAGS = -static + EXTRA_DIST=README configure.in fh_extractmin.3 fh_makeheap.3 fh_makekeyheap.3 fibtest.c fibtest2.c tt.c use.c diff --git a/packages/navit/navit_0.0.1.bb b/packages/navit/navit_0.0.1.bb new file mode 100644 index 0000000000..947d2b3ba8 --- /dev/null +++ b/packages/navit/navit_0.0.1.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "Navit is a car navigation system with routing engine." +LICENSE = "GPL" +DEPENDS = "glib-2.0 gtk+" +PV = "0.0.1" +PR = "r1" + +inherit autotools + +SRC_URI = "${SOURCEFORGE_MIRROR}/navit/navit-${PV}.tar.gz \ + file://compile-fix.patch;patch=1" + +EXTRA_OECONF = "--disable-gui-sdl --disable-binding-python" + +FILES_${PN}-dbg += "${libdir}/${PN}/*/.debug" diff --git a/packages/openmoko2/openmoko-browser2_svn.bb b/packages/openmoko2/openmoko-browser2_svn.bb new file mode 100644 index 0000000000..edfeca7702 --- /dev/null +++ b/packages/openmoko2/openmoko-browser2_svn.bb @@ -0,0 +1,7 @@ +DESCRIPTION = "The OpenMoko Webbrowser" +SECTION = "openmoko/apps" +DEPENDS += "intltool libmokoui2 check webkit-gtk" +PV = "0.0.1+svn${SVNREV}" +PR = "r0" + +inherit openmoko2 diff --git a/packages/openmoko2/openmoko-sound-system2_0.1.0.bb b/packages/openmoko2/openmoko-sound-system2_0.1.0.bb index 46397afa9b..35bfe66318 100644 --- a/packages/openmoko2/openmoko-sound-system2_0.1.0.bb +++ b/packages/openmoko2/openmoko-sound-system2_0.1.0.bb @@ -10,7 +10,9 @@ RDEPENDS = "\ pulseaudio-module-native-protocol-unix \ pulseaudio-module-cli-protocol-unix \ " -PR = "r0" +RREPLACES = "openmoko-sound-system" +RPROVIDES = "openmoko-sound-system" +PR = "r1" inherit openmoko-base update-rc.d diff --git a/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb b/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb index a8b41ed318..0693b9bb8a 100644 --- a/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb +++ b/packages/openmoko2/openmoko-sound-theme-standard2_svn.bb @@ -1,7 +1,9 @@ DESCRIPTION = "Standard sound theme for the OpenMoko distribution" SECTION = "openmoko/base" +RREPLACES = "openmoko-sound-theme-standard" +RPROVIDES = "openmoko-sound-theme-standard" PV = "0.1+svnr${SRCREV}" -PR = "r0" +PR = "r1" inherit openmoko2 autotools diff --git a/packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch b/packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch new file mode 100644 index 0000000000..2e4f796cc9 --- /dev/null +++ b/packages/pkgconfig/pkgconfig-0.22/sysroot-support.patch @@ -0,0 +1,102 @@ +Add support for PKG_CONFIG_SYSROOT_DIR to pkgconfig + +--- + main.c | 5 ++++- + pkg-config.1 | 9 +++++++++ + pkg.c | 14 +++++++++++++- + pkg.h | 3 +++ + 4 files changed, 29 insertions(+), 2 deletions(-) + +Index: pkg-config-0.22/main.c +=================================================================== +--- pkg-config-0.22.orig/main.c 2007-09-14 10:20:15.000000000 +0100 ++++ pkg-config-0.22/main.c 2007-09-14 10:22:41.000000000 +0100 +@@ -46,6 +46,8 @@ + static int want_debug_spew = 0; + static int want_verbose_errors = 0; + static int want_stdout_errors = 0; ++char *pcsysrootdir = NULL; ++ + + void + debug_spew (const char *format, ...) +@@ -196,7 +198,7 @@ main (int argc, char **argv) + GString *str; + GSList *packages = NULL; + char *search_path; +- char *pcbuilddir; ++ char *pcbuilddir; + const char *pkglibdir; + char **search_dirs; + char **iter; +@@ -345,6 +347,7 @@ main (int argc, char **argv) + } + } + #endif ++ pcsysrootdir = getenv ("PKG_CONFIG_SYSROOT_DIR"); + + pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR"); + if (pcbuilddir) +Index: pkg-config-0.22/pkg.c +=================================================================== +--- pkg-config-0.22.orig/pkg.c 2007-09-14 10:20:15.000000000 +0100 ++++ pkg-config-0.22/pkg.c 2007-09-14 10:22:41.000000000 +0100 +@@ -479,11 +479,23 @@ string_list_to_string (GSList *list) + GSList *tmp; + GString *str = g_string_new (""); + char *retval; ++ int offset=0; + + tmp = list; + while (tmp != NULL) + { +- g_string_append (str, tmp->data); ++ if (pcsysrootdir != NULL) ++ { ++ if (!strncmp(tmp->data,"-I",2) || ++ !strncmp(tmp->data,"-L",2)) ++ { ++ offset=2; ++ g_string_append_c (str,((char*)tmp->data)[0]); ++ g_string_append_c (str,((char*)tmp->data)[1]); ++ g_string_append (str,pcsysrootdir); ++ } ++ } ++ g_string_append (str, tmp->data+offset); + g_string_append_c (str, ' '); + + tmp = g_slist_next (tmp); +Index: pkg-config-0.22/pkg-config.1 +=================================================================== +--- pkg-config-0.22.orig/pkg-config.1 2007-09-14 10:20:15.000000000 +0100 ++++ pkg-config-0.22/pkg-config.1 2007-09-14 10:23:08.000000000 +0100 +@@ -260,6 +260,15 @@ Don't strip -I/usr/include out of cflags + Don't strip -L/usr/lib out of libs + + .TP ++.I "PKG_CONFIG_SYSROOT_DIR" ++Modify -I and -L to use the directories located in target sysroot. ++this option is usefull when crosscompiling package that use pkg-config ++to determine CFLAGS anf LDFLAGS. -I and -L are modified to point to ++the new system root. this means that a -I/usr/include/libfoo will ++become -I/var/target/usr/include/libfoo with a PKG_CONFIG_SYSROOT_DIR ++equal to /var/target (same rule apply to -L) ++ ++.TP + .I "PKG_CONFIG_LIBDIR" + Replaces the default \fIpkg-config\fP search directory. + +Index: pkg-config-0.22/pkg.h +=================================================================== +--- pkg-config-0.22.orig/pkg.h 2007-09-14 10:20:15.000000000 +0100 ++++ pkg-config-0.22/pkg.h 2007-09-14 10:22:41.000000000 +0100 +@@ -123,6 +123,9 @@ void disable_private_libs(void); + /* If TRUE, do not automatically prefer uninstalled versions */ + extern gboolean disable_uninstalled; + ++/* string that contain environment */ ++extern char* pcsysrootdir; ++ + #ifdef G_OS_WIN32 + /* If TRUE, do not automatically define "prefix" while + * parsing each .pc file */ diff --git a/packages/pkgconfig/pkgconfig.inc b/packages/pkgconfig/pkgconfig.inc index 47c077a8d3..ed9e7e69af 100644 --- a/packages/pkgconfig/pkgconfig.inc +++ b/packages/pkgconfig/pkgconfig.inc @@ -5,9 +5,10 @@ It replaces the ubiquitous *-config scripts you may have \ seen with a single tool." HOMEPAGE = "http://pkg-config.freedesktop.org/wiki/" LICENSE = "GPL" -PR = "r1" +PR = "r2" SRC_URI = "http://pkgconfig.freedesktop.org/releases/pkg-config-${PV}.tar.gz \ + file://sysroot-support.patch;patch=1 \ file://glibconfig-sysdefs.h" S = "${WORKDIR}/pkg-config-${PV}/" diff --git a/packages/poppler/poppler_0.6.bb b/packages/poppler/poppler_0.6.bb new file mode 100644 index 0000000000..3c1ec00183 --- /dev/null +++ b/packages/poppler/poppler_0.6.bb @@ -0,0 +1,6 @@ +require poppler.inc + +PR = "r0" + +EXTRA_OECONF_append = " --disable-abiword-output " + diff --git a/packages/python/python-pybluez_0.13.bb b/packages/python/python-pybluez_0.13.bb new file mode 100644 index 0000000000..2e7e282ddc --- /dev/null +++ b/packages/python/python-pybluez_0.13.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Python bindings for the Linux Bluetooth stack" +SECTION = "devel/python" +DEPENDS = "bluez-libs" +LICENSE = "GPL" +PR = "ml0" + +SRC_URI = "http://org.csail.mit.edu/pybluez/release/pybluez-src-${PV}.tar.gz" +S = "${WORKDIR}/pybluez-${PV}" + +inherit distutils diff --git a/packages/sylpheed/claws-mail_3.0.1.bb b/packages/sylpheed/claws-mail_3.0.1.bb new file mode 100644 index 0000000000..29e7a5bc63 --- /dev/null +++ b/packages/sylpheed/claws-mail_3.0.1.bb @@ -0,0 +1,43 @@ +SECTION = "x11/network" +DESCRIPTION = "Mail user agent" +DEPENDS = "gtk+ libetpan openssl aspell" +LICENSE = "GPL" +PR = "r0" + +SRC_URI = "\ + ${SOURCEFORGE_MIRROR}/sylpheed-claws/claws-mail-${PV}.tar.bz2 \ + file://desktop.patch;patch=1 \ + " + +FILES_${PN} = "${bindir} ${datadir}/pixmaps ${datadir}/applications" + +EXTRA_OECONF = "--disable-aspell-test \ + --enable--aspell \ + --disable-manual \ + --disable-crash-dialog \ + --disable-jpilot \ + --disable-trayicon-plugin \ + --disable-spamassassin-plugin \ + --disable-bogofilter-plugin \ + --disable-pgpcore-plugin \ + --disable-pgpmime-plugin \ + --disable-pgpinline-plugin \ + --disable-dillo-viewer-plugin \ + --disable-clamav-plugin \ + --disable-gnomeprint \ + --disable-valgrind \ + " + +inherit autotools pkgconfig + +do_install_append() { + install -d ${D}${datadir}/applications + install -m 0644 claws-mail.desktop ${D}${datadir}/applications/ + install -d ${D}${datadir}/pixmaps + install -m 0644 claws-mail.png ${D}${datadir}/pixmaps/ +} + +do_stage () { + autotools_stage_all +} + diff --git a/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb b/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb index 6256363500..2a09c76f09 100644 --- a/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb +++ b/packages/uboot/uboot-openmoko_1.2.0+gitf34024d4a328e6edd906456da98d2c537155c4f7+svn2943.bb @@ -9,7 +9,7 @@ UBOOT_OPENMOKO_REV = "2943" UBOOT_MACHINES = "gta01bv2 gta01bv3 gta01bv4" PV = "1.2.0+git${UBOOT_UPSTREAM_REV}+svn${UBOOT_OPENMOKO_REV}" -PR = "r0" +PR = "r1" PROVIDES = "virtual/bootloader" S = "${WORKDIR}/git" @@ -30,16 +30,9 @@ do_quilt() { } do_svnrev() { - FILE=${S}/tools/setlocalversion - OLDFILE=$FILE.old - NEWFILE=$FILE.new - cp $FILE $OLDFILE - LINES=`cat $OLDFILE | wc -l` - LINES_WE_WANT=$(($LINES-1)) - LASTLINE=`cat $OLDFILE | tail -n 1` - cat $OLDFILE | head -n $LINES_WE_WANT > $NEWFILE - echo ${LASTLINE}_${PR} >> $NEWFILE - rm $FILE && mv $NEWFILE $FILE + mv -f tools/setlocalversion tools/setlocalversion.old + echo -n "echo " >>tools/setlocalversion + echo ${PV} >>tools/setlocalversion } do_configure_prepend() { diff --git a/packages/uboot/uboot-openmoko_svn.bb b/packages/uboot/uboot-openmoko_svn.bb index e1575884c2..3669b409da 100644 --- a/packages/uboot/uboot-openmoko_svn.bb +++ b/packages/uboot/uboot-openmoko_svn.bb @@ -5,7 +5,7 @@ SECTION = "bootloader" PRIORITY = "optional" PROVIDES = "virtual/bootloader" PV = "1.2.0+git${SRCDATE}+svnr${SRCREV}" -PR = "r0" +PR = "r1" SRCREV_FORMAT = "patches" @@ -30,16 +30,9 @@ do_quilt() { } do_svnrev() { - FILE=${S}/tools/setlocalversion - OLDFILE=$FILE.old - NEWFILE=$FILE.new - cp $FILE $OLDFILE - LINES=`cat $OLDFILE | wc -l` - LINES_WE_WANT=$(($LINES-1)) - LASTLINE=`cat $OLDFILE | tail -n 1` - cat $OLDFILE | head -n $LINES_WE_WANT > $NEWFILE - echo ${LASTLINE}_${PR} >> $NEWFILE - rm $FILE && mv $NEWFILE $FILE + mv -f tools/setlocalversion tools/setlocalversion.old + echo -n "echo " >>tools/setlocalversion + echo ${PV} >>tools/setlocalversion } do_configure_prepend() { |