diff --git a/Makefile.am b/Makefile.am index a3f2f2c1e6655249867b8f8801083069399815ac..6c9be1d2e4311230e4a9907debfbc044057c88b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,10 +61,15 @@ ACLOCAL_AMFLAGS = -I m4 if CPPUNIT UNIT_TESTS=unit_tests endif + +# Compile java bindings if all of the dependencies existed if X_JNI - JNI=bindings/java/jni + JAVA_BINDINGS=bindings/java +else + JAVA_BINDINGS= endif -SUBDIRS = tsk tools tests samples man $(UNIT_TESTS) $(JNI) + +SUBDIRS = tsk tools tests samples man $(UNIT_TESTS) $(JAVA_BINDINGS) nobase_include_HEADERS = tsk/libtsk.h tsk/tsk_incs.h \ tsk/base/tsk_base.h tsk/base/tsk_os.h \ diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..0d5bb7777a3039ef75eb18688a436e090b899575 --- /dev/null +++ b/bindings/java/Makefile.am @@ -0,0 +1,16 @@ +# Compile the sub directories +SUBDIRS = jni + +tsk_jar = $(top_builddir)/bindings/java/dist/Tsk_DataModel.jar +jardir = $(prefix)/share/java +jar_DATA = $(tsk_jar) + +$(tsk_jar): + +all-local: + ant dist + +CLEANFILES = $(tsk_jar) + +clean-local: + ant clean diff --git a/bindings/java/build-unix.xml b/bindings/java/build-unix.xml index f1451406e997aa20fa597b9ae4fc8433ead1f7ac..d35e7404d4bc0b90717afabcf760e37a0cc01f2f 100644 --- a/bindings/java/build-unix.xml +++ b/bindings/java/build-unix.xml @@ -23,6 +23,17 @@ </java> </target> + <target name="check-native-build" depends="check-native-build-mac,check-native-build-unix"/> + + <target name="check-native-build-mac" depends="testTSKLibs" if="tsk_dylib.present"> + <uptodate property="native-up-to-date" srcfile="./jni/.libs/libtsk_jni.dylib" + targetfile="${amd64}/mac/libtsk_jni.jnilib" /> + </target> + + <target name="check-native-build-unix" depends="testTSKLibs" if="tsk_so.present"> + <uptodate property="native-up-to-date" srcfile="./jni/.libs/libtsk_jni.so" + targetfile="${amd64}/linux/libtsk_jni.so"/> + </target> <target name="testTSKLibs"> <property environment="env"/> @@ -35,46 +46,40 @@ <!-- OS X --> <target name="copyTskLibs_dylib" depends="testTSKLibs" if="tsk_dylib.present"> <property environment="env"/> - <copy file="./jni/.libs/libtsk_jni.dylib" tofile="./libtsk_jni.jnilib"/> + <copy file="./jni/.libs/libtsk_jni.dylib" tofile="./libtsk_jni.jnilib" overwrite="true"/> </target> <target name="copyMacLibs" depends="testTSKLibs" if="tsk_dylib.present"> <property environment="env"/> <property name="jni.dylib" location="${basedir}/jni/.libs/libtsk_jni.dylib" /> <property name="jni.jnilib" value="libtsk_jni.jnilib" /> - <property name="zlib.jni" location="/usr/lib/libz.dylib"/> - <property name="libewf.jni" location="/usr/local/lib/libewf.dylib"/> <!-- x86_64 --> - <copy file="${jni.dylib}" tofile="${x86_64}/mac/${jni.jnilib}"/> - <copy file="${zlib.jni}" tofile="${x86_64}/mac/zlib.dylib"/> - <copy file="${libewf.jni}" tofile="${x86_64}/mac/libewf.dylib"/> + <copy file="${jni.dylib}" tofile="${x86_64}/mac/${jni.jnilib}" overwrite="true"/> <!-- amd64 --> - <copy file="${jni.dylib}" tofile="${amd64}/mac/${jni.jnilib}"/> - <copy file="${zlib.jni}" tofile="${x86_64}/mac/zlib.dylib"/> - <copy file="${libewf.jni}" tofile="${x86_64}/mac/libewf.dylib"/> + <copy file="${jni.dylib}" tofile="${amd64}/mac/${jni.jnilib}" overwrite="true"/> </target> <!-- Non-OS X --> <target name="copyTskLibs_so" depends="testTSKLibs" if="tsk_so.present"> <property environment="env"/> - <copy file="./jni/.libs/libtsk_jni.so" tofile="./libtsk_jni.so"/> + <copy file="./jni/.libs/libtsk_jni.so" tofile="./libtsk_jni.so" overwrite="true"/> </target> <target name="copyLinuxLibs" depends="testTSKLibs" if="tsk_so.present"> <property environment="env"/> <property name="jni.so" location="${basedir}/jni/.libs/libtsk_jni.so" /> <!-- x86_64 --> - <copy file="${jni.so}" tofile="${x86_64}/linux/libtsk_jni.so"/> + <copy file="${jni.so}" tofile="${x86_64}/linux/libtsk_jni.so" overwrite="true"/> <!-- amd64 --> - <copy file="${jni.so}" tofile="${amd64}/linux/libtsk_jni.so"/> + <copy file="${jni.so}" tofile="${amd64}/linux/libtsk_jni.so" overwrite="true"/> <!-- x86 --> - <copy file="${jni.so}" tofile="${x86}/linux/libtsk_jni.so"/> + <copy file="${jni.so}" tofile="${x86}/linux/libtsk_jni.so" overwrite="true"/> <!-- i386 --> - <copy file="${jni.so}" tofile="${i386}/linux/libtsk_jni.so"/> + <copy file="${jni.so}" tofile="${i386}/linux/libtsk_jni.so" overwrite="true"/> <!-- i586 --> - <copy file="${jni.so}" tofile="${i586}/linux/libtsk_jni.so"/> + <copy file="${jni.so}" tofile="${i586}/linux/libtsk_jni.so" overwrite="true"/> <!-- i686 --> - <copy file="${jni.so}" tofile="${i686}/linux/libtsk_jni.so"/> + <copy file="${jni.so}" tofile="${i686}/linux/libtsk_jni.so" overwrite="true"/> </target> <target name="copyLibs" depends="copyLinuxLibs,copyMacLibs" /> diff --git a/bindings/java/build-windows.xml b/bindings/java/build-windows.xml index 821ae120fb659a6ad14e1e2d3426057d441ad567..40c6a38396aba76c49ee6f5fa7d7f41ce0818e51 100644 --- a/bindings/java/build-windows.xml +++ b/bindings/java/build-windows.xml @@ -33,7 +33,20 @@ <sysproperty key="types" value="${test-types}"/> </java> </target> - + + <target name="check-native-build" depends="check-build-32,check-build-64"/> + + <target name="check-build-32" if="win32.exists"> + <uptodate property="native-up-to-date" srcfile="${basedir}/../../win32/Release/libtsk_jni.dll" + targetfile="${x86}/win/libtsk_jni.dll"/> + </target> + + + <target name="check-build-64" if="win32.exists"> + <uptodate property="native-up-to-date" srcfile="${basedir}/../../win32/x64/Release/libtsk_jni.dll" + targetfile="${amd64}/win/libtsk_jni.dll"/> + </target> + <target name="copyLibs" depends="copyWinLibs" description="Copy native libs to the correct folder"> <property name="tsk.config" value="Release"/> <antcall target="copyWinLibs" /> @@ -52,65 +65,18 @@ </target> <target name="copyWinLibs64" depends="checkLibDirs" if="win64.exists"> - <property name="win64dir" location="${basedir}/../../win32/x64/${tsk.config}" /> - - <fileset dir="${win64dir}" id="win64dlls"> - <include name="*.dll" /> - </fileset> - <fileset dir="${crt}/win64" id="crt64dlls"> - <include name="*.dll" /> - </fileset> - - <copy todir="${amd64}/win" overwrite="true"> - <fileset refid="win64dlls" /> - </copy> - <copy todir="${amd64}/win" overwrite="true"> - <fileset refid="crt64dlls" /> - </copy> + <property name="tsk.jni.64" location="${basedir}/../../win32/x64/${tsk.config}/libtsk_jni.dll" /> - <copy todir="${x86_64}/win" overwrite="true"> - <fileset refid="win64dlls" /> - </copy> - <copy todir="${x86_64}/win" overwrite="true"> - <fileset refid="crt64dlls" /> - </copy> + <copy file="${tsk.jni.64}" todir="${amd64}/win" overwrite="true"/> + <copy file="${tsk.jni.64}" todir="${x86_64}/win" overwrite="true"/> </target> <target name="copyWinLibs32" depends="checkLibDirs" if="win32.exists"> - <property name="win32dir" location="${basedir}/../../win32/${tsk.config}" /> - <fileset dir="${win32dir}" id="win32dlls"> - <include name="*.dll" /> - </fileset> - <fileset dir="${crt}/win32" id="crt32dlls"> - <include name="*.dll" /> - </fileset> - - <copy todir="${i386}/win" overwrite="true"> - <fileset refid="win32dlls" /> - </copy> - <copy todir="${i386}/win" overwrite="true"> - <fileset refid="crt32dlls" /> - </copy> - - <copy todir="${x86}/win" overwrite="true"> - <fileset refid="win32dlls" /> - </copy> - <copy todir="${x86}/win" overwrite="true"> - <fileset refid="crt32dlls" /> - </copy> - - <copy todir="${i586}/win" overwrite="true"> - <fileset refid="win32dlls" /> - </copy> - <copy todir="${i586}/win" overwrite="true"> - <fileset refid="crt32dlls" /> - </copy> + <property name="tsk.jni.32" location="${basedir}/../../win32/${tsk.config}/libtsk_jni.dll" /> - <copy todir="${i686}/win" overwrite="true"> - <fileset refid="win32dlls" /> - </copy> - <copy todir="${i686}/win" overwrite="true"> - <fileset refid="crt32dlls" /> - </copy> + <copy file="${tsk.jni.32}" todir="${i386}/win" overwrite="true"/> + <copy file="${tsk.jni.32}" todir="${x86}/win" overwrite="true"/> + <copy file="${tsk.jni.32}" todir="${i586}/win" overwrite="true"/> + <copy file="${tsk.jni.32}" todir="${i686}/win" overwrite="true"/> </target> </project> diff --git a/bindings/java/build.xml b/bindings/java/build.xml index dcd3a31ba7b96eb9ee714c92b41eb16ed7317cd6..5f3725ce4db4e6ed00b88d37d22e2956b5699c98 100755 --- a/bindings/java/build.xml +++ b/bindings/java/build.xml @@ -27,7 +27,6 @@ <property name="i386" location="build/NATIVELIBS/i386" /> <property name="i586" location="build/NATIVELIBS/i586" /> <property name="i686" location="build/NATIVELIBS/i686"/> - <property name="crt" location="${basedir}/crt" /> <path id="libraries"> <fileset dir="${lib}"> @@ -116,7 +115,23 @@ pattern="lib/[artifact]-[revision](-[classifier]).[ext]" /> </javac> </target> - <target name="dist" depends="init-ivy, compile, copyLibs" + <target name="dist" depends="check-build" unless="up-to-date"> + <antcall target="dist-do"/> + </target> + + <target name="check-build" depends="check-native-build"> + <uptodate property="java-up-to-date" targetfile="${dist}/Tsk_DataModel.jar" > + <srcfiles dir="${src}" includes="**/*.java"/> + </uptodate> + <condition property="up-to-date"> + <and> + <isset property="java-up-to-date"/> + <isset property="native-up-to-date"/> + </and> + </condition> + </target> + + <target name="dist-do" depends="init-ivy, compile, copyLibs" description="generate the distribution" > <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --> <jar jarfile="${dist}/Tsk_DataModel.jar" basedir="${build}"/> diff --git a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java index 1821f767aaca54f5e675d9ebd704fa96876f23cd..ad2bd6fa6f779608e494363cf0b68c55086e2ef1 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java +++ b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java @@ -619,7 +619,7 @@ public String getMetaFlagsAsString() { String str = ""; if (metaFlags.contains(TSK_FS_META_FLAG_ENUM.ALLOC)) { str = TSK_FS_META_FLAG_ENUM.ALLOC.toString(); - } else if (metaFlags.contains(TSK_FS_META_FLAG_ENUM.ALLOC)) { + } else if (metaFlags.contains(TSK_FS_META_FLAG_ENUM.UNALLOC)) { str = TSK_FS_META_FLAG_ENUM.UNALLOC.toString(); } return str; diff --git a/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java b/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java index dd7e506dfec352291f7cbccc0c340a4988a84831..be8685ff9cb1831fb90c32d6118d74a53f5f5d35 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java +++ b/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java @@ -34,10 +34,6 @@ public class LibraryUtils { public static final String[] EXTS = new String[] { ".so", ".dylib", ".dll", ".jnilib" }; - - public static final Lib[] CRT_LIBS = new Lib[] { Lib.MSVCP, Lib.MSVCR }; - - public static final Lib[] OTHER_LIBS = new Lib[] { Lib.ZLIB, Lib.LIBEWF }; /** * The libraries the TSK Datamodel needs. @@ -66,45 +62,6 @@ public String getUnixName() { } } - /** - * Load all libraries needed for the current platform except the TSK JNI. - * - * @return - */ - public static boolean loadAuxilliaryLibs() { - System.out.println("Java lib path: " + System.getProperty("java.library.path")); - boolean loaded = true; - if (LibraryUtils.isWindows()) { - loaded = LibraryUtils.loadCRTLibs(); - } - - if (! LibraryUtils.isLinux()) { - - for(LibraryUtils.Lib lib : LibraryUtils.getLibs()) { - loaded = LibraryUtils.loadLibFromJar(lib); - if (!loaded) { - System.out.println("SleuthkitJNI: failed to load " + lib.getLibName()); - } else { - System.out.println("SleuthkitJNI: loaded " + lib.getLibName()); - } - } - } else { - System.out.println("In unix path."); - // Unix platform - for (Lib lib : LibraryUtils.getLibs()) { - try { - System.out.println("Lib name: " + lib.getUnixName()); - System.loadLibrary(lib.getUnixName()); - System.out.println("SleuthkitJNI: loaded " + lib.getLibName()); - } catch (UnsatisfiedLinkError e) { - loaded = false; - System.out.println("SleuthkitJNI: failed to load " + lib.getLibName()); - } - } - } - return loaded; - } - /** * Load the Sleuthkit JNI. * @@ -119,42 +76,6 @@ public static boolean loadSleuthkitJNI() { } return loaded; } - - /** Load the CRT Libraries. - * - * @return - */ - private static boolean loadCRTLibs() { - boolean loaded = true; - try { - // on windows force loading ms crt dependencies first - // in case linker can't find them on some systems - // Note: if shipping with a different CRT version, this will only print a warning - // and try to use linker mechanism to find the correct versions of libs. - // We should update this if we officially switch to a new version of CRT/compiler - for(LibraryUtils.Lib crt : LibraryUtils.getCRTLibs()) { - loaded = LibraryUtils.loadLibFromJar(crt); - if(!loaded) { - System.out.println("SleuthkitJNI: failed to load " + crt.getLibName()); - } else { - System.out.println("SleuthkitJNI: loaded " + crt.getLibName()); - } - } - } catch (UnsatisfiedLinkError e1) { - System.out.println(e1.toString()); - try { - //Try to load from system path. - System.out.println("Can't find CRT libraries, attempting to load from System.loadLibrary"); - System.loadLibrary("msvcr100"); - System.loadLibrary("msvcp100"); - loaded = true; - } catch (UnsatisfiedLinkError e2) { - System.out.println("SleuthkitJNI: error loading CRT libraries, " + e2.toString()); - loaded = false; - } - } - return loaded; - } /** * Get the name of the current platform. @@ -167,6 +88,8 @@ private static String getPlatform() { os = "win"; } else if(LibraryUtils.isMac()) { os = "mac"; + } else if(LibraryUtils.isLinux()) { + os = "linux"; } // os.arch represents the architecture of the JVM, not the os String arch = System.getProperty("os.arch"); @@ -232,7 +155,7 @@ private static boolean loadLibFromJar(Lib library) { // copy library to temp folder and load it try { - java.io.File libTemp = new java.io.File(System.getProperty("java.io.tmpdir") + libName + libExt); + java.io.File libTemp = new java.io.File(System.getProperty("java.io.tmpdir") + java.io.File.separator + libName + libExt); if(libTemp.exists()) { // Delete old file @@ -257,12 +180,4 @@ private static boolean loadLibFromJar(Lib library) { } return true; } - - private static Lib[] getCRTLibs() { - return CRT_LIBS; - } - - private static Lib[] getLibs() { - return OTHER_LIBS; - } } diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java index 2d75ca64b1d27b8f81a40fdd461f3854154e284f..8653c39c83a017ced0f66543acb5ac76af79e051 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java @@ -118,7 +118,6 @@ public class SleuthkitJNI { //Linked library loading static { - LibraryUtils.loadAuxilliaryLibs(); LibraryUtils.loadSleuthkitJNI(); } diff --git a/bindings/java/src/org/sleuthkit/datamodel/TskData.java b/bindings/java/src/org/sleuthkit/datamodel/TskData.java index 971e3de0682dc46e5a307f59e6d62150c2c5bd14..7c214dbf50a6f428882035d7b28377bfac4d6bb4 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/TskData.java +++ b/bindings/java/src/org/sleuthkit/datamodel/TskData.java @@ -413,8 +413,8 @@ public enum TSK_FS_TYPE_ENUM { TSK_FS_TYPE_HFS (0x00001000), ///< HFS file system TSK_FS_TYPE_HFS_DETECT (0x00001000), ///< HFS auto detection TSK_FS_TYPE_EXT4 (0x00002000), ///< Ext4 file system - TSK_FS_TYPE_YAFFS2(0x00003000), ///< YAFFS2 file system - TSK_FS_TYPE_YAFFS2_DETECT(0x00003000), ///< YAFFS2 auto detection + TSK_FS_TYPE_YAFFS2(0x00004000), ///< YAFFS2 file system + TSK_FS_TYPE_YAFFS2_DETECT(0x00004000), ///< YAFFS2 auto detection TSK_FS_TYPE_UNSUPP (0xffffffff); ///< Unsupported file system private int value; diff --git a/configure.ac b/configure.ac index 64ba753c7ff04a52c939b01d1913632ad6c06531..74b6ae6827ca6428f5f1188361423f4c388914fc 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,8 @@ m4_include([m4/cppunit.m4]) m4_include([m4/ax_jni_include_dir.m4]) m4_include([m4/ac_prog_javac_works.m4]) m4_include([m4/ac_prog_javac.m4]) - +m4_include([m4/ac_prog_java_works.m4]) +m4_include([m4/ac_prog_java.m4]) AC_CONFIG_SRCDIR([tsk/base/tsk_base.h]) AC_CONFIG_HEADERS([tsk/tsk_config.h]) @@ -74,6 +75,8 @@ AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF dnl AC_CHECK_FUNCS([dup2 gethostname isascii iswprint memset munmap regcomp select setlocale strcasecmp strchr strdup strerror strndup strrchr strtol strtoul strtoull utime wcwidth]) AC_CHECK_FUNCS([ishexnumber err errx warn warnx vasprintf getrusage]) +AC_CHECK_FUNCS([strlcpy strlcat]) + AX_PTHREAD([ AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]) CLIBS="$PTHREAD_LIBS $LIBS" @@ -87,6 +90,10 @@ if test -d /usr/local/include; then LDFLAGS="$LDFLAGS -L/usr/local/lib" fi +dnl Add enable/disable option +AC_ARG_ENABLE([java], + [AS_HELP_STRING([--disable-java], [Do not build the java bindings or jar file])]) + dnl Checks for libraries. @@ -198,25 +205,42 @@ AS_IF([test "x$with_libewf" != "xno"], )] dnl Check for the header file first to make sure they have the dev install [AC_CHECK_HEADERS([libewf.h], - [AC_CHECK_LIB([ewf], [libewf_get_version])] + [AC_CHECK_LIB([ewf], [libewf_get_version], [], [NO_LIBEWF=true])] )] ) AS_IF([test "x$ac_cv_lib_ewf_libewf_get_version" = "xyes"], [ax_libewf=yes], [ax_libewf=no]) -dnl Test for java/jni so that we can compile the java bindings -AC_PROG_JAVAC -if test "x$JAVAC" != x; then - AX_JNI_INCLUDE_DIR - for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS - do - JNI_CPPFLAGS="$JNI_CPPFLAGS -I$JNI_INCLUDE_DIR" - done - dnl Export the paths so that the makefile gets them - AC_SUBST(JNI_CPPFLAGS, $JNI_CPPFLAGS) -fi -AM_CONDITIONAL([X_JNI],[test "x$JNI_CPPFLAGS" != x]) +dnl sqlite requires pthread libraries - this was copied from its configure.ac +dnl AC_SEARCH_LIBS(pthread_create, pthread) +AC_SEARCH_LIBS(dlopen, dl) + +dnl Test for the various java things that we need for bindings +AS_IF([test "x$enable_java" != "xno"], [ + dnl javac is needed to compile the JAR file + AC_PROG_JAVAC + if test "x$JAVAC" != x; then + AX_JNI_INCLUDE_DIR + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS + do + JNI_CPPFLAGS="$JNI_CPPFLAGS -I$JNI_INCLUDE_DIR" + done + dnl Export the paths so that the makefile gets them + AC_SUBST(JNI_CPPFLAGS, $JNI_CPPFLAGS) + fi + + dnl java is needed by ant + dnl we had one report of a system with javac and not java + AC_PROG_JAVA + + dnl Test is ant is available + AC_PATH_PROG([ANT_FOUND], [ant], []) + +]) dnl test enable_java -AS_IF([test "x$JNI_CPPFLAGS" != x], [ax_java_support=yes], [ax_java_support=no]) +dnl if we found everything we need, set ax_java_support for the +dnl status message and set X_JNI for use in Makefile +AS_IF([test "x$JNI_CPPFLAGS" != x && test "x$ANT_FOUND" != x && test "x$JAVA" != x], [ax_java_support=yes], [ax_java_support=no]) +AM_CONDITIONAL([X_JNI],[test "x$ax_java_support" == "xyes"]) AC_CONFIG_COMMANDS([tsk/tsk_incs.h], [echo "#ifndef _TSK_INCS_H" > tsk/tsk_incs.h @@ -274,6 +298,7 @@ AC_CONFIG_FILES([ tests/Makefile samples/Makefile man/Makefile + bindings/java/Makefile bindings/java/jni/Makefile unit_tests/Makefile unit_tests/base/Makefile]) diff --git a/m4/ac_prog_java.m4 b/m4/ac_prog_java.m4 new file mode 100644 index 0000000000000000000000000000000000000000..1ba1688702ae9dbe97edfe5cc40a9412d24df64b --- /dev/null +++ b/m4/ac_prog_java.m4 @@ -0,0 +1,83 @@ +dnl @synopsis AC_PROG_JAVA +dnl +dnl Here is a summary of the main macros: +dnl +dnl AC_PROG_JAVAC: finds a Java compiler. +dnl +dnl AC_PROG_JAVA: finds a Java virtual machine. +dnl +dnl AC_CHECK_CLASS: finds if we have the given class (beware of +dnl CLASSPATH!). +dnl +dnl AC_CHECK_RQRD_CLASS: finds if we have the given class and stops +dnl otherwise. +dnl +dnl AC_TRY_COMPILE_JAVA: attempt to compile user given source. +dnl +dnl AC_TRY_RUN_JAVA: attempt to compile and run user given source. +dnl +dnl AC_JAVA_OPTIONS: adds Java configure options. +dnl +dnl AC_PROG_JAVA tests an existing Java virtual machine. It uses the +dnl environment variable JAVA then tests in sequence various common +dnl Java virtual machines. For political reasons, it starts with the +dnl free ones. You *must* call [AC_PROG_JAVAC] before. +dnl +dnl If you want to force a specific VM: +dnl +dnl - at the configure.in level, set JAVA=yourvm before calling +dnl AC_PROG_JAVA +dnl +dnl (but after AC_INIT) +dnl +dnl - at the configure level, setenv JAVA +dnl +dnl You can use the JAVA variable in your Makefile.in, with @JAVA@. +dnl +dnl *Warning*: its success or failure can depend on a proper setting of +dnl the CLASSPATH env. variable. +dnl +dnl TODO: allow to exclude virtual machines (rationale: most Java +dnl programs cannot run with some VM like kaffe). +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java +dnl programs. It is VERY IMPORTANT that you download the whole set, +dnl some macros depend on other. Unfortunately, the autoconf archive +dnl does not support the concept of set of macros, so I had to break it +dnl for submission. +dnl +dnl A Web page, with a link to the latest CVS snapshot is at +dnl <http://www.internatif.org/bortzmeyer/autoconf-Java/>. +dnl +dnl This is a sample configure.in Process this file with autoconf to +dnl produce a configure script. +dnl +dnl AC_INIT(UnTag.java) +dnl +dnl dnl Checks for programs. +dnl AC_CHECK_CLASSPATH +dnl AC_PROG_JAVAC +dnl AC_PROG_JAVA +dnl +dnl dnl Checks for classes +dnl AC_CHECK_RQRD_CLASS(org.xml.sax.Parser) +dnl AC_CHECK_RQRD_CLASS(com.jclark.xml.sax.Driver) +dnl +dnl AC_OUTPUT(Makefile) +dnl +dnl @category Java +dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> +dnl @version 2000-07-19 +dnl @license GPLWithACException + +AC_DEFUN([AC_PROG_JAVA],[ +AC_REQUIRE([AC_EXEEXT])dnl +if test x$JAVAPREFIX = x; then + test x$JAVA = x && AC_CHECK_PROGS(JAVA, kaffe$EXEEXT java$EXEEXT) +else + test x$JAVA = x && AC_CHECK_PROGS(JAVA, kaffe$EXEEXT java$EXEEXT, $JAVAPREFIX) +fi +test x$JAVA = x && AC_MSG_WARN([no acceptable Java virtual machine found in \$PATH]) +AC_PROG_JAVA_WORKS +AC_PROVIDE([$0])dnl +]) diff --git a/m4/ac_prog_java_works.m4 b/m4/ac_prog_java_works.m4 new file mode 100644 index 0000000000000000000000000000000000000000..cc71eb2866f39219183436a4814ac7ab9bf11051 --- /dev/null +++ b/m4/ac_prog_java_works.m4 @@ -0,0 +1,101 @@ +dnl @synopsis AC_PROG_JAVA_WORKS +dnl +dnl Internal use ONLY. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java +dnl programs. It is VERY IMPORTANT that you download the whole set, +dnl some macros depend on other. Unfortunately, the autoconf archive +dnl does not support the concept of set of macros, so I had to break it +dnl for submission. The general documentation, as well as the sample +dnl configure.in, is included in the AC_PROG_JAVA macro. +dnl +dnl @category Java +dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> +dnl @version 2000-07-19 +dnl @license GPLWithACException + +AC_DEFUN([AC_PROG_JAVA_WORKS], [ +AC_CHECK_PROG(uudecode, uudecode$EXEEXT, yes) +if test x$JAVA != x; then +if test x$uudecode = xyes; then +AC_CACHE_CHECK([if uudecode can decode base 64 file], ac_cv_prog_uudecode_base64, [ +dnl /** +dnl * Test.java: used to test if java compiler works. +dnl */ +dnl public class Test +dnl { +dnl +dnl public static void +dnl main( String[] argv ) +dnl { +dnl System.exit (0); +dnl } +dnl +dnl } +cat << \EOF > Test.uue +begin-base64 644 Test.class +yv66vgADAC0AFQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE +bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51 +bWJlclRhYmxlDAAKAAsBAARleGl0AQAEKEkpVgoADQAJBwAOAQAQamF2YS9s +YW5nL1N5c3RlbQEABjxpbml0PgEAAygpVgwADwAQCgADABEBAApTb3VyY2VG +aWxlAQAJVGVzdC5qYXZhACEAAQADAAAAAAACAAkABQAGAAEABwAAACEAAQAB +AAAABQO4AAyxAAAAAQAIAAAACgACAAAACgAEAAsAAQAPABAAAQAHAAAAIQAB +AAEAAAAFKrcAErEAAAABAAgAAAAKAAIAAAAEAAQABAABABMAAAACABQ= +==== +EOF +if uudecode$EXEEXT Test.uue; then + ac_cv_prog_uudecode_base64=yes +else + echo "configure: __oline__: uudecode had trouble decoding base 64 file 'Test.uue'" >&AC_FD_CC + echo "configure: failed file was:" >&AC_FD_CC + cat Test.uue >&AC_FD_CC + ac_cv_prog_uudecode_base64=no +fi +rm -f Test.uue]) +fi +if test x$ac_cv_prog_uudecode_base64 != xyes; then + rm -f Test.class + AC_MSG_WARN([I have to compile Test.class from scratch]) + if test x$ac_cv_prog_javac_works = xno; then + AC_MSG_ERROR([Cannot compile java source. $JAVAC does not work properly]) + fi + if test x$ac_cv_prog_javac_works = x; then + AC_PROG_JAVAC + fi +fi +AC_CACHE_CHECK(if $JAVA works, ac_cv_prog_java_works, [ +JAVA_TEST=Test.java +CLASS_TEST=Test.class +TEST=Test +changequote(, )dnl +cat << \EOF > $JAVA_TEST +/* [#]line __oline__ "configure" */ +public class +Test { +public static void main (String args[]) { + System.exit(0); +} } +EOF +changequote([, ])dnl +if test x$ac_cv_prog_uudecode_base64 != xyes; then + if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) && test -s $CLASS_TEST; then + : + else + echo "configure: failed program was:" >&AC_FD_CC + cat $JAVA_TEST >&AC_FD_CC + AC_MSG_ERROR(The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)) + fi +fi + if AC_TRY_COMMAND($JAVA $JAVAFLAGS $TEST) >/dev/null 2>&1; then + ac_cv_prog_java_works=yes +else + echo "configure: failed program was:" >&AC_FD_CC + cat $JAVA_TEST >&AC_FD_CC + AC_MSG_ERROR(The Java VM $JAVA failed (see config.log, check the CLASSPATH?)) +fi +rm -fr $JAVA_TEST $CLASS_TEST Test.uue]) +AC_PROVIDE([$0])dnl +fi +] +) + diff --git a/tsk/auto/db_sqlite.cpp b/tsk/auto/db_sqlite.cpp index 4679b0a003abd594842859bbfbef976cd1d98ec9..d05c96fe72d20e015c13509147d53d37b1f4dfda 100644 --- a/tsk/auto/db_sqlite.cpp +++ b/tsk/auto/db_sqlite.cpp @@ -572,7 +572,7 @@ int parObjId = fsObjId; } else { - parObjId = findParObjId(fs_file, fsObjId); + parObjId = findParObjId(fs_file, path, fsObjId); if (parObjId == -1) { //error return 1; @@ -582,23 +582,57 @@ int return addFile(fs_file, fs_attr, path, md5, known, fsObjId, parObjId, objId); } + +/** + * return a hash of the passed in string. We use this + * for full paths. + * From: http://www.cse.yorku.ca/~oz/hash.html + */ +uint32_t TskDbSqlite::hash(const unsigned char *str) { + uint32_t hash = 5381; + int c; + + while ((c = *str++)) { + // skip slashes -> normalizes leading/ending/double slashes + if (c == '/') + continue; + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } + + return hash; +} + /** * Store meta_addr to object id mapping of the directory in a local cache map * @param fsObjId fs id of this directory - * @param meta_addr meta_addr of this directory - * @param meta_seq meta_seq of this directory + * @param fs_file File for the directory to store + * @param path Full path (parent and this file) of this directory * @param objId object id of this directory from the objects table */ -void TskDbSqlite::storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const uint32_t & meta_seq, const int64_t & objId) { - map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId]; - //store only if does not exist -- otherwise '..' and '.' entries will overwrite - if (fsMap.count(meta_addr) == 0) { - fsMap[meta_addr][meta_seq] = objId; +void TskDbSqlite::storeObjId(const int64_t & fsObjId, const TSK_FS_FILE *fs_file, const char *path, const int64_t & objId) { + // skip the . and .. entries + if ((fs_file->name) && (fs_file->name->name) && (TSK_FS_ISDOT(fs_file->name->name))) { + return; + } + + uint32_t seq; + /* NTFS uses sequence, otherwise we hash the path. We do this to map to the + * correct parent folder if there are two from teh root dir that eventually point to + * the same folder (one deleted and one allocated) or two hard links. */ + if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype)) { + seq = fs_file->name->meta_seq; } else { - map<uint32_t, int64_t> &fileMap = fsMap[meta_addr]; - if (fileMap.count(meta_seq) == 0) { - fileMap[meta_seq] = objId; + seq = hash((const unsigned char *)path); + } + map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId]; + if (fsMap.count(fs_file->name->meta_addr) == 0) { + fsMap[fs_file->name->meta_addr][seq] = objId; + } + else { + map<uint32_t, int64_t> &fileMap = fsMap[fs_file->name->meta_addr]; + if (fileMap.count(seq) == 0) { + fileMap[seq] = objId; } } } @@ -606,16 +640,27 @@ void TskDbSqlite::storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_ad /** * Find parent object id of TSK_FS_FILE. Use local cache map, if not found, fall back to SQL * @param fs_file file to find parent obj id for + * @param path Path of parent folder that we want to match * @param fsObjId fs id of this file * @returns parent obj id ( > 0), -1 on error */ -int64_t TskDbSqlite::findParObjId(const TSK_FS_FILE * fs_file, const int64_t & fsObjId) { - //get from cache by parent meta addr, if available +int64_t TskDbSqlite::findParObjId(const TSK_FS_FILE * fs_file, const char *path, const int64_t & fsObjId) { + uint32_t seq; + /* NTFS uses sequence, otherwise we hash the path. We do this to map to the + * correct parent folder if there are two from teh root dir that eventually point to + * the same folder (one deleted and one allocated) or two hard links. */ + if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype)) { + seq = fs_file->name->meta_seq; + } + else { + seq = hash((const unsigned char *)path); + } + //get from cache by parent meta addr, if available map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId]; if (fsMap.count(fs_file->name->par_addr) > 0) { map<uint32_t, int64_t> &fileMap = fsMap[fs_file->name->par_addr]; - if (fileMap.count(fs_file->name->par_seq) > 0) { - return fileMap[fs_file->name->par_seq]; + if (fileMap.count(seq) > 0) { + return fileMap[seq]; } } @@ -824,7 +869,8 @@ int //if dir, update parent id cache if (meta_type == TSK_FS_META_TYPE_DIR) { - storeObjId(fsObjId, fs_file->name->meta_addr, fs_file->name->meta_seq, objId); + std::string fullPath = std::string(path) + fs_file->name->name; + storeObjId(fsObjId, fs_file, fullPath.c_str(), objId); } free(name); diff --git a/tsk/auto/tsk_db_sqlite.h b/tsk/auto/tsk_db_sqlite.h index 03b17e8573a9acf92882e10ac403efd376851bf7..735867816b760cc47f27ced47b6002369d44db65 100755 --- a/tsk/auto/tsk_db_sqlite.h +++ b/tsk/auto/tsk_db_sqlite.h @@ -233,8 +233,10 @@ class TskDbSqlite { const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId); int addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size, int64_t & objId); - void storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const uint32_t & meta_seq, const int64_t & objId); - int64_t findParObjId(const TSK_FS_FILE * fs_file, const int64_t & fsObjId); + + void storeObjId(const int64_t & fsObjId, const TSK_FS_FILE *fs_file, const char *path, const int64_t & objId); + int64_t findParObjId(const TSK_FS_FILE * fs_file, const char *path, const int64_t & fsObjId); + uint32_t hash(const unsigned char *str); sqlite3 *m_db; TSK_TCHAR m_dbFilePath[1024]; char m_dbFilePathUtf8[1024]; diff --git a/tsk/fs/hfs.c b/tsk/fs/hfs.c index 29dff27dfb0ceafb2669f95dadce2dd5bf29688f..99b55a5e93b53b4303882e95babd85852779628e 100644 --- a/tsk/fs/hfs.c +++ b/tsk/fs/hfs.c @@ -6250,10 +6250,12 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, if (file != NULL) { hfs->root_crtime = file->meta->crtime; hfs->has_root_crtime = TRUE; + tsk_fs_file_close(file); } else { hfs->has_root_crtime = FALSE; } + file = NULL; // disable hard link traversal while finding the hard // link directories themselves (to prevent problems if @@ -6275,11 +6277,12 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, "/" UTF8_NULL_REPLACE UTF8_NULL_REPLACE UTF8_NULL_REPLACE UTF8_NULL_REPLACE "HFS+ Private Data", &inum, NULL); if (result == 0) { - file = tsk_fs_file_open_meta(fs, NULL, inum); - if (file != NULL) { - hfs->meta_crtime = file->meta->crtime; + TSK_FS_FILE *file_tmp = tsk_fs_file_open_meta(fs, NULL, inum); + if (file_tmp != NULL) { + hfs->meta_crtime = file_tmp->meta->crtime; hfs->has_meta_crtime = TRUE; hfs->meta_inum = inum; + tsk_fs_file_close(file_tmp); } } @@ -6293,11 +6296,12 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, tsk_fs_path2inum(fs, "/.HFS+ Private Directory Data\r", &inum, NULL); if (result == 0) { - file = tsk_fs_file_open_meta(fs, NULL, inum); - if (file != NULL) { - hfs->metadir_crtime = file->meta->crtime; + TSK_FS_FILE *file_tmp = tsk_fs_file_open_meta(fs, NULL, inum); + if (file_tmp != NULL) { + hfs->metadir_crtime = file_tmp->meta->crtime; hfs->has_meta_dir_crtime = TRUE; hfs->meta_dir_inum = inum; + tsk_fs_file_close(file_tmp); } } diff --git a/tsk/img/ewf.c b/tsk/img/ewf.c index 07f56976f82ee2fad206d2710e6152b4406e541e..dd5c48a1042ec3b8751e8bdcab872def1330e76f 100644 --- a/tsk/img/ewf.c +++ b/tsk/img/ewf.c @@ -138,6 +138,10 @@ ewf_image_close(TSK_IMG_INFO * img_info) } free(ewf_info->images); } + else { + libewf_error_t *error; + libewf_glob_free( ewf_info->images, ewf_info->num_imgs, &error); + } tsk_deinit_lock(&(ewf_info->read_lock)); tsk_img_free(img_info); diff --git a/tsk/tsk_config.h.in b/tsk/tsk_config.h.in index d9d4e98910b19641b404e2f67f50393bc33dbc8f..f3773331c6490460ebc80d24e21fa4f97e9daf74 100644 --- a/tsk/tsk_config.h.in +++ b/tsk/tsk_config.h.in @@ -109,6 +109,12 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the `strlcat' function. */ +#undef HAVE_STRLCAT + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + /* Define to 1 if you have the <sys/param.h> header file. */ #undef HAVE_SYS_PARAM_H