pax_global_header00006660000000000000000000000064125272700500014512gustar00rootroot0000000000000052 comment=6d512d471ef0f83706c734885125a21012f97825 rifiuti2-0.6.1/000077500000000000000000000000001252727005000132535ustar00rootroot00000000000000rifiuti2-0.6.1/.travis.yml000066400000000000000000000003501252727005000153620ustar00rootroot00000000000000language: c compiler: gcc branches: except: - gh-pages os: - linux install: - sudo apt-get install -qq libglib2.0-dev script: - ./autogen.sh && ./configure && make && sudo make install - make check TESTSUITEFLAGS='-v' rifiuti2-0.6.1/ChangeLog000066400000000000000000000002701252727005000150240ustar00rootroot00000000000000This file is intentionally left blank. ChangeLog prior to 0.5.1 available in docs/ folder. Newer changes can be inspected via git log. Announcement for users is available in NEWS.md . rifiuti2-0.6.1/Makefile.am000066400000000000000000000011161252727005000153060ustar00rootroot00000000000000AUTOMAKE_OPTIONS = foreign dist-xz dist-zip SUBDIRS = src po test EXTRA_DIST = \ docs \ README.md \ NEWS.md \ $(NULL) dist-hook: -find $(top_distdir) -type f \( -name '*~' -o -name '.*~' \) -print0 | xargs -0 -r rm -f MAINTAINERCLEANFILES = \ $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \ $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \ $(NULL) -include $(top_srcdir)/dist-win.mk distclean-local: -rm -rf win-pkg -include $(top_srcdir)/git.mk rifiuti2-0.6.1/NEWS.md000066400000000000000000000033531252727005000143550ustar00rootroot00000000000000## 0.6.1 #### Bug fix * Restore old date/time format for tab-delimited output, in order to be more spreadsheet friendly (Issue #8) * Fix timezone offset for ISO8601-format date, to account for DST * Fix data retrieval on big endian systems * No more attempt to limit usage of TZ environment variable (which doesn't work anyway) ---- ## 0.6.0 #### Feature * Windows 10 recycle bin support (Issue #1) * Add GUI dialog to notify first time Windows users (Issue #2) * 8.3 path names can also be used in XML output now #### Bug fix * Win98 INFO2 trashed file size not retrieved correctly * Substantial rework on showing translation and file names in different lanuages, especially on Windows platform #### Change * Display file deletion time in UTC time zone by default * Vista version: * No more accepts multiple file arguments * Invalid file or dir in command argument treated as fatal error * Result is sorted by deletion time, instead of random order * Show version info in order to differentiate between Vista & Windows 10 formats * INFO2 version: * No more accepts standard input as input data ---- ## 0.5.1 * New manpage * Test cases added to repository * Debian packaging stuff added to repository ---- ## 0.5.0 * Complete rewrite, using glib for I18N support and unicode handling * This means INFO2 records from any localized version of Windows can be parsed correctly * Since Vista recycle bin format changed completely, there will be no INFO2 file. A new program, `rifiuti-vista`, handles such format. * Both program can output in XML format as well as tab-delimited plain text. * Can choose to output long path name or legacy one (like "Progra~1") * Some preliminary check to guard against specially crafted recycle bin files. rifiuti2-0.6.1/README.md000066400000000000000000000066661252727005000145500ustar00rootroot00000000000000`Rifiuti2` is a rewrite of [rifiuti][1], a great tool from Foundstone folks for analyzing Windows Recycle Bin INFO2 file. Analysis of Windows Recycle Bin is usually carried out during Windows computer forensics. `Rifiuti2` can extract file deletion time, original path and size of deleted files and whether the trashed files have been permanently removed. It was extended to cover more functionalities, such as: - [x] Handles recycle bin up to Windows 10 - [x] Different recycle bin format since Vista - [x] 64-bit file size support - [x] Supports all localized versions of Windows — both newer Unicode-based ones and legacy ones, as old as Win98 - [x] Supports output in XML format as well as original tab-delimited text Latest features and changes can be found in [NEWS](NEWS.md) file. [1]: https://web.archive.org/web/20101121070625/http://www.foundstone.com/us/resources/proddesc/rifiuti.htm ## Usage `rifiuti` is designed to be portable, and runs on command line environment. Depending on relevant Windows recycle bin format, there are 2 binaries to choose (most users would probably want first one): Program | Recycle bin from OS | Purpose --------|---------------------|-------- `rifiuti-vista`|Vista or above|Scans `\$Recycle.bin` style folder `rifiuti` |Windows 98 to XP/2003|Reads `INFO2` file in `\RECYCLED` or `\RECYCLER` folder Run programs without any option for more detail. Here are some of the more useful options: Option | Purpose -------:|:-------- -8 | Always print result in UTF-8 encoding -o | Output to file -x | Output XML instead of tab-separated fields -l | Display legacy (8.3) filenames and specify its codepage Please consult manpage (Unix) or README.html (bundled with Windows binaries) for complete options and detailed usage description. #### Examples *
`rifiuti-vista.exe -x -z -o result.xml \case\S-1-2-3\`
Scan for index files under `\case\S-1-2-3\`, adjust all deletion time for local time zone, and write XML output to `result.xml`
*
`rifiuti -l CP932 -8 INFO2`
Assume INFO2 file is generated from Japanese Windows, and display result on console in UTF-8 encoding
## Supported platform It has been tested on Linux (as early as Ubuntu 8.04), Windows XP, Windows 7, and recent FreeBSD, on both 32 and 64-bit intel CPU. Some testing on big endian platforms are done with Qemu emulator. More compatibility fix for other architectures welcome. ## Download Windows binaries, if applicable, would be officially provided [on Github release page][6]. On Linux side: * DEB format packages are available officially on [Debian][7] and [Ubuntu][8]. * There are some third party RPM packages, such as from [CERT Linux Forensics Tools Repository][9], which might work on CentOS, RHEL and Fedora. * [ArchAssault][10], a penetration testing derivative of Arch Linux, has `rifiuti2` packaged since late 2014. Official [FreeBSD port][11] is available since 8.x. For platforms not listed above, users would need to compile program themselves. [Instructions are provided](docs/Compile.md) on how to compile on Linux, \*BSD and Windows. [6]: https://github.com/abelcheung/rifiuti2/releases [7]: https://packages.debian.org/search?keywords=rifiuti2 [8]: http://packages.ubuntu.com/search?keywords=rifiuti2 [9]: https://forensics.cert.org/ [10]: https://archassault.org/packages/?q=rifiuti2 [11]: http://portsmon.freebsd.org/portoverview.py?category=security&portname=rifiuti2 rifiuti2-0.6.1/autogen.sh000077500000000000000000000001101252727005000152440ustar00rootroot00000000000000#!/bin/sh -ev glib-gettextize --copy --force autoreconf -f -i -v "$@" rifiuti2-0.6.1/configure.ac000066400000000000000000000040241252727005000155410ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT([rifiuti2], [0.6.1], [https://github.com/abelcheung/rifiuti2/issues],, [https://abelcheung.github.io/rifiuti2/]) AC_CONFIG_SRCDIR([src/rifiuti-vista.c]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_TESTDIR([test]) AM_INIT_AUTOMAKE([1.11]) AC_CANONICAL_HOST dnl I18N GETTEXT_PACKAGE=rifiuti ALL_LINGUAS="`cat $srcdir/po/LINGUAS`" AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, ["$GETTEXT_PACKAGE"], [Define the gettext package to be used]) AM_GLIB_GNU_GETTEXT dnl Compiler checks. AC_PROG_CC AC_PROG_CC_STDC if test "x$ac_cv_prog_cc_c99" = "xno"; then AC_MSG_ERROR([Could not find a C99 compatible compiler]) fi dnl Always use -Wall for gcc changequote(,)dnl if test "x$GCC" = "xyes"; then case " $CFLAGS " in *[\ \ ]-Wall[\ \ ]*) ;; *) CFLAGS="$CFLAGS -Wall" ;; esac fi changequote([,])dnl dnl Checks for programs. AC_PROG_INSTALL AC_PROG_LN_S dnl For test suite AC_CHECK_PROG([XMLLINT], [xmllint], [xmllint]) AC_CHECK_PROG([ICONV], [iconv], [iconv]) AC_CHECK_PROG([PERL], [perl], [perl]) dnl Checks for libraries. PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.16.0], [:], AC_MSG_ERROR([*** GLib not found. Errors follow: $DEP_PKG_ERRORS])) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) dnl Checks for header files. AC_CHECK_HEADERS([errno.h inttypes.h stdio.h time.h]) dnl Platform specific check. case "$host" in *-*-mingw*) os_mingw=y ;; *-*-*bsd*) os_bsd=y ;; esac AC_SUBST(os_mingw) AC_SUBST(os_bsd) AM_CONDITIONAL([OS_WINDOWS], [test "x$os_mingw" != x]) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_UINT64_T if test "x$ac_cv_c_uint64_t" = "xno" || test "x$ac_cv_c_uint64_t" = "x"; then AC_MSG_ERROR([This system does not support 64 bit integers.]) fi dnl Checks for library functions. AC_CHECK_FUNCS([setlocale strerror fseek fread memcpy]) AC_CONFIG_FILES([ Makefile po/Makefile.in src/Makefile test/Makefile test/atlocal ]) AC_OUTPUT dnl vim: set sw=4 ts=4 noexpandtab : rifiuti2-0.6.1/dist-win.mk000066400000000000000000000033731252727005000153500ustar00rootroot00000000000000# # Make file fragment for rifiuti2 -- maintainer only # Handle binary distribution for Windows # dist-win: win-pkg-data win-pkg/x86 win-pkg/x64 cd win-pkg && zip -9 -r $(abs_top_builddir)/$(distdir)-win.zip . win-pkg-data: win-pkg/rifiuti-l10n win-pkg/README.html win-pkg/README.html: $(top_srcdir)/src/rifiuti.1 set -e ;\ tmpfile1=$$(mktemp) ;\ tmpfile2=$$(mktemp) ;\ groff -Thtml -mman $< | \ sed -r '/####CHANGELOG####/ s@( $$tmpfile1 ;\ ( sed -e '0,/^##[^#]/d; /^----/,$$d;' $(abs_top_srcdir)/NEWS.md | \ markdown | sed -e 's/h[0-9]>/strong>/g;'; ) > $$tmpfile2 ;\ ( sed -e '/^####CHANGELOG####/,$$d' $$tmpfile1; cat $$tmpfile2; \ sed -e '0,/^####CHANGELOG####/d' $$tmpfile1 ) > $@ ;\ rm -f $$tmpfile1 $$tmpfile2 win-pkg/rifiuti-l10n: $(top_srcdir)/po/$(GETTEXT_PACKAGE).pot cd po && $(MAKE) install gnulocaledir=$(abs_top_builddir)/$@ cp $< $(abs_top_builddir)/$@ win-pkg/x86: test "`objdump -f $(top_builddir)/src/rifiuti$(EXEEXT) | \ awk '/file format/ {print $$NF}'`" = "pei-i386" objdump -f $(top_builddir)/src/rifiuti$(EXEEXT) | grep -q "HAS_RELOC" $(MKDIR_P) $@ strip --strip-unneeded -o $@/rifiuti$(EXEEXT) \ $(top_builddir)/src/rifiuti$(EXEEXT) strip --strip-unneeded -o $@/rifiuti-vista$(EXEEXT) \ $(top_builddir)/src/rifiuti-vista$(EXEEXT) win-pkg/x64: test "`objdump -f $(top_builddir)/src/rifiuti$(EXEEXT) | \ awk '/file format/ {print $$NF}'`" = "pei-x86-64" objdump -f $(top_builddir)/src/rifiuti$(EXEEXT) | grep -q "HAS_RELOC" $(MKDIR_P) $@ strip --strip-unneeded -o $@/rifiuti$(EXEEXT) \ $(top_builddir)/src/rifiuti$(EXEEXT) strip --strip-unneeded -o $@/rifiuti-vista$(EXEEXT) \ $(top_builddir)/src/rifiuti-vista$(EXEEXT) .PHONY: win-pkg-data dist-win rifiuti2-0.6.1/docs/000077500000000000000000000000001252727005000142035ustar00rootroot00000000000000rifiuti2-0.6.1/docs/AUTHORS000066400000000000000000000001661252727005000152560ustar00rootroot00000000000000Current version: Copyright (C) 2007, 2015 Abel Cheung Original version of rifiuti: Copyright (C) 2003 Keith J. Jones rifiuti2-0.6.1/docs/ChangeLog.old000066400000000000000000000112151252727005000165320ustar00rootroot00000000000000* * * This file is now obsolete. All future changes are available from Git log. * * ========== 0.5.1 release ========== 2008-11-30 Abel Cheung * src/rifiuti-vista.c: Warn if recycle bin contains any special file that shouldn't appear in recycle bin at all. 2008-11-25 Anthony Wong * test/: Add 3 test cases and results. 2008-11-23 Anthony Wong * debian/: Check in debian packaging related files. 2008-11-21 Anthony Wong * src/rifiuti.1: Add manpage. 2007-10-14 Abel Cheung * configure.ac: Post-release version bump. ========== 0.5.0 release ========== 2007-10-07 Abel Cheung * TODO: New file. 2007-10-07 Abel Cheung * src/*.h: Include inttypes.h instead of stdint.h. * src/rifiuti.c: Minor string changes. 2007-10-05 Abel Cheung * src/rifiuti.c, src/rifiuti-vista.c: - Drop hardcoded i18n parameters. * README: Minor changes. 2007-10-04 Abel Cheung * THANKS: New file. * AUTHORS, NEWS, README: Updated. 2007-10-04 Abel Cheung * configure.ac: - Disable AC_TYPE_UINT{32,64}_T check, not available in older autoconf. 2007-10-04 Abel Cheung * configure.ac: - Drop $localedir definition, AM_GLIB_GNU_GETTEXT should do it. * src/Makefile.am, po/ChangeLog: - Now make distcheck works. 2007-10-04 Abel Cheung * configure.ac: Check for install prog as well. * autogen.sh: Add file (thanks to sample from dia). 2007-10-04 Abel Cheung * AUTHORS, COPYING, INSTALL, NEWS, README, configure.ac, po, Makefile.am, src/Makefile.am: - Add autotools structure. 2007-09-28 Abel Cheung * src/rifiuti-vista.c: Implement --always-utf8 option. 2007-09-28 Abel Cheung * src/rifiuti.c: Some string changes. 2007-09-24 Abel Cheung * src/rifiuti-vista.dtd: New file. * src/rifiuti-vista.c: Implement XML output mode. 2007-09-24 Abel Cheung * src/rifiuti-vista.c, src/rifiuti-vista.h: - New version for Vista recycle bin analysis. 2007-09-22 Abel Cheung * src/utils.c, src/utils.h: New file. * src/rifiuti.c: - Move win_filetime_to_epoch() and shared enum's to utils.[ch]. - Forced UTF-8 output is implemented. - print_header(), print_footer(), print_record() become private functions. * src/Makefile: Cope for necessary changes. 2007-09-21 Abel Cheung * src/rifiuti.c: - Reorganize options into separate groups. - Make XML output mode conflict with any plain text option. - Mark some strings for translation. 2007-09-20 Abel Cheung * src/rifiuti.c: - Build fix for MinGW (avoid GNU-only calls). 2007-09-20 Abel Cheung * src/rifiuti.c (print_record): - For Win98 INFO2 file, try to convert from legacy file name to UTF-8 in XML display mode. - Very minor string changes. 2007-09-17 Abel Cheung * src/rifiuti.c: - Show warning message if print_* functions are called with unknown output format (highly unlikely). - Some calls to guard against failure in charset conversion. - Add --from-encoding option to specify encoding to convert from, which is useful ONLY when INFO2 is created by Win98 (thus no unicode file name), and output is in XML format (which is unicode only). Does nothing for now. 2007-09-17 Abel Cheung * src/rifiuti.dtd: New file. * src/rifiuti.h: Add output format enum. * src/rifiuti.c: - (print_header, print_footer, print_record) New functions. - Add support for XML output format. 2007-09-16 Abel Cheung * src/rifiuti.c: - Add -o option to specify output file name. - Supports reading data from stdin. - Use file stream throughout the whole file, drop usage of file descriptor. - Change fprintf into fputs or g_fprintf when the most appropriate one fits. 2007-09-14 Abel Cheung * src/rifiuti.c: - Cope with the case when deleted file is from a network share (thus first char is backslash). - Defines _GNU_SOURCE to avoid warning when compiling under Linux. - Replace g_strdup_printf with g_snprintf to avoid copying exceedingly large string. - Warn if end of file is not a proper footer (exactly 4 bytes). 2007-09-09 Abel Cheung * Makefile: Reorder gcc arguments to fix compilation in cygwin. 2007-09-08 Abel Cheung * First check-in of my modified rifiuti. rifiuti2-0.6.1/docs/Compile.md000066400000000000000000000056001252727005000161160ustar00rootroot00000000000000## Compile requirements Bootstraping process can be done for Unix/Linux like OS released since 2010. * `glib` ≥ 2.16 (deveopment headers and libraries, available since 2008) * `pkg-config` (or its replacement on *BSD, `pkgconf`) * basic autotools-based development toolchain * C compiler — both `gcc` and `clang` are tested * make * automake ≥ 1.11 * autoconf A few extra programs are also checked (`perl`, `iconv`, `xmllint`), but they are for testsuite only and not necessary for building software. ## Compile procedure on Linux / BSD First execute `autogen.sh` to generate autotools files necessary for building software: ``` $ ./autogen.sh ``` After that, everything follows the usual autotools procedure: ``` $ ./configure && make check ``` *Optional*: install software with administrator privilege: ``` # make install ``` `rifiuti2` can be used even without installing, only that there would be no translations in messages and result. If compile or `make check` fails, please report problem to Github page, describing your OS and compile environment, and attach `test/testsuite.log` on Gist. ## Compile procedure on MinGW / MSYS `rifiuti2` has only been thoroughly tested on [MSYS2][1], a Unix-like environment based on [mingw-w64][2], akin to the old [MSYS 1.0][5] which was mingw32 based. There are other mingw-w64 based distributions like [Cygwin][3] and [win-build][4], your mileage may vary. Follow the following procedure to setup MSYS2 necessary for building `rifiuti2`: 1. Grab installer from [MSYS2 page][1], and follow all instructions on that page. In particular, please **tread carefully** when starting to use `pacman` for upgrading packages. [Some pitfalls may result from careless update.][6] (Read section III of this page carefully) 2. After basic setup is done, grab Glib runtime and development packages - Install with `pacman -Sy mingw-w64-x86_64-glib2` for 64bit build, and/or - Install with `pacman -Sy mingw-w64-i686-glib2` for 32bit build 3. If one intend to run `rifiuti2` outside of MSYS bash environment (such as under Windows `cmd`), either: 1. Link program statically with `make LDFLAGS="-static"`. In this case `/mingw{64,32}/lib/pkgconfig/glib-2.0.pc` need to be manually edited to append `-liconv` to `Libs.private` line. 2. Copy all necessary libraries under `/mingw64/bin` or `/mingw32/bin` to the same folder `rifiuti` binaries reside in **Note 1**: Windows binary distributed on Github are statically linked to existing version of glib available in MSYS2 — 2.44 as of May 2015. **Note 2**: MSYS 1.0 might still be able to compile `rifiuti2`, but no effort will be made to ensure it's working at all. [1]: https://msys2.github.io/ [2]: http://mingw-w64.yaxm.org/doku.php [3]: https://cygwin.com/ [4]: http://win-builds.org/doku.php [5]: http://www.mingw.org/wiki/msys [6]: https://sourceforge.net/p/msys2/wiki/MSYS2%20installation/ rifiuti2-0.6.1/docs/LICENSE000066400000000000000000000031411252727005000152070ustar00rootroot00000000000000Other than autotools generated files (which are covered by GNU licesne), all other files are available through the following 3-clause BSD license. ================================================================= Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rifiuti2-0.6.1/docs/THANKS000066400000000000000000000007451252727005000151240ustar00rootroot00000000000000Obviously, all credits must go to Keith Jones and all the folks at Foundstone. Without their analysis on Windows Recycle Bin it is much more difficult to fully dissect it. Their elaborate white paper and original version of rifiuti are available from ODESSA project: http://odessa.sourceforge.net/ But there are more people to say thanks: Hilda Chan (Providing Chinese Vista Recycle Bin sample data) Anthony Wong (Providing manpage & original Debian packaging) rifiuti2-0.6.1/git.mk000066400000000000000000000235671252727005000144040ustar00rootroot00000000000000# git.mk # # Copyright 2009, Red Hat, Inc. # Copyright 2010,2011,2012,2013 Behdad Esfahbod # Written by Behdad Esfahbod # # Copying and distribution of this file, with or without modification, # is permitted in any medium without royalty provided the copyright # notice and this notice are preserved. # # The latest version of this file can be downloaded from: # https://raw.github.com/behdad/git.mk/master/git.mk # Bugs, etc, should be reported upstream at: # https://github.com/behdad/git.mk # # To use in your project, import this file in your git repo's toplevel, # then do "make -f git.mk". This modifies all Makefile.am files in # your project to -include git.mk. Remember to add that line to new # Makefile.am files you create in your project, or just rerun the # "make -f git.mk". # # This enables automatic .gitignore generation. If you need to ignore # more files, add them to the GITIGNOREFILES variable in your Makefile.am. # But think twice before doing that. If a file has to be in .gitignore, # chances are very high that it's a generated file and should be in one # of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. # # The only case that you need to manually add a file to GITIGNOREFILES is # when remove files in one of mostlyclean-local, clean-local, distclean-local, # or maintainer-clean-local make targets. # # Note that for files like editor backup, etc, there are better places to # ignore them. See "man gitignore". # # If "make maintainer-clean" removes the files but they are not recognized # by this script (that is, if "git status" shows untracked files still), send # me the output of "git status" as well as your Makefile.am and Makefile for # the directories involved and I'll diagnose. # # For a list of toplevel files that should be in MAINTAINERCLEANFILES, see # Makefile.am.sample in the git.mk git repo. # # Don't EXTRA_DIST this file. It is supposed to only live in git clones, # not tarballs. It serves no useful purpose in tarballs and clutters the # build dir. # # This file knows how to handle autoconf, automake, libtool, gtk-doc, # gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu. # # This makefile provides the following targets: # # - all: "make all" will build all gitignore files. # - gitignore: makes all gitignore files in the current dir and subdirs. # - .gitignore: make gitignore file for the current dir. # - gitignore-recurse: makes all gitignore files in the subdirs. # # KNOWN ISSUES: # # - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the # submodule doesn't find us. If you have configure.{in,ac} files in # subdirs, add a proxy git.mk file in those dirs that simply does: # "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. # And add those files to git. See vte/gnome-pty-helper/git.mk for # example. # ############################################################################### # Variables user modules may want to add to toplevel MAINTAINERCLEANFILES: ############################################################################### # # Most autotools-using modules should be fine including this variable in their # toplevel MAINTAINERCLEANFILES: GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \ $(srcdir)/aclocal.m4 \ $(srcdir)/autoscan.log \ $(srcdir)/configure.scan \ `AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \ test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \ for x in \ ar-lib \ compile \ config.guess \ config.sub \ depcomp \ install-sh \ ltmain.sh \ missing \ mkinstalldirs \ test-driver \ ; do echo "$$AUX_DIR/$$x"; done` \ `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \ head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done` # # All modules should also be fine including the following variable, which # removes automake-generated Makefile.in files: GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \ `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \ while read f; do \ case $$f in Makefile|*/Makefile) \ test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \ done` # # Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this, # though it's harmless to include regardless. GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \ `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ for x in \ libtool.m4 \ ltoptions.m4 \ ltsugar.m4 \ ltversion.m4 \ lt~obsolete.m4 \ ; do echo "$$MACRO_DIR/$$x"; done; \ fi` ############################################################################### # Default rule is to install ourselves in all Makefile.am files: ############################################################################### git-all: git-mk-install git-mk-install: @echo "Installing git makefile" @any_failed=; \ find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ if grep 'include .*/git.mk' $$x >/dev/null; then \ echo "$$x already includes git.mk"; \ else \ failed=; \ echo "Updating $$x"; \ { cat $$x; \ echo ''; \ echo '-include $$(top_srcdir)/git.mk'; \ } > $$x.tmp || failed=1; \ if test x$$failed = x; then \ mv $$x.tmp $$x || failed=1; \ fi; \ if test x$$failed = x; then : else \ echo "Failed updating $$x"; >&2 \ any_failed=1; \ fi; \ fi; done; test -z "$$any_failed" .PHONY: git-all git-mk-install ############################################################################### # Actual .gitignore generation: ############################################################################### $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk @echo "git.mk: Generating $@" @{ \ if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ for x in \ $(DOC_MODULE)-decl-list.txt \ $(DOC_MODULE)-decl.txt \ tmpl/$(DOC_MODULE)-unused.sgml \ "tmpl/*.bak" \ xml html \ ; do echo "/$$x"; done; \ FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ fi; \ if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ for lc in $(DOC_LINGUAS); do \ for x in \ $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ $(DOC_PAGES) \ $(DOC_INCLUDES) \ ; do echo "/$$lc/$$x"; done; \ done; \ for x in \ $(_DOC_OMF_ALL) \ $(_DOC_DSK_ALL) \ $(_DOC_HTML_ALL) \ $(_DOC_MOFILES) \ $(DOC_H_FILE) \ "*/.xml2po.mo" \ "*/*.omf.out" \ ; do echo /$$x; done; \ fi; \ if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ for lc in $(HELP_LINGUAS); do \ for x in \ $(HELP_FILES) \ "$$lc.stamp" \ "$$lc.mo" \ ; do echo "/$$lc/$$x"; done; \ done; \ fi; \ if test "x$(gsettings_SCHEMAS)" = x; then :; else \ for x in \ $(gsettings_SCHEMAS:.xml=.valid) \ $(gsettings__enum_file) \ ; do echo "/$$x"; done; \ fi; \ if test -f $(srcdir)/po/Makefile.in.in; then \ for x in \ po/Makefile.in.in \ po/Makefile.in.in~ \ po/Makefile.in \ po/Makefile \ po/Makevars.template \ po/POTFILES \ po/Rules-quot \ po/stamp-it \ po/.intltool-merge-cache \ "po/*.gmo" \ "po/*.header" \ "po/*.mo" \ "po/*.sed" \ "po/*.sin" \ po/$(GETTEXT_PACKAGE).pot \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ ; do echo "/$$x"; done; \ fi; \ if test -f $(srcdir)/configure; then \ for x in \ autom4te.cache \ configure \ config.h \ stamp-h1 \ libtool \ config.lt \ ; do echo "/$$x"; done; \ fi; \ if test "x$(DEJATOOL)" = x; then :; else \ for x in \ $(DEJATOOL) \ ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ echo /site.exp; \ fi; \ if test "x$(am__dirstamp)" = x; then :; else \ echo "$(am__dirstamp)"; \ fi; \ if test "x$(LTCOMPILE)" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ for x in \ "*.lo" \ ".libs" "_libs" \ ; do echo "$$x"; done; \ fi; \ for x in \ .gitignore \ $(GITIGNOREFILES) \ $(CLEANFILES) \ $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ so_locations \ $(MOSTLYCLEANFILES) \ $(TEST_LOGS) \ $(TEST_LOGS:.log=.trs) \ $(TEST_SUITE_LOG) \ "*.$(OBJEXT)" \ $(DISTCLEANFILES) \ $(am__CONFIG_DISTCLEAN_FILES) \ $(CONFIG_CLEAN_FILES) \ TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ "*.tab.c" \ $(MAINTAINERCLEANFILES) \ $(BUILT_SOURCES) \ $(DEPDIR) \ $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ $(filter %_vala.stamp,$(DIST_COMMON)) \ $(filter %.vapi,$(DIST_COMMON)) \ $(filter %$(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))),$(DIST_COMMON)) \ Makefile \ Makefile.in \ "*.orig" \ "*.rej" \ "*.bak" \ "*~" \ ".*.sw[nop]" \ ".*.un~" \ ".dirstamp" \ ; do echo "/$$x"; done; \ } | \ sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ sed 's@/[.]/@/@g' | \ LC_ALL=C sort | uniq > $@.tmp && \ mv $@.tmp $@; all: $(srcdir)/.gitignore gitignore-recurse-maybe gitignore: $(srcdir)/.gitignore gitignore-recurse gitignore-recurse-maybe: @for subdir in $(DIST_SUBDIRS); do \ case " $(SUBDIRS) " in \ *" $$subdir "*) :;; \ *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ esac; \ done gitignore-recurse: @for subdir in $(DIST_SUBDIRS); do \ test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ done maintainer-clean: gitignore-clean gitignore-clean: -rm -f $(srcdir)/.gitignore .PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe rifiuti2-0.6.1/po/000077500000000000000000000000001252727005000136715ustar00rootroot00000000000000rifiuti2-0.6.1/po/ChangeLog000066400000000000000000000000001252727005000154310ustar00rootroot00000000000000rifiuti2-0.6.1/po/LINGUAS000066400000000000000000000000061252727005000147120ustar00rootroot00000000000000zh_HK rifiuti2-0.6.1/po/POTFILES.in000066400000000000000000000000561252727005000154470ustar00rootroot00000000000000src/rifiuti-vista.c src/rifiuti.c src/utils.c rifiuti2-0.6.1/po/zh_HK.po000066400000000000000000000336741252727005000152510ustar00rootroot00000000000000# Traditional Chinese (Hong Kong) translation of rifiuti. # Copyright (C) 2015 Abel Cheung # This file is distributed under the same license as the rifiuti2 package. # Abel Cheung , 2015. # msgid "" msgstr "" "Project-Id-Version: rifiuti2 0.6.0\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=glib&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2015-05-13 21:00+0800\n" "PO-Revision-Date: 2015-05-13 20:58China Standard Time\n" "Last-Translator: Abel Cheung \n" "Language-Team: Chinese (Hong Kong)\n" "Language: Chinese (Hong Kong)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../../src/rifiuti-vista.c:57 ../../src/rifiuti.c:68 msgid "Write output to FILE" msgstr "輸出至 <檔案>" #: ../../src/rifiuti-vista.c:57 ../../src/rifiuti.c:69 msgid "FILE" msgstr "檔案" #: ../../src/rifiuti-vista.c:59 ../../src/rifiuti.c:71 msgid "Output in XML format instead of tab-delimited values" msgstr "輸出改為 XML 模式,而非 Tab 字元分隔的文字模式" #: ../../src/rifiuti-vista.c:61 ../../src/rifiuti.c:76 msgid "Present deletion time in time zone of local system (default is UTC)" msgstr "以本系統的時區顯示檔案刪除時間 (預設為 UTC)" #: ../../src/rifiuti-vista.c:64 ../../src/rifiuti.c:79 msgid "Print version information and exit" msgstr "顯示版本資料並離開" #: ../../src/rifiuti-vista.c:66 msgid "$Recycle.bin folder or file name" msgstr "$Recycle.bin 目錄或檔案名稱" #: ../../src/rifiuti-vista.c:73 ../../src/rifiuti.c:88 msgid "String to use as delimiter (TAB by default)" msgstr "作為區隔欄位用的字串 (預設為 TAB)" #: ../../src/rifiuti-vista.c:73 ../../src/rifiuti.c:88 msgid "STRING" msgstr "字串" #: ../../src/rifiuti-vista.c:75 ../../src/rifiuti.c:90 msgid "Don't show header info" msgstr "不顯示檔頭資料" #: ../../src/rifiuti-vista.c:77 ../../src/rifiuti.c:92 msgid "Always display result in UTF-8 encoding" msgstr "輸出結果永遠用 UTF-8 編碼顯示" #: ../../src/rifiuti-vista.c:99 #, c-format msgid "File is truncated, or probably not a $Recycle.bin index file.\n" msgstr "檔案被截短了,又或者根本不是 $Recycle.bin 索引檔案。\n" #. TRANSLATOR COMMENT: the variable is function name #: ../../src/rifiuti-vista.c:109 ../../src/rifiuti.c:125 #, c-format msgid "%s(): fread() failed when reading version info" msgstr "%s(): 當讀取版本資料時,fread() 發生錯誤" #. TRANSLATOR COMMENT: the variable is function name #: ../../src/rifiuti-vista.c:132 #, c-format msgid "%s(): fread() failed when reading file name length" msgstr "%s(): 當讀取檔案名稱長度時,fread() 發生錯誤" #: ../../src/rifiuti-vista.c:146 #, c-format msgid "" "File is not supported, or it is probably not a $Recycle.bin index file.\n" msgstr "檔案格式不支援,又或者根本不是 $Recycle.bin 索引檔案。\n" #: ../../src/rifiuti-vista.c:153 #, c-format msgid "Index file expected size and real size do not match.\n" msgstr "索引檔實際大小和預期不符。\n" #: ../../src/rifiuti-vista.c:211 #, c-format msgid "Error converting file name from %s encoding to UTF-8 encoding: %s" msgstr "無法將檔案名稱從 %s 編碼轉換為 UTF-8 編碼:%s" #: ../../src/rifiuti-vista.c:234 ../../src/rifiuti.c:466 #, c-format msgid "Error getting metadata of file '%s': %s\n" msgstr "無法獲取 ‘%s’ 檔案的相關資料:%s\n" #: ../../src/rifiuti-vista.c:241 ../../src/rifiuti.c:473 #, c-format msgid "Error opening file '%s' for reading: %s\n" msgstr "無法開啟檔案 ‘%s’ 讀取內容:%s\n" #: ../../src/rifiuti-vista.c:248 #, c-format msgid "File '%s' fails validation.\n" msgstr "檔案 ‘%s’ 不通過檢驗。\n" #. #. * TRANSLATOR COMMENT: 1st parameter is function name, #. * 2nd is file name, 3rd is error message #. #: ../../src/rifiuti-vista.c:261 #, c-format msgid "%s(): fread() failed when reading content of file '%s': %s\n" msgstr "%s(): 讀取檔案 ‘%s’ 內容時,fread() 失敗:%s\n" #. VERY wrong if reaching here. Version info has already been filtered once #: ../../src/rifiuti-vista.c:283 #, c-format msgid "Version info for '%s' still wrong despite file validation." msgstr "即使通過檢驗後,‘%s’ 的版本依然是錯誤的。" #: ../../src/rifiuti-vista.c:315 #, c-format msgid "Error opening directory '%s': %s\n" msgstr "無法開啟 ‘%s’ 目錄:%s\n" #: ../../src/rifiuti-vista.c:415 msgid "DIR_OR_FILE" msgstr "目錄或檔案" #: ../../src/rifiuti-vista.c:417 msgid "" "Parse index files in C:\\$Recycle.bin style folder and dump recycle bin " "data. Can also dump a single index file." msgstr "" "解析 C:\\$Recycle.bin 形式的目錄裏面的索引檔,並顯示其中的回收筒資料。也可以" "解析單一的索引檔。" #: ../../src/rifiuti-vista.c:421 ../../src/rifiuti.c:303 #, c-format msgid "Report bugs to %s" msgstr "如程式有問題,請在 %s 報告" #: ../../src/rifiuti-vista.c:427 ../../src/rifiuti.c:309 msgid "Plain text output options:" msgstr "文字模式輸出選項:" #: ../../src/rifiuti-vista.c:428 ../../src/rifiuti.c:310 msgid "Show plain text output options" msgstr "顯示和文字模式輸出有關的選項" #: ../../src/rifiuti-vista.c:468 ../../src/rifiuti.c:354 #, c-format msgid "Error parsing options: %s\n" msgstr "無法解析選項:%s\n" #: ../../src/rifiuti-vista.c:482 #, c-format msgid "" "Must specify exactly one directory containing $Recycle.bin index files, or " "one such index file, as argument.\n" "\n" msgstr "" "選項中必須指定剛好一個載有 $Recycle.bin 索引檔案的目錄,或者剛好一個這種檔" "案,不多不少。\n" "\n" #: ../../src/rifiuti-vista.c:485 ../../src/rifiuti.c:369 #, c-format msgid "Run program with '-?' option for more info.\n" msgstr "有關詳情請在執行程式時加上 ‘-?’ 選項。\n" #: ../../src/rifiuti-vista.c:494 ../../src/rifiuti.c:378 #, c-format msgid "Error opening file '%s' for writing: %s\n" msgstr "無法開啟檔案 ‘%s’ 來寫入資料:%s\n" #: ../../src/rifiuti-vista.c:507 ../../src/rifiuti.c:391 #, c-format msgid "Plain text format options can not be used in XML mode.\n" msgstr "文字模式的選項不可以配合 XML 模式使用。\n" #: ../../src/rifiuti-vista.c:544 ../../src/rifiuti.c:454 #, c-format msgid "'%s' does not exist.\n" msgstr "‘%s’ 不存在。\n" #: ../../src/rifiuti-vista.c:557 #, c-format msgid "" "No files with name pattern '%s' are found in directory. Probably not a " "$Recycle.bin directory.\n" msgstr "目錄中沒有名稱像 ‘%s’ 的檔案。可能根本不是 $Recycle.bin 目錄。\n" #: ../../src/rifiuti-vista.c:571 #, c-format msgid "'%s' is not a normal file or directory.\n" msgstr "‘%s’ 不是一般檔案或目錄。\n" #: ../../src/rifiuti-vista.c:581 msgid "No valid recycle bin index file found.\n" msgstr "找不到合符格式的回收筒索引檔。\n" #: ../../src/rifiuti.c:73 msgid "Show legacy (8.3) filename if available and specify its CODEPAGE" msgstr "如果可能的話,顯示舊式 (8.3) 檔案路徑,並指定該用哪個 <編碼頁> 處理" #: ../../src/rifiuti.c:74 msgid "CODEPAGE" msgstr "編碼頁" #: ../../src/rifiuti.c:81 msgid "INFO2 file name" msgstr "INFO2 檔案名稱" #: ../../src/rifiuti.c:115 #, c-format msgid "File is truncated, or probably not an INFO2 file.\n" msgstr "檔案被截短了,又或者根本不是 INFO2 檔案。\n" #. TRANSLATOR COMMENT: the variable is function name #: ../../src/rifiuti.c:136 #, c-format msgid "%s(): fread() failed when reading recordsize" msgstr "%s(): 當讀取 recordsize 時 fread() 失敗" #: ../../src/rifiuti.c:150 ../../src/rifiuti.c:173 msgid "Invalid record size for this version of INFO2" msgstr "回收筒每項紀錄的長度和這個版本的 INFO2 應有的不符" #: ../../src/rifiuti.c:155 #, c-format msgid "" "This INFO2 file was produced on a Windows 98. Please specify codepage of " "concerned system with '-l' or '--legacy-filename' option.\n" "\n" msgstr "" "這個 INFO2 檔來自 Windows 98。請用 ‘-l’ 或 ‘--legacy-filename’ 選項指定原本的" "系統的編碼頁。\n" "\n" #. TRANSLATOR COMMENT: use suitable example from YOUR language & code page #: ../../src/rifiuti.c:159 #, c-format msgid "" "For example, if file name was expected to contain accented latin characters, " "use '-l CP1252' option; or in case of Japanese characters, '-l CP932'.\n" "\n" "Code pages (or any other encodings) supported by 'iconv' can be used.\n" msgstr "" "舉個例子,如果預期檔名應該有正體中文,請使用 ‘-l CP950’ 選項;如果有簡體的," "則是 ‘-l CP936’。\n" "\n" "任何 ‘iconv’ 支援的編碼和編碼頁都可以使用。\n" #: ../../src/rifiuti.c:181 #, c-format msgid "File is not supported, or it is probably not an INFO2 file.\n" msgstr "檔案格式不支援,又或者根本不是 INFO2 檔案。\n" #: ../../src/rifiuti.c:218 #, c-format msgid "Invalid drive number (0x%X) for record %u." msgstr "第 %2$u 項紀錄中的磁碟號碼 (0x%1$X) 不合法。" #: ../../src/rifiuti.c:257 #, c-format msgid "" "Error converting file name from %s encoding to UTF-8 encoding for record %u: " "%s" msgstr "無法將第 %2$u 項紀錄的檔案名稱從 %1$s 編碼轉換為 UTF-8 編碼:%3$s" #: ../../src/rifiuti.c:301 msgid "Parse INFO2 file and dump recycle bin data." msgstr "分析 INFO2 檔案並顯示資源回收筒的內容。" #: ../../src/rifiuti.c:368 #, c-format msgid "" "Must specify exactly one INFO2 file as argument.\n" "\n" msgstr "" "必須指定剛好一個 INFO2 檔作為參數。\n" "\n" #: ../../src/rifiuti.c:404 #, c-format msgid "" "'%s' is not a valid code page or encoding. Only those supported by 'iconv' " "can be used.\n" msgstr "‘%s’ 不是正確的編碼或編碼頁。只有 ‘iconv’ 支援的才可以使用。\n" #: ../../src/rifiuti.c:408 #, c-format msgid "" "Please visit following web page for a list closely resembling encodings " "supported by rifiuti:\n" "\n" "\t%s\n" "\n" msgstr "" "想獲取 rifiuti 支援的編碼,以下網頁載有近似的清單:\n" "\n" "\t%s\n" "\n" #: ../../src/rifiuti.c:414 #, c-format msgid "Please execute 'iconv -l' for list of supported encodings.\n" msgstr "要獲取程式支援的編碼,請執行 ‘iconv -l’。\n" #: ../../src/rifiuti.c:460 #, c-format msgid "'%s' is not a normal file.\n" msgstr "‘%s’ 不是一般檔案。\n" #: ../../src/rifiuti.c:504 #, c-format msgid "Failed to read next record: %s" msgstr "無法讀取下一項紀錄:%s" #: ../../src/utils.c:223 #, c-format msgid "Recycle bin path: '%s'" msgstr "資源回收筒路徑:‘%s’" #. TRANSLATOR COMMENT: Error when trying to determine recycle bin version #: ../../src/utils.c:230 msgid "??? (empty folder)" msgstr "??? (空白目錄)" #. TRANSLATOR COMMENT: Error when trying to determine recycle bin version #: ../../src/utils.c:234 msgid "??? (version inconsistent)" msgstr "??? (版本不一致)" #: ../../src/utils.c:239 #, c-format msgid "Version: %s" msgstr "版本:%s" #: ../../src/utils.c:246 #, c-format msgid "Index%sDeleted Time%sGone?%sSize%sPath" msgstr "索引碼%s回收時間%s已刪?%s大小%s路徑" #: ../../src/utils.c:250 #, c-format msgid "Index%sDeleted Time%sSize%sPath" msgstr "索引%s回收時間%s大小%s路徑" #: ../../src/utils.c:298 #, c-format msgid "Error formatting file deletion time for record index %s." msgstr "無法整理紀錄 %s 的檔案刪除時間成為可顯示的形式。" #: ../../src/utils.c:307 ../../src/utils.c:326 msgid "(File name not representable in UTF-8 encoding)" msgstr "(檔案名稱無法用 UTF-8 編碼顯示)" #: ../../src/utils.c:321 #, c-format msgid "Error converting file name from %s encoding to UTF-8 for index %s: %s" msgstr "無法將紀錄 %2$s 的檔案名稱從 %1$s 編碼轉換為 UTF-8 編碼:%3$s" #: ../../src/utils.c:337 msgid "Yes" msgstr "是" #: ../../src/utils.c:337 msgid "No" msgstr "否" #: ../../src/utils.c:350 #, c-format msgid "Error converting path name to display for record %s: %s" msgstr "無法將紀錄 %s 的檔案名稱轉換為可顯示的內容:%s" #: ../../src/utils.c:354 msgid "(File name not representable in current language)" msgstr "(檔案名稱無法用目前語言表示)" #: ../../src/utils.c:389 #, c-format msgid "%s is distributed under the BSD 3-Clause License.\n" msgstr "%s 根據 3-clause BSD 授權條款發行。\n" #. TRANSLATOR COMMENT: 1st argument is software name, 2nd is official URL #: ../../src/utils.c:392 #, c-format msgid "" "Information about %s can be found on\n" "\n" "\t%s\n" msgstr "" "以下網站有更多有關 %s 的資料:\n" "\n" "\t%s\n" #: ../../src/utils.c:450 msgid "This is a command line application" msgstr "這個是命令提示字元模式下的應用程式" #~ msgid "" #~ "Output in XML format instead of tab-delimited values (plain text options " #~ "disallowed in this case)" #~ msgstr "" #~ "輸出改為 XML 模式,而非 Tab 字元分隔的文字模式 (這情況下不允許使用文字模式" #~ "的選項)" #~ msgid "File names" #~ msgstr "檔名" #~ msgid "Error converting path name to display: %s" #~ msgstr "無法將檔案名稱轉換為可顯示的內容:%s" #~ msgid "Recycle bin file/dir: '%s'" #~ msgstr "資源回收筒檔案/目錄:‘%s’" #~ msgid "Error converting file name to UTF-8 encoding: %s" #~ msgstr "無法將檔案名稱轉換為 UTF-8 編碼:%s" #~ msgid "Index file '%s' has incorrect size" #~ msgstr "索引檔 ‘%s’ 的大小不符合規定" #~ msgid "Error formatting file deletion time for file '%s'." #~ msgstr "無法整理索引檔 ‘%s’ 中的檔案刪除時間成為可顯示的形式。" #~ msgid "" #~ "The assumed file name character set when no unicode file name is present " #~ "in INFO2 record (mandatory if INFO2 file is created by Win98, ignored " #~ "otherwise)" #~ msgstr "" #~ "當 INFO2 紀錄中沒有 unicode 檔名時,假設檔名來自何種編碼 (如果 INFO2 檔案" #~ "來自 Win98,此選項是必要的,反之則會被忽略)" #~ msgid "ENC" #~ msgstr "編碼" rifiuti2-0.6.1/src/000077500000000000000000000000001252727005000140425ustar00rootroot00000000000000rifiuti2-0.6.1/src/.indent.pro000066400000000000000000000010521252727005000161210ustar00rootroot00000000000000/* * GNU .indent.pro file for Rifiuti2 * Sources still need some manual edit to achieve desired * result, where tabs of any size would still look good. * - Some continuation lines have tabs partially replaced by spaces. * - Code after switch/case are indented by 2 spaces instead of a tab. */ -gnu -bfda -bli0 -bls -cbi2 -cli2 -cs -di16 -hnl -i4 -l80 -psl -ts4 -ut /* Declarations */ -T FILE -T rbin_type -T rbin_struct -T uint32_t -T uint64_t -T int64_t -T off_t /* Glib types */ -T GStatBuf -T GSList -T gboolean -T GLogLevelFlags -T gpointer rifiuti2-0.6.1/src/Makefile.am000066400000000000000000000016451252727005000161040ustar00rootroot00000000000000AM_CPPFLAGS = \ -I$(srcdir) \ $(GLIB_CFLAGS) \ -DLOCALEDIR=\"$(localedir)\" \ -DG_LOG_DOMAIN=\"$(PACKAGE)\" bin_PROGRAMS = rifiuti rifiuti-vista man_MANS = rifiuti.1 EXTRA_DIST = rifiuti.1 rifiuti_SOURCES = \ rifiuti.c \ rifiuti.h \ utils.c \ utils.h rifiuti_LDADD = $(GLIB_LIBS) rifiuti_vista_SOURCES = \ rifiuti-vista.c \ rifiuti-vista.h \ utils.c \ utils.h rifiuti_vista_LDADD = $(GLIB_LIBS) if OS_WINDOWS rifiuti_LDADD += -luser32 rifiuti_vista_LDADD += -luser32 endif install-data-hook: cd $(DESTDIR)$(mandir)/man1 && $(LN_S) rifiuti.1 rifiuti-vista.1 uninstall-hook: -rm -f $(DESTDIR)$(mandir)/man1/rifiuti-vista.1 -include $(top_srcdir)/git.mk rifiuti2-0.6.1/src/rifiuti-vista.c000066400000000000000000000445361252727005000170210ustar00rootroot00000000000000/* * Copyright (C) 2007, 2015 Abel Cheung. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" #include #include #include "utils.h" #include #include #include "rifiuti-vista.h" char *delim = NULL; static char **fileargs = NULL; static char *outfilename = NULL; char *legacy_encoding = NULL; int output_format = OUTPUT_CSV; static gboolean no_heading = FALSE; static gboolean xml_output = FALSE; gboolean always_utf8 = FALSE; gboolean has_unicode_filename = TRUE; gboolean use_localtime = FALSE; static gboolean do_print_version = FALSE; static GOptionEntry mainoptions[] = { {"output", 'o', 0, G_OPTION_ARG_FILENAME, &outfilename, N_("Write output to FILE"), N_("FILE")}, {"xml", 'x', 0, G_OPTION_ARG_NONE, &xml_output, N_("Output in XML format instead of tab-delimited values"), NULL}, {"localtime", 'z', 0, G_OPTION_ARG_NONE, &use_localtime, N_("Present deletion time in time zone of local system (default is UTC)"), NULL}, {"version", 'v', 0, G_OPTION_ARG_NONE, &do_print_version, N_("Print version information and exit"), NULL}, {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &fileargs, N_("$Recycle.bin folder or file name"), NULL}, {NULL} }; static GOptionEntry textoptions[] = { {"delimiter", 't', 0, G_OPTION_ARG_STRING, &delim, N_("String to use as delimiter (TAB by default)"), N_("STRING")}, {"no-heading", 'n', 0, G_OPTION_ARG_NONE, &no_heading, N_("Don't show header info"), NULL}, {"always-utf8", '8', 0, G_OPTION_ARG_NONE, &always_utf8, N_("Always display result in UTF-8 encoding"), NULL}, {NULL} }; /* Check if index file has sufficient amount of data for reading */ /* 0 = success, all other return status = error */ static int validate_index_file (FILE *inf, off_t size, uint64_t *version, uint32_t *namelength) { off_t expected; size_t status; g_debug ("Start file validation..."); if (size <= VERSION1_FILENAME_OFFSET) /* file path can't possibly be empty */ { g_debug ("file size = %i, expect larger than %i\n", (int) size, VERSION1_FILENAME_OFFSET); g_printerr (_("File is truncated, or probably not a $Recycle.bin index file.\n")); return RIFIUTI_ERR_BROKEN_FILE; } /* with file size check already done, fread fail probably mean serious problem */ rewind (inf); status = fread (version, sizeof (*version), 1, inf); if (status < 1) { /* TRANSLATOR COMMENT: the variable is function name */ g_critical (_("%s(): fread() failed when reading version info"), __func__); return RIFIUTI_ERR_OPEN_FILE; } *version = GUINT64_FROM_LE (*version); g_debug ("version=%" G_GUINT64_FORMAT, *version); switch (*version) { case (uint64_t) FORMAT_VISTA: expected = VERSION1_FILE_SIZE; /* see populate_record_data() for reason */ if ((size == expected) || (size == expected - 1)) return 0; break; case (uint64_t) FORMAT_WIN10: g_return_val_if_fail ((size > VERSION2_FILENAME_OFFSET), FALSE); fseek (inf, VERSION2_FILENAME_OFFSET - sizeof (*namelength), SEEK_SET); if (status < 1) { /* TRANSLATOR COMMENT: the variable is function name */ g_critical (_("%s(): fread() failed when reading file name length"), __func__); return RIFIUTI_ERR_OPEN_FILE; } status = fread (namelength, sizeof (*namelength), 1, inf); *namelength = GUINT32_FROM_LE (*namelength); /* Fixed header length + file name length in UTF-16 encoding */ expected = VERSION2_FILENAME_OFFSET + (*namelength) * 2; if (size == expected) return 0; break; default: g_printerr (_("File is not supported, or it is probably " "not a $Recycle.bin index file.\n")); return RIFIUTI_ERR_BROKEN_FILE; } g_debug ("File size = %" G_GUINT64_FORMAT ", expected %" G_GUINT64_FORMAT, (uint64_t) size, (uint64_t) expected); g_printerr (_("Index file expected size and real size do not match.\n")); return RIFIUTI_ERR_BROKEN_FILE; } static rbin_struct * populate_record_data (void *buf, uint64_t version, uint32_t namelength, gboolean erraneous) { uint64_t win_filetime; rbin_struct *record; GError *error = NULL; long read, write; record = g_malloc0 (sizeof (rbin_struct)); record->version = version; record->type = RECYCLE_BIN_TYPE_DIR; /* * In rare cases, the size of index file is 543 bytes versus (normal) 544 bytes. * In such occasion file size only occupies 56 bit, not 64 bit as it ought to be. * Actually this 56-bit file size is very likely wrong after all. Probably some * bug inside Windows. This is observed during deletion of dd.exe from Forensic * Acquisition Utilities (by George M. Garner Jr) in certain localized Vista. */ /* TODO: Consider if the (possibly wrong) size should be printed or not */ memcpy (&record->filesize, buf + FILESIZE_OFFSET, FILETIME_OFFSET - FILESIZE_OFFSET - (int) erraneous); record->filesize = GUINT64_FROM_LE (record->filesize); g_debug ("filesize=%" G_GUINT64_FORMAT, record->filesize); /* File deletion time */ memcpy (&win_filetime, buf + FILETIME_OFFSET - (int) erraneous, VERSION1_FILENAME_OFFSET - FILETIME_OFFSET); win_filetime = GUINT64_FROM_LE (win_filetime); record->deltime = win_filetime_to_epoch (win_filetime); /* One extra char for safety, though path should have already been null terminated */ g_debug ("namelength=%d", namelength); switch (version) { case (uint64_t) FORMAT_VISTA: record->utf8_filename = utf16le_to_utf8 ((gunichar2 *) (buf + VERSION1_FILENAME_OFFSET - (int) erraneous), namelength + 1, &read, &write, &error); break; case (uint64_t) FORMAT_WIN10: record->utf8_filename = utf16le_to_utf8 ((gunichar2 *) (buf + VERSION2_FILENAME_OFFSET), namelength + 1, &read, &write, &error); break; } g_debug ("utf16->8 r=%li w=%li", read, write); if (error) { g_warning (_("Error converting file name from %s encoding to " "UTF-8 encoding: %s"), "UTF-16", error->message); g_clear_error (&error); } return record; } static void parse_record (char *index_file, GSList **recordlist) { FILE *infile; rbin_struct *record; char *basename; uint64_t version; uint32_t namelength = 0; GStatBuf st; void *buf; basename = g_path_get_basename (index_file); if (0 != g_stat (index_file, &st)) { g_printerr (_("Error getting metadata of file '%s': %s\n"), basename, strerror (errno)); goto parse_record_open_error; } if (NULL == (infile = g_fopen (index_file, "rb"))) { g_printerr (_("Error opening file '%s' for reading: %s\n"), basename, strerror (errno)); goto parse_record_open_error; } if (0 != validate_index_file (infile, st.st_size, &version, &namelength)) { g_printerr (_("File '%s' fails validation.\n"), basename); goto parse_validation_error; } rewind (infile); /* Files are expected to be at most 0.5KB. Large files should have already been rejected. */ buf = g_malloc0 (st.st_size + 2); if (1 != fread (buf, st.st_size, 1, infile)) { /* * TRANSLATOR COMMENT: 1st parameter is function name, * 2nd is file name, 3rd is error message */ g_critical (_("%s(): fread() failed when " "reading content of file '%s': %s\n"), __func__, basename, strerror (errno)); goto parse_validation_error; } g_debug ("Start populating record for '%s'...", basename); switch (version) { case (uint64_t) FORMAT_VISTA: /* see populate_record_data() for meaning of last parameter */ record = populate_record_data (buf, version, (uint32_t) WIN_PATH_MAX, (st.st_size == VERSION1_FILE_SIZE - 1)); break; case (uint64_t) FORMAT_WIN10: record = populate_record_data (buf, version, namelength, FALSE); break; default: /* VERY wrong if reaching here. Version info has already been filtered once */ g_critical (_("Version info for '%s' still wrong " "despite file validation."), basename); goto parse_validation_error; } g_debug ("Parsing done for '%s'", basename); record->index_s = basename; *recordlist = g_slist_prepend (*recordlist, record); fclose (infile); g_free (buf); return; parse_validation_error: fclose (infile); parse_record_open_error: g_free (basename); } /* Scan folder and add all "$Ixxxxxx.xxx" to filelist for parsing */ static void populate_index_file_list (GSList **list, char *path) { GDir *dir; char *direntry, *fname; GPatternSpec *pattern1, *pattern2; GError *error = NULL; if (NULL == (dir = g_dir_open (path, 0, &error))) { g_printerr (_("Error opening directory '%s': %s\n"), path, error->message); g_clear_error (&error); exit (RIFIUTI_ERR_OPEN_FILE); } pattern1 = g_pattern_spec_new ("$I??????.*"); pattern2 = g_pattern_spec_new ("$I??????"); while ((direntry = (char *) g_dir_read_name (dir)) != NULL) { if (!g_pattern_match_string (pattern1, direntry) && !g_pattern_match_string (pattern2, direntry)) continue; fname = g_build_filename (path, direntry, NULL); *list = g_slist_prepend (*list, fname); } g_dir_close (dir); g_pattern_spec_free (pattern1); g_pattern_spec_free (pattern2); } /* Search for desktop.ini in folder for hint of recycle bin */ static gboolean found_desktop_ini (char *path) { char *filename, *content, *found; filename = g_build_filename (path, "desktop.ini", NULL); if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) goto desktop_ini_error; /* assume desktop.ini is ASCII and not something spurious */ if (!g_file_get_contents (filename, &content, NULL, NULL)) goto desktop_ini_error; /* Don't bother parsing, we don't use the content at all */ found = strstr (content, RECYCLE_BIN_CLSID); g_free (content); g_free (filename); return (found != NULL); desktop_ini_error: g_free (filename); return FALSE; } static void free_record (rbin_struct *record) { g_free (record->index_s); g_free (record->utf8_filename); g_free (record); } static int sort_record_by_time (rbin_struct *a, rbin_struct *b) { /* time_t can be 32 or 64 bit, can't just return a-b :( */ return ((a->deltime < b->deltime) ? -1 : (a->deltime > b->deltime) ? 1 : strcmp (a->index_s, b->index_s)); } int main (int argc, char **argv) { FILE *outfile; GSList *filelist = NULL; GSList *recordlist = NULL; char *fname, *bug_report_str; GError *error = NULL; GOptionContext *context; GOptionGroup *textoptgroup; setlocale (LC_ALL, ""); if (g_file_test (LOCALEDIR, G_FILE_TEST_IS_DIR)) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); else { /* searching current dir is more useful on Windows */ char *d = g_path_get_dirname (argv[0]); char *p = g_build_filename (d, "rifiuti-l10n", NULL); if (g_file_test (p, G_FILE_TEST_IS_DIR)) bindtextdomain (GETTEXT_PACKAGE, p); g_free (p); g_free (d); } bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); context = g_option_context_new (_("DIR_OR_FILE")); g_option_context_set_summary (context, _("Parse index files in C:\\$Recycle.bin style folder " "and dump recycle bin data. Can also dump " "a single index file.")); bug_report_str = g_strdup_printf (_("Report bugs to %s"), PACKAGE_BUGREPORT); g_option_context_set_description (context, bug_report_str); g_free (bug_report_str); g_option_context_add_main_entries (context, mainoptions, "rifiuti"); textoptgroup = g_option_group_new ("text", _("Plain text output options:"), N_("Show plain text output options"), NULL, NULL); g_option_group_set_translation_domain (textoptgroup, GETTEXT_PACKAGE); g_option_group_add_entries (textoptgroup, textoptions); g_option_context_add_group (context, textoptgroup); /* Must be done before parsing arguments since argc will be modified later */ if (argc <= 1) { char *msg = g_option_context_get_help (context, FALSE, NULL); #ifdef G_OS_WIN32 g_set_print_handler (gui_message); #endif g_print ("%s", msg); g_free (msg); g_option_context_free (context); exit (EXIT_SUCCESS); } g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, my_debug_handler, NULL); { gboolean i; /* The user case where this code won't provide benefit is VERY rare, * so don't bother doing fallback because it never worked for them */ #if GLIB_CHECK_VERSION(2, 40, 0) && defined (G_OS_WIN32) char **args; args = g_win32_get_command_line (); i = g_option_context_parse_strv (context, &args, &error); g_strfreev (args); #else i = g_option_context_parse (context, &argc, &argv, &error); #endif g_option_context_free (context); if (!i) { g_printerr (_("Error parsing options: %s\n"), error->message); g_clear_error (&error); exit (RIFIUTI_ERR_ARG); } } if (do_print_version) { print_version(); exit (EXIT_SUCCESS); } if (!fileargs || g_strv_length (fileargs) > 1) { g_printerr (_("Must specify exactly one directory containing " "$Recycle.bin index files, or one such index file, " "as argument.\n\n")); g_printerr (_("Run program with '-?' option for more info.\n")); exit (RIFIUTI_ERR_ARG); } if (outfilename) { outfile = g_fopen (outfilename, "wb"); if (NULL == outfile) { g_printerr (_("Error opening file '%s' for writing: %s\n"), outfilename, strerror (errno)); exit (RIFIUTI_ERR_OPEN_FILE); } } else outfile = stdout; if (xml_output) { output_format = OUTPUT_XML; if (no_heading || always_utf8 || (NULL != delim)) { g_printerr (_("Plain text format options can not " "be used in XML mode.\n")); exit (RIFIUTI_ERR_ARG); } } if (NULL == delim) delim = g_strndup ("\t", 2); else { char *d = filter_escapes (delim); if (d != NULL) { g_free (delim); delim = d; } } { char *i = delim; GString *str = g_string_new (g_strdup ("filtered delimiter = ")); do { if (((*i) <= 0x7E) && ((*i) >= 0x20)) str = g_string_append_c (str, *i); else g_string_append_printf (str, "\\x%02X", (char) (*i)); } while ((char) (* (++i)) != '\0'); g_debug (str->str); g_string_free (str, TRUE); } g_debug ("Start basic file checking..."); if (!g_file_test (fileargs[0], G_FILE_TEST_EXISTS)) { g_printerr (_("'%s' does not exist.\n"), fileargs[0]); exit (RIFIUTI_ERR_OPEN_FILE); } else if (g_file_test (fileargs[0], G_FILE_TEST_IS_DIR)) { populate_index_file_list (&filelist, fileargs[0]); if (NULL == filelist) { /* last ditch effort: search for desktop.ini. Just print empty content * representing empty recycle bin if found. */ if (!found_desktop_ini (fileargs[0])) { g_printerr (_("No files with name pattern '%s' are found in " "directory. Probably not a $Recycle.bin directory.\n"), "$Ixxxxxx.*"); exit (RIFIUTI_ERR_OPEN_FILE); } } } else if (g_file_test (fileargs[0], G_FILE_TEST_IS_REGULAR)) { fname = g_strdup (fileargs[0]); filelist = g_slist_prepend (filelist, fname); } else { g_printerr (_("'%s' is not a normal file or directory.\n"), fileargs[0]); exit (RIFIUTI_ERR_OPEN_FILE); } g_slist_foreach (filelist, (GFunc) parse_record, &recordlist); /* NULL filelist at this point means a valid empty $Recycle.bin */ if ((filelist != NULL) && (recordlist == NULL)) { g_printerr ("%s", _("No valid recycle bin index file found.\n")); g_slist_foreach (filelist, (GFunc) g_free, NULL); g_slist_free (filelist); exit (RIFIUTI_ERR_BROKEN_FILE); } recordlist = g_slist_sort (recordlist, (GCompareFunc) sort_record_by_time); { GSList *l = recordlist; int64_t ver; if (!l) ver = VERSION_NOT_FOUND; else { ver = (int64_t) ((rbin_struct *) recordlist->data)->version; for (; l != NULL; l = l->next) if ((int64_t) ((rbin_struct *) l->data)->version != ver) { ver = VERSION_INCONSISTENT; break; } } if (!no_heading) print_header (outfile, fileargs[0], ver, FALSE); } /* TODO: store return status of each file, then exit the program with last non-zero status */ /* TODO: store errors accumulated when parsing each file, then print a summary of errors * after normal result, instead of dumping all errors on the spot */ g_slist_foreach (recordlist, (GFunc) print_record, outfile); print_footer (outfile); g_debug ("Cleaning up..."); /* g_slist_free_full() available only since 2.28 */ g_slist_foreach (recordlist, (GFunc) free_record, NULL); g_slist_free (recordlist); g_slist_foreach (filelist, (GFunc) g_free, NULL); g_slist_free (filelist); fclose (outfile); g_strfreev (fileargs); g_free (outfilename); g_free (delim); exit (EXIT_SUCCESS); } /* vim: set sw=4 ts=4 noexpandtab : */ rifiuti2-0.6.1/src/rifiuti-vista.h000066400000000000000000000036431252727005000170200ustar00rootroot00000000000000/* * Copyright (C) 2007, 2015 Abel Cheung. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _RIFIUTI_VISTA_H #define _RIFIUTI_VISTA_H #include "utils.h" #define VERSION1_FILE_SIZE 0x220 #define FILESIZE_OFFSET 0x8 #define FILETIME_OFFSET 0x10 #define VERSION1_FILENAME_OFFSET 0x18 #define VERSION2_FILENAME_OFFSET 0x1C #define RECYCLE_BIN_CLSID "645FF040-5081-101B-9F08-00AA002F954E" #endif /* vim: set sw=4 ts=4 noexpandtab : */ rifiuti2-0.6.1/src/rifiuti.1000066400000000000000000000324711252727005000156060ustar00rootroot00000000000000.\"- .\" Man page for rifiuti2 .\" .\" Copyright (c) 2008 Anthony Wong .\" Copyrgith (c) 2015 Abel Cheung .\" .\" This documentation is available under BSD 3-clause license. .\" . ie \n[www-html] \{\ .\" see groff_www(7) .BCL black #bbffee blue blue #302226 .TH "RIFIUTI2 0.6.1" "1" .SH INSTALLATION ON WINDOWS \fBRifiuti2\fP is designed to run as portable Windows command line application, and no installation is required. Copy the binaries corresponding to your system (\fCx64\\\fP for 64 bit systems, \fCx86\\\fP for 32 bit) to any folder of your choice and they are ready for use. Read sections below on how to use the programs. .SS Translation By default output messages of rifiuti2 are in English. Optionally one can copy .nh \fCrifiuti\-l10n\fP .hy folder to the same location the binaries reside in, and set \fCLANGUAGE\fP environment variable to appropriate value to enable translations. Supported language codes are the same as existing subdirectory names under .nh \fCrifiuti\-l10n\fP .hy folder. For example, assuming folder .nh \fCrifiuti\-l10n\\fr\\\fP .hy exists, running following in Windows \fCcmd\fP would enable French translation: .RS \fCset LANGUAGE=fr\fP .RE The file \fCrifiuti.pot\fP in archive contains translation template for rifiuti2. Rifiuti2 makes use of \f[CB]gettext\fP for handling translation. There are lots of tutorial on internet on how to work with gettext translations; any completed translation can be submitted to main author for inclusion in next release. .SH LATEST CHANGE ####CHANGELOG#### .PP Changes for previous versions are available from .RS https://github.com/abelcheung/rifiuti2/blob/master/NEWS.md .RE . \} . el \{\ .TH RIFIUTI2 "1" "May 2015" "0.6.1" "MS Windows recycle bin analysis tool" .SH NAME rifiuti2 \- MS Windows recycle bin analysis tool . \} .SH SYNOPSIS .B rifiuti .RB [ \-hvz ] .RB [ \-x " |" .RB [ \-8n ] .RB [ \-t .IR delim "]]" .RB [ \-l .IR codepage ] .RB [ \-o .IR outfile ] .I filename .B rifiuti-vista .RB [ \-hvz ] .RB [ \-x " |" .RB [ \-8n ] .RB [ \-t .IR delim "]]" .RB [ \-o .IR outfile ] .I file_or_directory .SH DESCRIPTION Rifiuti2 analyse recycle bin files from Windows. Analysis of Windows recycle bin is usually carried out during Windows computer forensics. Rifiuti2 can extract file deletion time, original path and size of deleted files and whether the deleted files have been moved out from the recycle bin since they are trashed. .PP Rifiuti2 supports a wide range of Windows versions, from Windows 98 to Windows 10. The command used for analysis depends on the version of Windows producing the recycle bin (\fBnot the version of users\' system!\fP), which uses vastly different format before and after Vista: .PP .IP \[bu] \fCrifiuti-vista\fP: For Vista or later, which is located in .nh \fC\\$Recycle.bin\\\fP\fI\fP\fC\\\fP. .hy Each deleted file has its own accompanied index file remembering the original path, file size and deletion time. If original file is permanentsly deleted, so is the index file. .IP \[bu] \fCrifiuti\fP: For Windows 98 to XP, which uses a single index file named INFO2 under either .nh \fC\\RECYCLED\\\fP .hy or .nh \fC\\RECYCLER\\\fP\fI\fP\fC\\\fP .hy (depending on filesystem). This file keeps track record for deletion status and info for \fIall\fP deleted items, including those permanently removed or restored. .PP By default, both programs dump tab-delimited fields on screen, which can be viewed on screen or imported into spreadsheet program. \fB\-x\fP option instructs program to dump XML formatted content instead. .PP Index field has different meaning for pre-Vista and post-Vista versions. INFO2 has an index number for each of deletion item indicating the chronological order of items. For Vista version, it means the index file name instead, which matches pattern \(lq$I\fBxxxxxx\fP.\fI\fP\(rq, where \fBx\fP is random alphanumeric character. .PP Deleted time is represented in UTC time by default. Under tab-delimited mode, the original date/time format is preserved, while in XML mode ISO 8601 date/time format is used. For example, 3PM at 2014 X\'mas represented in these modes would be respectively: .RS \fC2014-12-25 15:00:00\fP .RE .RS \fC2014-12-25T15:00:00Z\fP .RE It would be easier for spreadsheet programs to interpret first format. .PP File size and file path are self-explanatory, but there are some special notes. File size can mean the real size of deleted file, or the cluster size it occupies on filesystem, depending on recycle bin format. File path might not always be displayable on local system because it might contain characters from other localized version of Windows. .SH OPTIONS .TP \fB\-o\fP, \fB\-\-output\fP=\fI\,FILE\/\fP Write output to FILE. .TP \fB\-x\fP, \fB\-\-xml\fP Output in XML format instead of tab\-delimited values. With XML mode, all plain text options are disallowed, and result is always in UTF-8 encoding. See below for plain text options. .TP \fB\-l\fP, \fB\-\-legacy\-filename\fP=\fI\,CODEPAGE\/\fP Show legacy filename if available (like \(lq\fCD:\\Progra~1\\\fP\(rq), and specify the CODEPAGE used in the Windows system producing this INFO2 file. Any encodings supported by \fBiconv\fP(1) can be used, though for maximum accuracy of file name results, it is better to stick with Microsoft codepages (such as CP850 or CP1252 for west European version, CP932 for Japanese, etc). .RS \fBNote\fP: This option is mandatory if INFO2 file is created by Windows 98. This option does not exist in \fCrifiuti-vista\fP. .RE .TP \fB\-z\fP, \fB\-\-localtime\fP Present deletion time in numeric time zone of local system running the program. By default, UTC time is displayed, which is the time value recorded in index files. Using the X\'mas example above, the time for Berlin (without daylight saving time) would be \fC2014-12-25T16:00:00+0100\fP in ISO 8601 format. .RS \fBNote\fP: It is possible to use any timezone of users\' choice by setting $TZ environment variable, though not recommended. See \fBENVIRONMENT VARIABLE\fP section below. .RE .SS PLAIN TEXT OUTPUT OPTIONS .TP \fB\-t\fP, \fB\-\-delimiter\fP=\fI\,STRING\/\fP String to use as delimiter (TAB by default). Several escaped characters are recognised: \\r (CARRIAGE RETURN), \\n (NEW LINE), \\t (TAB), \\f (FORM FEED), \\v (VERTICAL TAB), \\e (ESCAPE) .TP \fB\-n\fP, \fB\-\-no\-heading\fP Don\'t show recycle bin path name, version and header for each field .TP \fB\-8\fP, \fB\-\-always\-utf8\fP Always display result in UTF\-8 encoding .PP .SS MISCELLANEOUS OPTIONS .TP \fB\-v\fP, \fB\-\-version\fP Print version information and exit. .TP \fB\-h\fP, \fB\-\-help\fP Show help options and exit. .TP \fB\-\-help\-all\fP Show all help options and exit. .TP \fB\-\-help\-text\fP Show plain text output options and exit. .PP .SH EXAMPLES .TP \fCrifiuti-vista \-x \-z \-o result.xml \\case\\S\-1\-2\-3\\\fP .RS Scan for index files under \\case\\S\-1\-2\-3\\, adjust all deletion time for local time zone, and write XML output to result.xml .RE .TP \fCrifiuti-vista \-n \-8 \\case\\S\-1\-2\-3\\\fP Show tab-delimited result on screen in UTF-8 encoding without header .TP \fCrifiuti-vista -t '\\r\\n' \\case\\S\-1\-2\-3\\$IF96NJ3.rtf\fP Only analyse a single index file and print each field in its own line .TP \fCrifiuti \-t ',' -o result.csv INFO2\fP Change tab-delimited result to comma-delimited and write to result.csv .TP \fCrifiuti \-l CP1255 \-8 \-n INFO2\fP .RS Read INFO2 from Hebrew version of Windows, display 8.3 file names on screen in UTF-8 encoding without header .RE .SH ENVIRONMENT VARIABLES The following environment variables affect execution of program: .TP \fBCHARSET\fP, \fBLC_CTYPE\fP .RS If recycle bin path contains non-ASCII character, these variables affect how they are displayed. UTF-8 capable systems are recommended to set .nh \fCCHARSET=UTF-8\fP .hy or use appropriate UTF-8 values for \fCLC_CTYPE\fP explicitly, otherwise path might be displayed in Universal Character Name sequences like \\u1234. .RE .TP \fBRIFIUTI_DEBUG\fP .RS Setting it to any non-empty value would cause programs to print more debugging output to stderr. .RE .TP \fBTZ\fP .RS If non-empty, indicate user-specified time zone when \fB\-z\fP option is used. Normally the time zone information is obtained from system and there is no need to set this variable. However, it can be used as a facility to temporarily override timezone for some programs, which can be used for situations like constructing timeline event. .PP This value is OS dependent. For example, for timezone in Los Angeles, the value for Windows is \(lqPST8PDT\(rq, while corresponding value on Linux would be \(lqAmerica/Los_Angeles\(rq. Please consult manual for your operating system for more info. .PP Please see \fBBUGS\fP section below for problems when using this variable. .RE .SH EXIT STATUS Both programs return 0 on success, and >0 if error occurs. .PP However \fCrifiuti-vista\fP is more permissive: it still returns success if \fIsome\fP (not all) of index files are invalid. .SH HISTORY \fIRifiuti2\fP is a rewrite of \fIrifiuti\fP, a tool of identical purpose written by Foundstone which was later purchased by McAfee. Quoting from the original FoundStone page: .RS Many computer crime investigations require the reconstruction of a subject\'s Recycle Bin. Since this analysis technique is executed regularly, we researched the structure of the data found in the Recycle Bin repository files (INFO2 files). Rifiuti, the Italian word meaning "trash", was developed to examine the contents of the INFO2 file in the Recycle Bin. ... Rifiuti is built to work on multiple platforms and will execute on Windows (through Cygwin), Mac OS X, Linux, and *BSD platforms. .RE .PP However, since the original rifiuti (last updated 2004) can\'t analyze recycle bin from any localized version of Windows (restricted to English), this rewrite effort is born to overcome the limitation. Later rifiuti2 was improved to add support for Vista format recycle bin, XML output and other extra features not available from original version. .SH BUGS In very special circumstance (which author can\'t reproduce now), index file of certain deleted item can be corrupt, causing incorrect deleted file size to be stored. There is no way to report correct size. This problem shouldn\'t happen after Vista though. .PP Handling of non-ASCII file argument is not satisfactory; it may not work in certain case under MinGW bash. .PP Non-ASCII deleted item path name may not be always displayed appropriately, especially on systems with non-UTF-8 locale (such as Windows \fBcmd\fP, where output is restricted to ANSI codepages). Storing UTF-8 result into file with \fB\-8\fP or \fB\-x\fP option and then opening it with Unicode capable editor could be a solution. .PP The calculation of local time might not be correct. For example, documentation of _tzset() function on Windows has this statement: .RS The C run-time library assumes the United States\' rules for implementing the calculation of daylight saving time (DST). .RE Therefore the time might not be correct in case the files inside recycle bin are produced on Windows using other countries as region settings. Besides, the difference between standard time and DST is hardcoded to be one hour, which is incorrect for a few selected regions. .PP So it is always better to use UTC time whenever possible. .SH REPORTING BUGS Report bugs to .\" The whole link and text would disappear when using .\" ascii driver, So have to use if/else . ie \n[www-html] \{\ .\" Using .IP doesn't work, URL is emitted before it .RS .URL https://github.com/abelcheung/rifiuti2/issues .RE . \} . el \{\ .IP https://github.com/abelcheung/rifiuti2/issues . \} .PP Information about rifiuti2 can be found on . ie \n[www-html] \{\ .RS .URL https://abelcheung.github.io/rifiuti2/ .RE . \} . el \{\ .IP https://abelcheung.github.io/rifiuti2/ . \} .SH SEE ALSO . ie \n[www-html] \{\ .PP .URL http://odessa.sourceforge.net/ "Open Digital Evidence Search and Seizure Architecture project" , which contains the original rifiuti tool .PP Forensics tools and other security related utilities .URL http://www.mcafee.com/us/downloads/free-tools/index.aspx "originally written by FoundStone" are now available under McAfee\'s own license .PP .URL http://me.abelcheung.org/wp-content/uploads/2007/09/vista-recycle-bin-sample.pdf "Vista recycle bin file structure" , by Abel Cheung .PP .URL http://www.csisite.net/downloads/INFO2.pdf "INFO2 recycle bin file example" , by Steve Hailey . \} . el \{\ .TP Open Digital Evidence Search and Seizure Architecture project, which contains the original rifiuti tool http://odessa.sourceforge.net/ .TP Forensics tools and other security related utilities originally written by FoundStone are now available under McAfee\'s own license. http://www.mcafee.com/us/downloads/free-tools/index.aspx .TP Vista recycle bin file structure, by Abel Cheung http://me.abelcheung.org/wp-content/uploads/2007/09/vista-recycle-bin-sample.pdf .TP INFO2 recycle bin file example, by Steve Hailey http://www.csisite.net/downloads/INFO2.pdf . \} .PP .SH COPYRIGHT Part of the work of rifiuti2 is derived from Rifiuti. Both pieces of software are licensed under the simplified BSD license. .SH AUTHOR The main author of rifiuti2 is Abel Cheung .nh \fC\fP .hy .PP The original author of rifiuti is Keith J. Jones .nh \fC\fP .hy .PP Anthony Wong .nh \fC\fP .hy helped in Debian packaging and was author of the original manpage. rifiuti2-0.6.1/src/rifiuti.c000066400000000000000000000371201252727005000156640ustar00rootroot00000000000000/* * Copyright (C) 2003, by Keith J. Jones. * Copyright (C) 2007, 2015 Abel Cheung. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" #include #include #include "utils.h" #include #include #include "rifiuti.h" char *delim = NULL; static char **fileargs = NULL; static char *outfilename = NULL; char *legacy_encoding = NULL; int output_format = OUTPUT_CSV; static gboolean no_heading = FALSE; static gboolean xml_output = FALSE; gboolean always_utf8 = FALSE; gboolean has_unicode_filename = FALSE; gboolean use_localtime = FALSE; static gboolean do_print_version = FALSE; /* 0-25 => A-Z, 26 => '\', 27 or above is erraneous */ unsigned char driveletters[28] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '?' }; static GOptionEntry mainoptions[] = { {"output", 'o', 0, G_OPTION_ARG_FILENAME, &outfilename, N_("Write output to FILE"), N_("FILE")}, {"xml", 'x', 0, G_OPTION_ARG_NONE, &xml_output, N_("Output in XML format instead of tab-delimited values"), NULL}, {"legacy-filename", 'l', 0, G_OPTION_ARG_STRING, &legacy_encoding, N_("Show legacy (8.3) filename if available and specify its CODEPAGE"), N_("CODEPAGE")}, {"localtime", 'z', 0, G_OPTION_ARG_NONE, &use_localtime, N_("Present deletion time in time zone of local system (default is UTC)"), NULL}, {"version", 'v', 0, G_OPTION_ARG_NONE, &do_print_version, N_("Print version information and exit"), NULL}, {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &fileargs, N_("INFO2 file name"), NULL}, {NULL} }; static GOptionEntry textoptions[] = { {"delimiter", 't', 0, G_OPTION_ARG_STRING, &delim, N_("String to use as delimiter (TAB by default)"), N_("STRING")}, {"no-heading", 'n', 0, G_OPTION_ARG_NONE, &no_heading, N_("Don't show header info"), NULL}, {"always-utf8", '8', 0, G_OPTION_ARG_NONE, &always_utf8, N_("Always display result in UTF-8 encoding"), NULL}, {NULL} }; /* * Check if index file has sufficient amount of data for reading * 0 = success, all other return status = error */ static int validate_index_file (FILE *inf, off_t size, uint32_t *info2_version, uint32_t *recordsize) { size_t status; g_debug ("Start file validation..."); if (size < RECORD_START_OFFSET) /* empty INFO2 file has 20 bytes */ { g_debug ("file size = %d, expect at least %d\n", (int) size, RECORD_START_OFFSET); g_printerr (_("File is truncated, or probably not an INFO2 file.\n")); return RIFIUTI_ERR_BROKEN_FILE; } /* with file size check already done, fread fail -> serious problem */ fseek (inf, 0, SEEK_SET); status = fread (info2_version, sizeof (*info2_version), 1, inf); if (status < 1) { /* TRANSLATOR COMMENT: the variable is function name */ g_critical (_("%s(): fread() failed when reading version info"), __func__); return RIFIUTI_ERR_OPEN_FILE; } *info2_version = GUINT32_FROM_LE (*info2_version); fseek (inf, RECORD_SIZE_OFFSET, SEEK_SET); status = fread (recordsize, sizeof (*recordsize), 1, inf); if (status < 1) { /* TRANSLATOR COMMENT: the variable is function name */ g_critical (_("%s(): fread() failed when reading recordsize"), __func__); return RIFIUTI_ERR_OPEN_FILE; } *recordsize = GUINT32_FROM_LE (*recordsize); /* Recordsize should be restricted to either 280 (v4) or 800 bytes (v5) */ switch (*info2_version) { case FORMAT_WIN98: if (*recordsize != VERSION4_RECORD_SIZE) { g_debug ("Size per record = %u, expect %u instead.", *recordsize, VERSION4_RECORD_SIZE); g_critical (_("Invalid record size for this version of INFO2")); return RIFIUTI_ERR_BROKEN_FILE; } if (!legacy_encoding) { g_printerr (_("This INFO2 file was produced on a Windows 98. " "Please specify codepage of concerned system with " "'-l' or '--legacy-filename' option.\n\n")); /* TRANSLATOR COMMENT: use suitable example from YOUR language & code page */ g_printerr (_("For example, if file name was expected to contain " "accented latin characters, use '-l CP1252' option; " "or in case of Japanese characters, '-l CP932'.\n\n" "Code pages (or any other encodings) supported by " "'iconv' can be used.\n")); return RIFIUTI_ERR_ARG; } break; case FORMAT_WIN2K: if (*recordsize != VERSION5_RECORD_SIZE) { g_debug ("Size per record = %u, expect %u instead.", *recordsize, VERSION5_RECORD_SIZE); g_critical (_("Invalid record size for this version of INFO2")); return RIFIUTI_ERR_BROKEN_FILE; } /* only version 5 contains UTF-16 filename */ has_unicode_filename = TRUE; break; default: g_printerr (_("File is not supported, or it is " "probably not an INFO2 file.\n")); return RIFIUTI_ERR_BROKEN_FILE; } return 0; } static rbin_struct * populate_record_data (void *buf) { rbin_struct *record; uint64_t win_filetime; uint32_t drivenum; long read, write; g_debug ("Start populating record..."); record = g_malloc0 (sizeof (rbin_struct)); record->type = RECYCLE_BIN_TYPE_FILE; /* Guarantees null-termination by allocating extra byte */ record->legacy_filename = (char *) g_malloc0 (RECORD_INDEX_OFFSET - LEGACY_FILENAME_OFFSET + 1); memcpy (record->legacy_filename, buf + LEGACY_FILENAME_OFFSET, RECORD_INDEX_OFFSET - LEGACY_FILENAME_OFFSET); memcpy (&record->index_n, buf + RECORD_INDEX_OFFSET, DRIVE_LETTER_OFFSET - RECORD_INDEX_OFFSET); record->index_n = GUINT32_FROM_LE (record->index_n); g_debug ("index=%u", record->index_n); memcpy (&drivenum, buf + DRIVE_LETTER_OFFSET, FILETIME_OFFSET - DRIVE_LETTER_OFFSET); drivenum = GUINT32_FROM_LE (drivenum); g_debug ("drive=%u", drivenum); if (drivenum >= sizeof (driveletters) - 1) g_warning (_("Invalid drive number (0x%X) for record %u."), drivenum, record->index_n); record->drive = driveletters[MIN (drivenum, sizeof (driveletters) - 1)]; record->emptied = FALSE; /* first byte will be removed from filename if file is not in recycle bin */ if (!*record->legacy_filename) { record->emptied = TRUE; *record->legacy_filename = record->drive; } /* File deletion time */ memcpy (&win_filetime, buf + FILETIME_OFFSET, FILESIZE_OFFSET - FILETIME_OFFSET); win_filetime = GUINT64_FROM_LE (win_filetime); record->deltime = win_filetime_to_epoch (win_filetime); /* File size or occupied cluster size */ /* BEWARE! This is 32bit data casted to 64bit struct member */ memcpy (&record->filesize, buf + FILESIZE_OFFSET, UNICODE_FILENAME_OFFSET - FILESIZE_OFFSET); record->filesize = GUINT64_FROM_LE (record->filesize); g_debug ("filesize=%" G_GUINT64_FORMAT, record->filesize); if (has_unicode_filename) { GError *error = NULL; /* * Added safeguard to memory buffer (2 bytes larger than necessary), * so safely assume string is null terminated */ record->utf8_filename = utf16le_to_utf8 ((gunichar2 *) (buf + UNICODE_FILENAME_OFFSET), WIN_PATH_MAX + 1, &read, &write, &error); g_debug ("utf16->8 r=%li w=%li", read, write); if (error) { g_warning (_("Error converting file name from %s encoding to " "UTF-8 encoding for record %u: %s"), "UTF-16", record->index_n, error->message); g_clear_error (&error); } } return record; } int main (int argc, char **argv) { void *buf; FILE *infile, *outfile; int status; GOptionGroup *textoptgroup; GOptionContext *context; GError *error = NULL; GStatBuf st; rbin_struct *record; uint32_t recordsize, info2_version; char *bug_report_str; setlocale (LC_ALL, ""); if (g_file_test (LOCALEDIR, G_FILE_TEST_IS_DIR)) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); else { /* searching current dir is more useful on Windows */ char *d = g_path_get_dirname (argv[0]); char *p = g_build_filename (d, "rifiuti-l10n", NULL); if (g_file_test (p, G_FILE_TEST_IS_DIR)) bindtextdomain (GETTEXT_PACKAGE, p); g_free (p); g_free (d); } bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); context = g_option_context_new ("INFO2"); g_option_context_set_summary (context, _("Parse INFO2 file and dump recycle bin data.")); bug_report_str = g_strdup_printf (_("Report bugs to %s"), PACKAGE_BUGREPORT); g_option_context_set_description (context, bug_report_str); g_free (bug_report_str); g_option_context_add_main_entries (context, mainoptions, "rifiuti"); textoptgroup = g_option_group_new ("text", _("Plain text output options:"), N_("Show plain text output options"), NULL, NULL); g_option_group_set_translation_domain (textoptgroup, GETTEXT_PACKAGE); g_option_group_add_entries (textoptgroup, textoptions); g_option_context_add_group (context, textoptgroup); /* Must be done before parsing arguments since argc will be modified later */ if (argc <= 1) { char *msg = g_option_context_get_help (context, FALSE, NULL); #ifdef G_OS_WIN32 g_set_print_handler (gui_message); #endif g_print ("%s", msg); g_free (msg); g_option_context_free (context); exit (EXIT_SUCCESS); } g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, my_debug_handler, NULL); { gboolean i; /* * The user case where this code won't provide benefit is VERY rare, * so don't bother doing fallback because it was always the case before. * * However this parsing doesn't work nice with path translation in MSYS; * directory separator in the middle of path would be translated to root * of MSYS folder if earlier path component is in pure non-ASCII. */ #if GLIB_CHECK_VERSION(2, 40, 0) && defined (G_OS_WIN32) char **args; args = g_win32_get_command_line (); i = g_option_context_parse_strv (context, &args, &error); g_strfreev (args); #else i = g_option_context_parse (context, &argc, &argv, &error); #endif g_option_context_free (context); if (!i) { g_printerr (_("Error parsing options: %s\n"), error->message); g_clear_error (&error); exit (RIFIUTI_ERR_ARG); } } if (do_print_version) { print_version(); exit (EXIT_SUCCESS); } if (!fileargs || g_strv_length (fileargs) > 1) { g_printerr (_("Must specify exactly one INFO2 file as argument.\n\n")); g_printerr (_("Run program with '-?' option for more info.\n")); exit (RIFIUTI_ERR_ARG); } if (outfilename) { outfile = g_fopen (outfilename, "wb"); if (NULL == outfile) { g_printerr (_("Error opening file '%s' for writing: %s\n"), outfilename, strerror (errno)); exit (RIFIUTI_ERR_OPEN_FILE); } } else outfile = stdout; if (xml_output) { output_format = OUTPUT_XML; if (no_heading || always_utf8 || (NULL != delim)) { g_printerr (_("Plain text format options " "can not be used in XML mode.\n")); exit (RIFIUTI_ERR_ARG); } } /* Is charset valid? */ if (legacy_encoding) { GIConv try; try = g_iconv_open (legacy_encoding, "UTF-8"); if (try == (GIConv) - 1) { g_printerr (_("'%s' is not a valid code page or encoding. " "Only those supported by 'iconv' can be used.\n"), legacy_encoding); #ifdef G_OS_WIN32 g_printerr (_("Please visit following web page for a list " "closely resembling encodings supported by " "rifiuti:\n\n\t%s\n\n"), "https://www.gnu.org/software/libiconv/"); #endif #ifdef G_OS_UNIX g_printerr (_("Please execute 'iconv -l' for list " "of supported encodings.\n")); #endif exit (RIFIUTI_ERR_ENCODING); } else g_iconv_close (try); } if (NULL == delim) delim = g_strndup ("\t", 2); else { char *d = filter_escapes (delim); if (d != NULL) { g_free (delim); delim = d; } } { char *i = delim; GString *str = g_string_new (g_strdup ("filtered delimiter = ")); do { if (((*i) <= 0x7E) && ((*i) >= 0x20)) str = g_string_append_c (str, *i); else g_string_append_printf (str, "\\x%02X", (char) (*i)); } while ((char) (* (++i)) != '\0'); g_debug (str->str); g_string_free (str, TRUE); } g_debug ("Start basic file checking..."); if (!g_file_test (fileargs[0], G_FILE_TEST_EXISTS)) { g_printerr (_("'%s' does not exist.\n"), fileargs[0]); exit (RIFIUTI_ERR_OPEN_FILE); } if (!g_file_test (fileargs[0], G_FILE_TEST_IS_REGULAR)) { g_printerr (_("'%s' is not a normal file.\n"), fileargs[0]); exit (RIFIUTI_ERR_OPEN_FILE); } if (0 != g_stat (fileargs[0], &st)) { g_printerr (_("Error getting metadata of file '%s': %s\n"), fileargs[0], strerror (errno)); exit (RIFIUTI_ERR_OPEN_FILE); } if (!(infile = g_fopen (fileargs[0], "rb"))) { g_printerr (_("Error opening file '%s' for reading: %s\n"), fileargs[0], strerror (errno)); exit (RIFIUTI_ERR_OPEN_FILE); } status = validate_index_file (infile, st.st_size, &info2_version, &recordsize); if (status != 0) { fclose (infile); exit (status); } rewind (infile); if (!no_heading) print_header (outfile, fileargs[0], (int64_t) info2_version, TRUE); /* * Add 2 padding bytes as null-termination of unicode file name. Not so confident * that file names created with Win2K or earlier are null terminated, because * random memory fragments are copied to the padding bytes */ buf = g_malloc0 (recordsize + 2); fseek (infile, RECORD_START_OFFSET, SEEK_SET); while (TRUE) { status = fread (buf, recordsize, 1, infile); if (status != 1) { if (!feof (infile)) g_warning (_("Failed to read next record: %s"), strerror (errno)); break; } record = populate_record_data (buf); print_record (record, outfile); g_free (record->utf8_filename); g_free (record->legacy_filename); g_free (record); } print_footer (outfile); g_debug ("Cleaning up..."); fclose (infile); fclose (outfile); g_free (buf); exit (EXIT_SUCCESS); } /* vim: set sw=4 ts=4 noexpandtab : */ rifiuti2-0.6.1/src/rifiuti.h000066400000000000000000000044411252727005000156710ustar00rootroot00000000000000/* * Copyright (C) 2003, by Keith J. Jones. * Copyright (C) 2007, 2015 Abel Cheung. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _RIFIUTI_H #define _RIFIUTI_H #include "utils.h" /* These offsets are relative to file start */ #define RECORD_SIZE_OFFSET 12 #define RECORD_START_OFFSET 20 /* Following offsets are relative to start of each record */ #define LEGACY_FILENAME_OFFSET 0x0 #define RECORD_INDEX_OFFSET WIN_PATH_MAX #define DRIVE_LETTER_OFFSET ((WIN_PATH_MAX) + 4) #define FILETIME_OFFSET ((WIN_PATH_MAX) + 8) #define FILESIZE_OFFSET ((WIN_PATH_MAX) + 16) #define UNICODE_FILENAME_OFFSET ((WIN_PATH_MAX) + 20) #define VERSION4_RECORD_SIZE ((WIN_PATH_MAX) + 20) /* 280 bytes */ #define VERSION5_RECORD_SIZE ((WIN_PATH_MAX) * 3 + 20) /* 800 bytes */ #endif /* vim: set sw=4 ts=4 noexpandtab : */ rifiuti2-0.6.1/src/utils.c000066400000000000000000000350461252727005000153560ustar00rootroot00000000000000/* * Copyright (C) 2007, 2015 Abel Cheung. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" #include #include "utils.h" #include #ifdef G_OS_WIN32 #include #endif static GString * get_datetime_str (time_t t, int *is_dst) { GString *output; size_t len; struct tm *tm; extern gboolean use_localtime; /* * According to localtime() in MSDN: If the TZ environment variable is set, * the C run-time library assumes rules appropriate to the United States for * implementing the calculation of daylight-saving time (DST). * * This means DST start/stop time would be wrong for other parts of the world, * and there is no way to indicate places whether DST is not +1 hour based on * standard time. So providing facility for user adjustable TZ would be useless * for non-US users. However, unsetting here still can't prevent user setting * $TZ in command line. Throw my hands up and just document the problem. */ tm = use_localtime ? localtime (&t) : gmtime (&t); if ( is_dst != NULL ) *is_dst = tm->tm_isdst; output = g_string_sized_new (40); len = strftime (output->str, output->allocated_len, "%Y-%m-%d %H:%M:%S", tm); if ( !len ) { g_string_free (output, TRUE); return NULL; } output->len = len; /* is this unorthodox? */ return output; } /* * Turns out strftime is not so cross-platform, Windows one supports far * less format strings than Unix counterpart. * However, GDateTime is not available until 2.26, so bite the bullet. * * Returns ISO 8601 formatted time. */ static GString * get_iso8601_datetime_str (time_t t) { GString *output; extern gboolean use_localtime; int is_dst; #ifdef G_OS_WIN32 struct _timeb tstruct; int offset; #else size_t len; struct tm *tm; #endif if ( ( output = get_datetime_str (t, &is_dst) ) == NULL ) return NULL; output->str[10] = 'T'; if ( !use_localtime ) return g_string_append_c (output, 'Z'); #ifdef G_OS_WIN32 _ftime (&tstruct); /* * 1. timezone value is in opposite sign of what people expect * 2. it doesn't account for DST. * 3. tm.tm_isdst is merely a flag and not indication on difference of * hours between DST and standard time. But there is no way to * override timezone in C library other than $TZ, and it always use * US rule, so again, just give up and use the value */ offset = MAX(is_dst, 0) * 60 - tstruct.timezone; g_string_append_printf (output, "%+.2i%.2i", offset / 60, abs(offset) % 60); #else tm = localtime (&t); len = strftime (output->str + output->len, output->allocated_len - output->len, "%z", tm); if ( !len ) { g_string_free (output, TRUE); return NULL; } output->len += len; #endif return output; } time_t win_filetime_to_epoch (uint64_t win_filetime) { uint64_t epoch; g_debug ("%s(): FileTime = %" G_GUINT64_FORMAT, __func__, win_filetime); /* Let's assume we don't need millisecond resolution time for now */ epoch = (win_filetime - 116444736000000000LL) / 10000000; /* Let's assume this program won't survive till 22th century */ return (time_t) (epoch & 0xFFFFFFFF); } /* * Wrapper of g_utf16_to_utf8 for big endian system. * Always assume string is nul-terminated. */ char * utf16le_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **error) { #if ((G_BYTE_ORDER) == (G_LITTLE_ENDIAN)) return g_utf16_to_utf8 (str, -1, items_read, items_written, error); #else gunichar2 *buf; char *ret; /* should be guaranteed to succeed */ buf = (gunichar2 *) g_convert ((const char *) str, len * 2, "UTF-16BE", "UTF-16LE", NULL, NULL, NULL); ret = g_utf16_to_utf8 (buf, -1, items_read, items_written, error); g_free (buf); return ret; #endif } /* * single/double quotes and backslashes have already been * quoted / unquoted when parsing arguments. We need to * interpret \r, \n etc separately */ char * filter_escapes (const char *str) { GString *result; char *i = (char *)str; if ((str == NULL) || (*str == '\0')) return NULL; result = g_string_new (NULL); for (; *i != '\0'; i++) { if (*i != '\\') { result = g_string_append_c (result, *i); continue; } switch ((char) (*(i+1))) { case 'r': result = g_string_append_c (result, '\r'); i++; break; case 'n': result = g_string_append_c (result, '\n'); i++; break; case 't': result = g_string_append_c (result, '\t'); i++; break; case 'v': result = g_string_append_c (result, '\v'); i++; break; case 'f': result = g_string_append_c (result, '\f'); i++; break; case 'e': result = g_string_append_c (result, '\x1B'); i++; break; default: result = g_string_append_c (result, '\\'); } } return g_string_free (result, FALSE); } void my_debug_handler (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer data) { if (log_level != G_LOG_LEVEL_DEBUG) return; const char *val = g_getenv ("RIFIUTI_DEBUG"); if (val != NULL) g_printerr ("DEBUG: %s\n", message); } void maybe_convert_fprintf (FILE *file, const char *format, ...) { va_list args; char *utf_str; const char *charset; extern gboolean always_utf8; va_start (args, format); utf_str = g_strdup_vprintf (format, args); va_end (args); g_return_if_fail (g_utf8_validate (utf_str, -1, NULL)); if (always_utf8 || g_get_charset (&charset)) fputs (utf_str, file); else { char *locale_str = g_convert_with_fallback (utf_str, -1, charset, "UTF-8", NULL, NULL, NULL, NULL); fputs (locale_str, file); g_free (locale_str); } g_free (utf_str); } void print_header (FILE *outfile, char *infilename, int64_t version, gboolean is_info2) { char *utf8_filename, *ver_string; extern int output_format; extern char *delim; g_return_if_fail (infilename != NULL); g_return_if_fail (outfile != NULL); g_debug ("Entering %s()", __func__); utf8_filename = g_filename_display_name (infilename); switch (output_format) { case OUTPUT_CSV: maybe_convert_fprintf (outfile, _("Recycle bin path: '%s'"), utf8_filename); fputs ("\n", outfile); switch (version) { case VERSION_NOT_FOUND: /* TRANSLATOR COMMENT: Error when trying to determine recycle bin version */ ver_string = g_strdup (_("??? (empty folder)")); break; case VERSION_INCONSISTENT: /* TRANSLATOR COMMENT: Error when trying to determine recycle bin version */ ver_string = g_strdup (_("??? (version inconsistent)")); break; default: ver_string = g_strdup_printf ("%" G_GUINT64_FORMAT, version); } maybe_convert_fprintf (outfile, _("Version: %s"), ver_string); g_free (ver_string); fputs ("\n\n", outfile); if (is_info2) /* TRANSLATOR COMMENT: "Gone" means file is permanently deleted */ maybe_convert_fprintf (outfile, _("Index%sDeleted Time%sGone?%sSize%sPath"), delim, delim, delim, delim); else maybe_convert_fprintf (outfile, _("Index%sDeleted Time%sSize%sPath"), delim, delim, delim); fputs ("\n", outfile); break; case OUTPUT_XML: fputs ("\n", outfile); /* No proper way to report wrong version info yet */ fprintf (outfile, "\n", (is_info2 ? "file" : "dir"), MAX (version, 0)); fprintf (outfile, " %s\n", utf8_filename); break; default: g_warn_if_reached (); } g_free (utf8_filename); g_debug ("Leaving %s()", __func__); } void print_record (rbin_struct *record, FILE *outfile) { char *utf8_filename, *timestr = NULL; GString *temp_timestr; GError *error = NULL; gboolean is_info2; char *index; extern char *legacy_encoding; extern gboolean has_unicode_filename; extern int output_format; extern char *delim; extern gboolean always_utf8; g_return_if_fail (record != NULL); g_return_if_fail (outfile != NULL); is_info2 = (record->type == RECYCLE_BIN_TYPE_FILE); index = is_info2 ? g_strdup_printf ("%u", record->index_n) : g_strdup (record->index_s); if (has_unicode_filename && !legacy_encoding) { utf8_filename = record->utf8_filename ? g_strdup (record->utf8_filename) : g_strdup (_("(File name not representable in UTF-8 encoding)")); } else /* this part is info2 only */ { /* * On Windows, conversion from the file path's legacy charset to display codepage * charset is most likely not supported unless the 2 legacy charsets happen to be * equal. Try -> UTF-8 -> and see which step fails. */ utf8_filename = g_convert (record->legacy_filename, -1, "UTF-8", legacy_encoding, NULL, NULL, &error); if (error) { g_warning (_("Error converting file name from %s encoding " "to UTF-8 for index %s: %s"), legacy_encoding, index, error->message); g_clear_error (&error); utf8_filename = g_strdup (_("(File name not representable in UTF-8 encoding)")); } } switch (output_format) { case OUTPUT_CSV: if ( NULL == ( temp_timestr = get_datetime_str (record->deltime, NULL) ) ) { g_warning (_("Error formatting file deletion time for record index %s."), index); timestr = g_strdup ("???"); } else timestr = g_string_free (temp_timestr, FALSE); fprintf (outfile, "%s%s%s%s", index, delim, timestr, delim); if (is_info2) maybe_convert_fprintf (outfile, "%s%s", record->emptied ? _("Yes") : _("No"), delim); fprintf (outfile, "%" G_GUINT64_FORMAT "%s", (uint64_t) record->filesize, delim); if (always_utf8) fprintf (outfile, "%s\n", utf8_filename); else { char *shown = g_locale_from_utf8 (utf8_filename, -1, NULL, NULL, &error); if (error) { g_warning (_("Error converting path name to display for record %s: %s"), index, error->message); g_clear_error (&error); shown = g_locale_from_utf8 ( _("(File name not representable in current language)"), -1, NULL, NULL, NULL); } fprintf (outfile, "%s\n", shown); g_free (shown); } break; case OUTPUT_XML: if ( NULL == ( temp_timestr = get_iso8601_datetime_str (record->deltime) ) ) { g_warning (_("Error formatting file deletion time for record index %s."), index); timestr = g_strdup ("???"); } else timestr = g_string_free (temp_timestr, FALSE); fprintf (outfile, " emptied ? 'Y' : 'N'); fprintf (outfile, "size=\"%" G_GUINT64_FORMAT "\">\n" " %s\n" " \n", record->filesize, utf8_filename); break; default: g_warn_if_reached (); } g_free (utf8_filename); g_free (timestr); g_free (index); } void print_version () { maybe_convert_fprintf (stdout, "%s %s\n", PACKAGE, VERSION); /* TRANSLATOR COMMENT: %s is software name */ maybe_convert_fprintf (stdout, _("%s is distributed under the " "BSD 3-Clause License.\n"), PACKAGE); /* TRANSLATOR COMMENT: 1st argument is software name, 2nd is official URL */ maybe_convert_fprintf (stdout, _("Information about %s can be found on\n\n\t%s\n"), PACKAGE, PACKAGE_URL); } void print_footer ( FILE *outfile) { extern int output_format; g_return_if_fail (outfile != NULL); g_debug ("Entering %s()", __func__); switch (output_format) { case OUTPUT_CSV: /* do nothing */ break; case OUTPUT_XML: fputs ("\n", outfile); break; default: g_return_if_reached (); break; } g_debug ("Leaving %s()", __func__); } /* GUI message box */ #ifdef G_OS_WIN32 #include static char * convert_with_fallback (const char *string, const char *fallback) { GError *err = NULL; char *output = g_locale_from_utf8 (string, -1, NULL, NULL, &err); if (err != NULL) { g_critical ("Failed to convert message to display: %s\n", err->message); g_clear_error (&err); return g_strdup (fallback); } return output; } void gui_message (const char *message) { char *title, *output; title = convert_with_fallback (_("This is a command line application"), "This is a command line application"); output = convert_with_fallback (message, "Fail to display help message. Please " "invoke program with '--help' option."); MessageBox (NULL, output, title, MB_OK | MB_ICONINFORMATION | MB_TOPMOST); g_free (title); g_free (output); } #endif /* vim: set sw=4 ts=4 noexpandtab : */ rifiuti2-0.6.1/src/utils.h000066400000000000000000000113311252727005000153520ustar00rootroot00000000000000/* * Copyright (C) 2007, 2015 Abel Cheung. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _UTILS_H #define _UTILS_H #include #include #include #include enum { RIFIUTI_ERR_ARG = 1, RIFIUTI_ERR_OPEN_FILE, RIFIUTI_ERR_BROKEN_FILE, RIFIUTI_ERR_ENCODING }; typedef enum { RECYCLE_BIN_TYPE_FILE, RECYCLE_BIN_TYPE_DIR, } rbin_type; enum { /* negative number means error when retrieving version info */ VERSION_INCONSISTENT = -2, VERSION_NOT_FOUND, FORMAT_VISTA = 1, FORMAT_WIN10, FORMAT_WIN98 = 4, FORMAT_WIN2K, }; enum { OUTPUT_CSV, OUTPUT_XML }; struct _rbin_struct { rbin_type type; uint64_t version; /* $Recycle.bin only */ union { /* number or file name */ uint32_t index_n; char *index_s; }; gboolean emptied; /* INFO2 only */ unsigned char drive; /* INFO2 only */ time_t deltime; uint64_t filesize; char *utf8_filename; char *legacy_filename; /* INFO2 only */ }; typedef struct _rbin_struct rbin_struct; /* Glib doc is lying; GStatBuf not available until 2.25. * Use the definition as of 2.44 */ #if !GLIB_CHECK_VERSION(2,25,0) # if (defined (__MINGW64_VERSION_MAJOR) || defined (_MSC_VER)) && !defined(_WIN64) typedef struct _stat32 GStatBuf; # else typedef struct stat GStatBuf; # endif #endif /* Most versions of recycle bin use full PATH_MAX (260 char) to represent file paths, * in either ANSI or Unicode variations, except Windows 10 which uses variable size. */ #define WIN_PATH_MAX 0x104 /* shared functions */ time_t win_filetime_to_epoch (uint64_t win_filetime ); char * utf16le_to_utf8 (const gunichar2 *str , glong len , glong *items_read , glong *items_written , GError **error ); char * filter_escapes (const char *str ); void print_header (FILE *outfile , char *infilename , int64_t version , gboolean is_info2 ); void print_record (rbin_struct *record , FILE *outfile ); void print_footer (FILE *outfile ); void print_version (); void my_debug_handler (const char *log_domain , GLogLevelFlags log_level , const char *message , gpointer data ); void maybe_convert_fprintf (FILE *file , const char *format , ...); #ifdef G_OS_WIN32 void gui_message (const char *message ); #endif #endif /* vim: set sw=4 ts=4 noexpandtab : */ rifiuti2-0.6.1/test/000077500000000000000000000000001252727005000142325ustar00rootroot00000000000000rifiuti2-0.6.1/test/Makefile.am000066400000000000000000000066271252727005000163010ustar00rootroot00000000000000# Copyright (C) 2015 Abel Cheung. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the project nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # The `:;' works around a Bash 3.2 bug when the output is not writable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac :;{ \ echo '# Signature of the current package.' && \ echo 'm4_define([AT_PACKAGE_NAME], [$(PACKAGE_NAME)])' && \ echo 'm4_define([AT_PACKAGE_TARNAME], [$(PACKAGE_TARNAME)])' && \ echo 'm4_define([AT_PACKAGE_VERSION], [$(PACKAGE_VERSION)])' && \ echo 'm4_define([AT_PACKAGE_STRING], [$(PACKAGE_STRING)])' && \ echo 'm4_define([AT_PACKAGE_BUGREPORT], [$(PACKAGE_BUGREPORT)])'; \ echo 'm4_define([AT_PACKAGE_URL], [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' TESTSUITE = $(srcdir)/testsuite EXTRA_DIST = \ rifiuti.dtd \ samples \ $(srcdir)/package.m4 \ testsuite.at \ $(TESTSUITE) \ atlocal.in AM_CPPFLAGS = $(GLIB_CFLAGS) noinst_PROGRAMS = getcharset getcharset_LDADD = $(GLIB_LIBS) check-local: atconfig atlocal $(TESTSUITE) $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) installcheck-local: atconfig atlocal $(TESTSUITE) $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' \ $(TESTSUITEFLAGS) clean-local: test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' --clean -rm -f *.tmp AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te AUTOTEST = $(AUTOM4TE) --language=autotest $(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4 $(INC_AT_FILES) $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at mv $@.tmp $@ INC_AT_FILES = \ test_cli_option.at \ test_common.at \ test_encoding.at \ test_parse_info2.at \ test_parse_dir.at \ test_read_write.at \ test_xml.at EXTRA_DIST += $(INC_AT_FILES) DISTCLEANFILES = atconfig atlocal CLEANFILES = testsuite.log MAINTAINERCLEANFILES = testsuite $(srcdir)/package.m4 GITIGNOREFILES = testsuite.dir -include $(top_srcdir)/git.mk rifiuti2-0.6.1/test/atlocal.in000066400000000000000000000010461252727005000162020ustar00rootroot00000000000000# -*- shell-script -*- # @configure_input@ # Configurable variable values for Autoconf test suite. # prog checks has_iconv="test 'x@ICONV@' != 'x'" has_xmllint="test 'x@XMLLINT@' != 'x'" has_perl="test 'x@PERL@' != 'x'" xmllint="@XMLLINT@" # detect & set env is_mingw="test 'x@os_mingw@' != 'x'" is_bsd="test 'x@os_bsd@' != 'x'" getcharset="$abs_buildddir/getcharset" set_ascii="env CHARSET=ASCII" set_utf8="env CHARSET=UTF-8" # abbrev progf="$abs_top_builddir/src/rifiuti" progd="$abs_top_builddir/src/rifiuti-vista" sample="$abs_srcdir/samples" rifiuti2-0.6.1/test/getcharset.c000066400000000000000000000002421252727005000165250ustar00rootroot00000000000000#include #include #include int main() { const char *charset; setlocale(LC_ALL, ""); g_get_charset(&charset); puts (charset); } rifiuti2-0.6.1/test/rifiuti.dtd000066400000000000000000000004771252727005000164120ustar00rootroot00000000000000 rifiuti2-0.6.1/test/samples/000077500000000000000000000000001252727005000156765ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/INFO2-empty000066400000000000000000000000241252727005000175660ustar00rootroot00000000000000 rifiuti2-0.6.1/test/samples/INFO2-empty.txt000066400000000000000000000001171252727005000204070ustar00rootroot00000000000000Recycle bin path: 'INFO2-empty' Version: 5 Index Deleted Time Gone? Size Path rifiuti2-0.6.1/test/samples/INFO2-sample1000066400000000000000000000310241252727005000177760ustar00rootroot00000000000000 D )C:\DOCUME~1\ALLUSE~1\Desktop\е~1.LNKp\еʵ.lnk,J Z9C:\Documents and Settings\All Users\Desktop\ gSLhb͋xQ.lnkC:\Documents and Settings\Administrator\Desktop\wongsir_url.txt-@L=C:\Documents and Settings\Administrator\Desktop\wongsir_url.txtC:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.bin.@Č?p,C:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.binC:\Documents and Settings\Administrator\Desktop\theme\.svn/ fE C:\Documents and Settings\Administrator\Desktop\theme\.svnC:\Documents and Settings\Administrator\Desktop\Config Client0EXC:\Documents and Settings\Administrator\Desktop\Config ClientC:\Documents and Settings\Administrator\Desktop\Config Client.7z1E0C:\Documents and Settings\Administrator\Desktop\Config Client.7zC:\Documents and Settings\All Users\Desktop\Wireshark.lnk2r+JC:\Documents and Settings\All Users\Desktop\Wireshark.lnkC:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar9FJ)C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline@[J)C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConlineC:\DOCUME~1\ADMINI~1\Desktop\360~1.LNKesktop\360.lnkAJC:\Documents and Settings\Administrator\Desktop\360Oi{.lnkC:\Documents and Settings\Administrator\Desktop\gdbB`HJ)C:\Documents and Settings\Administrator\Desktop\gdbC:\Documents and Settings\Administrator\Desktop\gdb.zipC`HJ)C:\Documents and Settings\Administrator\Desktop\gdb.zipC:\Documents and Settings\Administrator\Desktop\recovered filesD 7:JC:\Documents and Settings\Administrator\Desktop\recovered filesC:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConlineEwJ)C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConlineC:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exeFpwJNC:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exeC:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exeGpwJNC:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exerifiuti2-0.6.1/test/samples/INFO2-sample1-alt.txt000066400000000000000000000031411252727005000213710ustar00rootroot00000000000000Recycle bin path: 'INFO2-sample1' Version: 5 Index Deleted Time Gone? Size Path 44 2008-10-28 15:53:42 No 4096 C:\DOCUME~1\ALLUSE~1\Desktop\有道桌~1.LNK 45 2008-11-03 15:01:59 No 4096 C:\Documents and Settings\Administrator\Desktop\wongsir_url.txt 46 2008-11-06 09:20:58 No 2912256 C:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.bin 47 2008-11-13 12:08:39 No 765952 C:\Documents and Settings\Administrator\Desktop\theme\.svn 48 2008-11-13 12:11:33 No 5812224 C:\Documents and Settings\Administrator\Desktop\Config Client 49 2008-11-13 12:11:36 No 1847296 C:\Documents and Settings\Administrator\Desktop\Config Client.7z 50 2008-11-19 04:42:04 No 4096 C:\Documents and Settings\All Users\Desktop\Wireshark.lnk 57 2008-11-19 05:07:15 No 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar 64 2008-11-19 05:07:35 Yes 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline 65 2008-11-19 05:17:12 No 4096 C:\DOCUME~1\ADMINI~1\Desktop\360保~1.LNK 66 2008-11-19 05:21:37 No 2732032 C:\Documents and Settings\Administrator\Desktop\gdb 67 2008-11-19 05:21:37 No 2723840 C:\Documents and Settings\Administrator\Desktop\gdb.zip 68 2008-11-19 11:34:23 No 0 C:\Documents and Settings\Administrator\Desktop\recovered files 69 2008-11-19 18:51:45 No 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline 70 2008-11-19 18:51:45 No 5169152 C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exe 71 2008-11-19 18:51:45 No 5169152 C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exe rifiuti2-0.6.1/test/samples/INFO2-sample1.txt000066400000000000000000000032161252727005000206160ustar00rootroot00000000000000Recycle bin path: 'INFO2-sample1' Version: 5 Index Deleted Time Gone? Size Path 44 2008-10-28 15:53:42 No 4096 C:\Documents and Settings\All Users\Desktop\有道桌面词典.lnk 45 2008-11-03 15:01:59 No 4096 C:\Documents and Settings\Administrator\Desktop\wongsir_url.txt 46 2008-11-06 09:20:58 No 2912256 C:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.bin 47 2008-11-13 12:08:39 No 765952 C:\Documents and Settings\Administrator\Desktop\theme\.svn 48 2008-11-13 12:11:33 No 5812224 C:\Documents and Settings\Administrator\Desktop\Config Client 49 2008-11-13 12:11:36 No 1847296 C:\Documents and Settings\Administrator\Desktop\Config Client.7z 50 2008-11-19 04:42:04 No 4096 C:\Documents and Settings\All Users\Desktop\Wireshark.lnk 57 2008-11-19 05:07:15 No 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar 64 2008-11-19 05:07:35 Yes 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline 65 2008-11-19 05:17:12 No 4096 C:\Documents and Settings\Administrator\Desktop\360保险箱.lnk 66 2008-11-19 05:21:37 No 2732032 C:\Documents and Settings\Administrator\Desktop\gdb 67 2008-11-19 05:21:37 No 2723840 C:\Documents and Settings\Administrator\Desktop\gdb.zip 68 2008-11-19 11:34:23 No 0 C:\Documents and Settings\Administrator\Desktop\recovered files 69 2008-11-19 18:51:45 No 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline 70 2008-11-19 18:51:45 No 5169152 C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exe 71 2008-11-19 18:51:45 No 5169152 C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exe rifiuti2-0.6.1/test/samples/INFO2-sample1.xml000066400000000000000000000067741252727005000206130ustar00rootroot00000000000000 test_case/INFO2 5 44 N 4096 C:\Documents and Settings\All Users\Desktop\有道桌面词典.lnk 45 N 4096 C:\Documents and Settings\Administrator\Desktop\wongsir_url.txt 46 N 2912256 C:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.bin 47 N 765952 C:\Documents and Settings\Administrator\Desktop\theme\.svn 48 N 5812224 C:\Documents and Settings\Administrator\Desktop\Config Client 49 N 1847296 C:\Documents and Settings\Administrator\Desktop\Config Client.7z 50 N 4096 C:\Documents and Settings\All Users\Desktop\Wireshark.lnk 57 N 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar 64 Y 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline 65 N 4096 C:\Documents and Settings\Administrator\Desktop\360保险箱.lnk 66 N 2732032 C:\Documents and Settings\Administrator\Desktop\gdb 67 N 2723840 C:\Documents and Settings\Administrator\Desktop\gdb.zip 68 N 0 C:\Documents and Settings\Administrator\Desktop\recovered files 69 N 2727936 C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline 70 N 5169152 C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exe 71 N 5169152 C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exe rifiuti2-0.6.1/test/samples/INFO2-sample2000066400000000000000000000036741252727005000200110ustar00rootroot00000000000000 YYC:\WINDOWS\All Users\Desktop\Connect to the Internet.LNKternet.LNKYCC0C&CY0CYbCwY0LCCCYdY0Y\JYCHC4YtCzC:\WINDOWS\Desktop\Online Servicese Services1WS\Desktop\Online Services\AYCC0C&CY0CYbCwY0LCCCYdY0Y\JYCHC4Y Csz:\WINDOWS\Desktop\IE9-WindowsVista-x64-enu.exe64-enu.exe,Y4CC0C&CY04CYbCwY0LCC8CYdY0Y\JY8CH8C4Y8C?NMzC:\My Documents\Rsum.txt.txtm.txt.txtD\DC3.TXTz<v=hWEC0C&C0WEbCw㐁0LCCWE|0\J<WEHWE?D`A{C:\WINDOWS\Desktop\winzip100.exezip100.exeDC4.EXE| @Y̺CC0C&C0̺CYbCw㐁0LCCкCYdY0Y\JYкCHкC4YC {_:\WINDOWS\Desktop\111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111CF{C:\WINDOWS\Desktop\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345C`F1{rifiuti2-0.6.1/test/samples/INFO2-sample2.txt000066400000000000000000000017531252727005000206230ustar00rootroot00000000000000Recycle bin path: 'INFO2-sample2' Version: 4 Index Deleted Time Gone? Size Path 0 2015-04-20 00:07:36 No 32768 C:\WINDOWS\All Users\Desktop\Connect to the Internet.LNK 1 2015-04-20 00:07:42 No 32768 C:\WINDOWS\Desktop\Online Services 2 2015-04-20 00:09:43 Yes 524288 C:\WINDOWS\Desktop\IE9-WindowsVista-x64-enu.exe 3 2015-04-20 01:04:33 No 32768 C:\My Documents\Résumé.txt.txt 4 2015-04-20 01:05:01 No 6258688 C:\WINDOWS\Desktop\winzip100.exe 5 2015-04-20 01:05:41 Yes 32768 C:\WINDOWS\Desktop\111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 6 2015-04-20 01:06:12 No 32768 C:\WINDOWS\Desktop\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 rifiuti2-0.6.1/test/samples/INFO2-sample2.xml000066400000000000000000000030431252727005000205760ustar00rootroot00000000000000 INFO2-sample2 C:\WINDOWS\All Users\Desktop\Connect to the Internet.LNK C:\WINDOWS\Desktop\Online Services C:\WINDOWS\Desktop\IE9-WindowsVista-x64-enu.exe C:\My Documents\Résumé.txt.txt C:\WINDOWS\Desktop\winzip100.exe C:\WINDOWS\Desktop\111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 C:\WINDOWS\Desktop\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 rifiuti2-0.6.1/test/samples/dir-empty.txt000066400000000000000000000001301252727005000203430ustar00rootroot00000000000000Recycle bin path: 'dir-empty' Version: ??? (empty folder) Index Deleted Time Size Path rifiuti2-0.6.1/test/samples/dir-empty/000077500000000000000000000000001252727005000176105ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/dir-empty/desktop.ini000066400000000000000000000002011252727005000217530ustar00rootroot00000000000000[.ShellClassInfo] CLSID={645FF040-5081-101B-9F08-00AA002F954E} LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-8964 rifiuti2-0.6.1/test/samples/dir-mixed.txt000066400000000000000000000004211252727005000203160ustar00rootroot00000000000000Recycle bin path: 'dir-mixed' Version: ??? (version inconsistent) Index Deleted Time Size Path $IEQWWMF.exe 2007-09-21 08:38:30 679936 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\fmdata.exe $IDNLPD4.exe 2015-04-19 10:50:51 872448 C:\Temp\FAU\FAU.x86\dd.exe rifiuti2-0.6.1/test/samples/dir-mixed/000077500000000000000000000000001252727005000175605ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/dir-mixed/$IDNLPD4.exe000066400000000000000000000001221252727005000213600ustar00rootroot00000000000000P `N zC:\Temp\FAU\FAU.x86\dd.exerifiuti2-0.6.1/test/samples/dir-mixed/$IEQWWMF.exe000066400000000000000000000010401252727005000214410ustar00rootroot00000000000000` `{*C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\fmdata.exerifiuti2-0.6.1/test/samples/dir-sample1.txt000066400000000000000000000035741252727005000205660ustar00rootroot00000000000000Recycle bin path: 'dir-sample1' Version: 1 Index Deleted Time Size Path $IUVFB0M.rtf 2007-09-21 06:32:46 155 C:\Users\student\Desktop\New Rich Text Document.rtf $I0JGHX7 2007-09-21 06:47:49 0 C:\Users\student\Desktop\New Folder 1 $I1IS2OK.txt 2007-09-21 06:48:13 0 C:\Users\student\Desktop\New Text Document blah.txt $IYAR1YY.exe 2007-09-21 07:54:23 20480 C:\dd.exe $I95CUKU 2007-09-21 08:02:59 4096 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\sparsefile $IHMU3NR.zip 2007-09-21 08:17:19 5025829 C:\Users\student\Downloads\fau-1.3.0.2355(rc3).zip $I7FV8IY.exe 2007-09-21 08:23:18 153478296 C:\Users\student\Downloads\VMware-server-installer-1.0.4-56528.exe $IMG2SSB 2007-09-21 08:28:57 0 C:\Users\student\Desktop\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 $IZK01YL.txt 2007-09-21 08:31:35 11 C:\Users\student\Desktop\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012\1234567.txt $I1TDH1G.exe 2007-09-21 08:38:30 704512 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\nc.exe $IEQWWMF.exe 2007-09-21 08:38:30 679936 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\fmdata.exe $IFRN1CZ.exe 2007-09-21 08:38:30 110592 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\wipe.exe $IW527XU.exe 2007-09-21 08:38:30 331776 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\volume_dump.exe $IC6GEAW.exe 2007-09-21 08:50:16 20480 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\dd.exe $IZUFRX4.vmdk 2007-09-21 09:22:25 10737418240 C:\Virtual Machines\Windows XP Professional\Windows XP Professional-flat.vmdk rifiuti2-0.6.1/test/samples/dir-sample1.xml000066400000000000000000000065571252727005000205530ustar00rootroot00000000000000 $IZK01YL.txt 11 C:\Users\student\Desktop\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012\1234567.txt $IW527XU.exe 331776 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\volume_dump.exe $IHMU3NR.zip 5025829 C:\Users\student\Downloads\fau-1.3.0.2355(rc3).zip $I7FV8IY.exe 153478296 C:\Users\student\Downloads\VMware-server-installer-1.0.4-56528.exe $I95CUKU 4096 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\sparsefile $IC6GEAW.exe 20480 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\dd.exe $I0JGHX7 0 C:\Users\student\Desktop\New Folder 1 $IYAR1YY.exe 20480 C:\dd.exe $IFRN1CZ.exe 110592 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\wipe.exe $IEQWWMF.exe 679936 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\fmdata.exe $IUVFB0M.rtf 155 C:\Users\student\Desktop\New Rich Text Document.rtf $I1TDH1G.exe 704512 C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\nc.exe $I1IS2OK.txt 0 C:\Users\student\Desktop\New Text Document blah.txt $IMG2SSB 0 C:\Users\student\Desktop\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 $IZUFRX4.vmdk 10737418240 C:\Virtual Machines\Windows XP Professional\Windows XP Professional-flat.vmdk rifiuti2-0.6.1/test/samples/dir-sample1/000077500000000000000000000000001252727005000200145ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/dir-sample1/$I0JGHX7000066400000000000000000000010401252727005000210160ustar00rootroot00000000000000SC:\Users\student\Desktop\New Folder 1rifiuti2-0.6.1/test/samples/dir-sample1/$I1IS2OK.txt000066400000000000000000000010401252727005000216350ustar00rootroot00000000000000`daC:\Users\student\Desktop\New Text Document blah.txtrifiuti2-0.6.1/test/samples/dir-sample1/$I1TDH1G.exe000066400000000000000000000010401252727005000215570ustar00rootroot00000000000000 `{*C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\nc.exerifiuti2-0.6.1/test/samples/dir-sample1/$I7FV8IY.exe000066400000000000000000000010401252727005000216230ustar00rootroot00000000000000% N>(C:\Users\student\Downloads\VMware-server-installer-1.0.4-56528.exerifiuti2-0.6.1/test/samples/dir-sample1/$I95CUKU000066400000000000000000000010401252727005000210340ustar00rootroot00000000000000%C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\sparsefilerifiuti2-0.6.1/test/samples/dir-sample1/$IC6GEAW.exe000066400000000000000000000010371252727005000216110ustar00rootroot00000000000000P/Tn,C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\dd.exerifiuti2-0.6.1/test/samples/dir-sample1/$IEQWWMF.exe000066400000000000000000000010401252727005000216750ustar00rootroot00000000000000` `{*C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\fmdata.exerifiuti2-0.6.1/test/samples/dir-sample1/$IFRN1CZ.exe000066400000000000000000000010401252727005000216320ustar00rootroot00000000000000`{*C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\wipe.exerifiuti2-0.6.1/test/samples/dir-sample1/$IHMU3NR.zip000066400000000000000000000010401252727005000216640ustar00rootroot00000000000000%L'C:\Users\student\Downloads\fau-1.3.0.2355(rc3).ziprifiuti2-0.6.1/test/samples/dir-sample1/$IMG2SSB000066400000000000000000000010401252727005000210440ustar00rootroot00000000000000Ps)C:\Users\student\Desktop\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012rifiuti2-0.6.1/test/samples/dir-sample1/$IUVFB0M.rtf000066400000000000000000000010401252727005000216400ustar00rootroot00000000000000,29C:\Users\student\Desktop\New Rich Text Document.rtfrifiuti2-0.6.1/test/samples/dir-sample1/$IW527XU.exe000066400000000000000000000010401252727005000216100ustar00rootroot00000000000000PZ}*C:\Users\student\Downloads\fau-1.3.0.2355(rc3)\fau\FAU.x86\volume_dump.exerifiuti2-0.6.1/test/samples/dir-sample1/$IYAR1YY.exe000066400000000000000000000010371252727005000216730ustar00rootroot00000000000000Pp$C:\dd.exerifiuti2-0.6.1/test/samples/dir-sample1/$IZK01YL.txt000066400000000000000000000010401252727005000216570ustar00rootroot00000000000000 bt)C:\Users\student\Desktop\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012\1234567.txtrifiuti2-0.6.1/test/samples/dir-sample1/$IZUFRX4.vmdk000066400000000000000000000010401252727005000220510ustar00rootroot00000000000000`p0C:\Virtual Machines\Windows XP Professional\Windows XP Professional-flat.vmdkrifiuti2-0.6.1/test/samples/dir-sample1/$RUVFB0M.rtf000066400000000000000000000002301252727005000216510ustar00rootroot00000000000000{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fcharset0 Arial;}} {\*\generator Msftedit 5.41.21.2506;}\viewkind4\uc1\pard\lang1033\f0\fs20 lalala hahaha\par } rifiuti2-0.6.1/test/samples/dir-win10-01.txt000066400000000000000000000013521252727005000203700ustar00rootroot00000000000000Recycle bin path: 'dir-win10-01' Version: 2 Index Deleted Time Size Path $IKEGS1G 2015-04-04 17:19:52 0 C:\Users\tester\12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 $IQ7LAXT.png 2015-04-04 17:20:01 6455 C:\Users\tester\Pictures\web-canvas.png $I7R52EG.txt 2015-04-04 17:24:09 14 C:\Temp\foobat.txt.txt $IBBFODN 2015-04-07 23:19:35 7 C:\Temp\𨳊𨶙閪邨鰂 $IHO61YT 2015-04-07 23:32:07 12884901888 C:\Temp\largesparsefile $IROMPZ0.exe 2015-04-19 10:49:59 1761792 C:\Temp\FAU\FAU.x64\dd.exe $IDNLPD4.exe 2015-04-19 10:50:51 872448 C:\Temp\FAU\FAU.x86\dd.exe rifiuti2-0.6.1/test/samples/dir-win10-01.xml000066400000000000000000000023671252727005000203600ustar00rootroot00000000000000 test/samples/dir-win10-01 C:\Temp\foobat.txt.txt C:\Temp\𨳊𨶙閪邨鰂 C:\Temp\FAU\FAU.x86\dd.exe C:\Temp\largesparsefile C:\Users\tester\12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 C:\Users\tester\Pictures\web-canvas.png C:\Temp\FAU\FAU.x64\dd.exe rifiuti2-0.6.1/test/samples/dir-win10-01/000077500000000000000000000000001252727005000176265ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/dir-win10-01/$I7R52EG.txt000066400000000000000000000001121252727005000214110ustar00rootroot000000000000008)nC:\Temp\foobat.txt.txtrifiuti2-0.6.1/test/samples/dir-win10-01/$IBBFODN000066400000000000000000000000741252727005000206610ustar00rootroot00000000000000OqC:\Temp\ccؙݪrifiuti2-0.6.1/test/samples/dir-win10-01/$IDNLPD4.exe000066400000000000000000000001221252727005000214260ustar00rootroot00000000000000P `N zC:\Temp\FAU\FAU.x86\dd.exerifiuti2-0.6.1/test/samples/dir-win10-01/$IHO61YT000066400000000000000000000001141252727005000206540ustar00rootroot00000000000000NqC:\Temp\largesparsefilerifiuti2-0.6.1/test/samples/dir-win10-01/$IKEGS1G000066400000000000000000000010121252727005000206410ustar00rootroot00000000000000Z;nC:\Users\tester\12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890rifiuti2-0.6.1/test/samples/dir-win10-01/$IQ7LAXT.png000066400000000000000000000001541252727005000214710ustar00rootroot000000000000007nn(C:\Users\tester\Pictures\web-canvas.pngrifiuti2-0.6.1/test/samples/dir-win10-01/$IROMPZ0.exe000066400000000000000000000001221252727005000214700ustar00rootroot00000000000000@ݔzC:\Temp\FAU\FAU.x64\dd.exerifiuti2-0.6.1/test/samples/dir-win10-01/$R7R52EG.txt000066400000000000000000000000161252727005000214250ustar00rootroot00000000000000Blah blah blahrifiuti2-0.6.1/test/samples/dir-win10-01/$RKEGS1G000066400000000000000000000000001252727005000206460ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/dir-win10-01/$RQ7LAXT.png000066400000000000000000000144671252727005000215160ustar00rootroot00000000000000PNG  IHDRl~QgAMA asRGBPLTE rxwDFH Z[[-/189<ABDG{{UVY[]a7:=㬰kmp58;<>Bmorefjwm69="$&37:(+-9}h9AAwꌎpãrbi%-"ø~uEIIϼTlN5WW,j9{)}޿[(,WA8DulblgaJe̷CB&MÂ`mpgWI쉌¤Z,M|ZOϓ[N(/CB'2_tHkߧb6a|<\BY73I{}p֣|5PYc;{^j콻X[VM8Ī鞞-?Ve13lrCv=u.N.ރF|n~d;_+ sZ$@QABEqjQ/p=SO,{~$F«TJHZFk\(mD-TT#*!X0I dH(1~-窔T.gD-HEBxDOT ,~ڰ-(8Gggδ9axUH*}O^pa}kBT$GGӯ0f P*E"t?T_p9s=]> /\$x uP"a3lwg$},(&uܝ3{ $l<61{->a ܽz?g-+H%`ľ{2a;tw׮ぁ N ُ} >[b?]rE&l0&@?25Cp)$ ɔX$<#/#G_7ߘx18@(gdz '~]}xwO/T( )lg[Aў={1~͚5 W&>! Ӎ AٱpOuw4JuG/,1%l^m=V@[ }i֬wf&B-! j ~!pGêǷÉ<d>Z2Z\#;amIrEl*i*lK <:24npӳe:e2п}ǎ_@m8PW%%[<vV$t۶,˘'}!/@k/_b6?hB!'x:Lg߸?4G_ӟxvAQQ[ׯ_/0\I$Fq$g?4h^~Pq(}ڹs=u}jR 9HU&J$=^'?Dş_cۆ1DZώيB')a3`!G(303^wnl\V 1ށw~ܹoӳIu\'L-NS*0,㶊%<n*m =ysmr4!&1;ҺO0ܮ?bG"=& BY6`b/NV)~ c~++aw{fg鼜 T~x&FiggݷV~"[cif[߮rvo*$Z6lTڑOnn۝ =Bw:uXvZ1lDG~YETi45][>1 qꅭ==Y8nBB"MLVKLcz `M|uDؕM5o]y9^L8mlyzZgϡ{*B:L*`7WG̸؃-j |||bDTT%,ys7jzϗĆ{3믕h

>KDh4⪬G?_SU$ɿ҃w\{ӦlB@/C JۉDPDD͒kЎ5Wh4%ĝ q\</^ ./U0}Z}äb(t˙L`#<#~δ}J|@UJPvFxn6{`l8:`cIA6ܸ熍6IЭX)=v%=tqٔYDI-#t0().FolL^w߾}i4P GDz)qw(2O@;ڕ;pCXp0=lPll0^_{Id^dɵҬPh:7Ŏސ Rym #…K{o .YU 2fiS}Ig@% ؇2|eQ[˖5-&B!)z:]ḏbUJ٥rO :&1`&vDv8|Vq]P޴Tx _xȑ+S+Z_;{)4*!!+3 3S2[%^6}2861|!ƕ[qUz*7A} @9ꎋ?={6^Y~6!~玫"M؛Ur2B§%2>Zqn{퇗£XKrݩ{pa0gZ;KB%3 p6fC1L􌽧M |d-(zJ^RV5. XʰK/--3]ZVLw>p|\of& 8`lxDrA#Ტy-g6nnvjiy{DN زӳBC҄Qe%=DG 7FRRL,{ueA/G+*߼y!1'޻ 'ZtM&LPG)K`C%m`#۳'Om(Xa0 )5e*P-AFv:"Jr#(sOERc7Jj)RVˏ.]ҖG-t|oGGkDz3їqtC,ݤ?Ѥp'U".s|q,S%%7.z;Յ G<ǒ~+, q&z5'NCMj2RP,"cC. <7() -Ym\A$KaR|AIBo@ 𚛈M.Rll0Uf|CWr@KBooG<Oۖ' ?LQQ[S)a5f Ą$ƉVgffxxk[r?U___I1k%lo~G/hL!Lt߂+iZC(} $HTLvΔN|حanij ~DIX3lbR%pG?n3'ΞMEFGnҍߊWtBC3^)E{>-T#?YrwҲ.\TI5R~OԩDqHȌ/?3Qw:W'M1}k. _WsR̷ y2(w|z{YGmkxY=|6l-rys$땴T_MZCr^;zO#8oW/-T 52/ὄn! 6͵}1"H__ԺG'SN{TJj?ecŰ7DR5kkE}XCrnvrVSRflˢ=7 kfoقmr2z[5/OHL(C)cwƔI řzj @_sgF|aR3g ܣB(q,#oL9ߝg??v2 Nh8b1,Ͼ1e;9>qBR Çgq1nDh5C j5%͉cR1,8c2O)oN0&OS?~$!EaԫZ&N N2ᯍ}.L%St1ɘ3dž9ZZ ?PI:U7?Jgho3;?O?(K?+I>IENDB`rifiuti2-0.6.1/test/samples/dir-win10-01/desktop.ini000066400000000000000000000002011252727005000217710ustar00rootroot00000000000000[.ShellClassInfo] CLSID={645FF040-5081-101B-9F08-00AA002F954E} LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-8964 rifiuti2-0.6.1/test/samples/japanese-path-dir.txt000066400000000000000000000001441252727005000217320ustar00rootroot00000000000000Recycle bin path: './ごみ箱/dir-empty' Version: ??? (empty folder) Index Deleted Time Size Path rifiuti2-0.6.1/test/samples/japanese-path-file.txt000066400000000000000000000001331252727005000220710ustar00rootroot00000000000000Recycle bin path: './ごみ箱/INFO2-empty' Version: 5 Index Deleted Time Gone? Size Path rifiuti2-0.6.1/test/samples/ごみ箱/000077500000000000000000000000001252727005000211165ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/ごみ箱/INFO2-empty000066400000000000000000000000241252727005000230060ustar00rootroot00000000000000 rifiuti2-0.6.1/test/samples/ごみ箱/dir-empty/000077500000000000000000000000001252727005000230305ustar00rootroot00000000000000rifiuti2-0.6.1/test/samples/ごみ箱/dir-empty/desktop.ini000066400000000000000000000002011252727005000251730ustar00rootroot00000000000000[.ShellClassInfo] CLSID={645FF040-5081-101B-9F08-00AA002F954E} LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-8964 rifiuti2-0.6.1/test/test_cli_option.at000066400000000000000000000027121252727005000177600ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_SETUP([Short Options]) AT_KEYWORDS([option]) _r2_check_empty_option([-?]) _r2_check_empty_option([-v]) _r2_check_option([-t :]) _r2_check_option([-n]) _r2_check_option([-8]) AT_CLEANUP AT_SETUP([Long Options]) AT_KEYWORDS([option]) _r2_check_empty_option([--help-all]) _r2_check_option([--delimiter=:]) _r2_check_option([--no-heading]) _r2_check_option([--always-utf8]) AT_CLEANUP AT_SETUP([Invalid options]) AT_KEYWORDS([option]) _r2_check_empty_option([--invalid-option],[1]) AT_CHECK([$progf -l foobar $sample/INFO2-sample2], [4], [], [ignore]) AT_CLEANUP AT_SETUP([Wrong combinations]) AT_KEYWORDS([option]) _r2_check_option([-x -t :], [1]) _r2_check_option([-x -n], [1]) _r2_check_option([-x -8], [1]) AT_CLEANUP AT_SETUP([Err on no file args]) AT_KEYWORDS([file option]) _r2_check_ignore_err([-8], [1]) AT_CLEANUP AT_SETUP([Err on multiple file args]) AT_KEYWORDS([file option]) _r2_check_ignore_err([foo bar baz], [1]) AT_CLEANUP AT_SETUP([Escaped char in delimiter]) AT_KEYWORDS([option]) dnl FreeBSD sed does not support escaped chars AT_CHECK([$has_perl || exit 77]) AT_CHECK([ perl -p -e 's/\t/\n\t/g' < $sample/INFO2-sample1.txt > expout cd $sample $set_ascii $progf -8 -t "\n\t" INFO2-sample1 ],, [expout], []) AT_CHECK([ perl -p -e 's/\t/\n\t/g' < $sample/dir-sample1.txt > expout cd $sample $set_ascii $progd -8 -t "\n\t" dir-sample1 ],, [expout], []) AT_CLEANUP dnl vim: set ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/test_common.at000066400000000000000000000011551252727005000171110ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 m4_defun([_r2_check_empty_option], [ AT_CHECK([$progf $1], [$2], [ignore], [ignore]) AT_CHECK([$progd $1], [$2], [ignore], [ignore]) ]) m4_defun([_r2_check_option], [ AT_CHECK([$progf $1 $sample/INFO2-empty], [$2], [ignore], [ignore]) AT_CHECK([$progd $1 $sample/dir-empty], [$2], [ignore], [ignore]) ]) m4_defun([_r2_check_ignore_err], [ AT_CHECK([$progf $1], [$2], [$3], [ignore]) AT_CHECK([$progd $1], [$2], [$3], [ignore]) ]) m4_defun([_r2_basic_compare], [ AT_CHECK([ rm -f expout cp $sample/$2 expout cd $sample $set_ascii $1 ],, [expout]) ]) rifiuti2-0.6.1/test/test_encoding.at000066400000000000000000000044251252727005000174120ustar00rootroot00000000000000dnl -*- coding: utf-8; mode: m4; -*- dnl Test suite for rifiuti2 dnl dnl ごみ箱 is 'recycle bin' in Japanese dnl AT_SETUP([UTF-8 - No Fallback For Path]) AT_KEYWORDS([encoding]) AT_CHECK([ cp $sample/japanese-path-file.txt expout cd $sample $set_utf8 $progf ./ごみ箱/INFO2-empty ],, [expout]) AT_CHECK([ rm -f expout cp $sample/japanese-path-dir.txt expout cd $sample $set_utf8 $progd ./ごみ箱/dir-empty ],, [expout]) AT_CLEANUP dnl dnl For the case when entire non-ASCII path can't be displayed dnl AT_SETUP([Fallback For Path 1]) AT_KEYWORDS([encoding]) AT_CHECK([${has_perl} || exit 77]) dnl 1. Curse those quadrigraphs dnl 2. I hate writing regex with m4! Takes so much time to make it work, dnl and fragile as hell dnl 3. Path need to have ./ as prefix, without that and the middle slash dnl will be transformed into root of MinGW folder. This only happens dnl when folder with non-ASCII name is prepended before slash. Looks like dnl bug in g_win32_get_command_line() AT_CHECK([ PERLIO=":utf8" perl -C -p -e 's/@{:@@<:@\p{Han}\p{Hiragana}@:>@@:}@/sprintf "\\u%x", ord@{:@@S|@1@:}@/ge' < $sample/japanese-path-file.txt > expout cd $sample/ $set_ascii $progf ./ごみ箱/INFO2-empty ],, [expout], []) AT_CHECK([ PERLIO=":utf8" perl -C -p -e 's/@{:@@<:@\p{Han}\p{Hiragana}@:>@@:}@/sprintf "\\u%x", ord@{:@@S|@1@:}@/ge' < $sample/japanese-path-dir.txt > expout cd $sample/ $set_ascii $progd ./ごみ箱/dir-empty ],, [expout], []) AT_CLEANUP dnl dnl For the case when part of non-ASCII path can't be displayed dnl in CP950, only the character 箱 can be displayed as is dnl AT_SETUP([Fallback For Path 2]) AT_KEYWORDS([encoding]) AT_CHECK([${has_perl} || exit 77]) AT_CHECK([${has_iconv} || exit 77]) AT_CHECK([ PERLIO=":utf8" perl -C -p -e 's/@{:@@<:@\p{Hiragana}@:>@@:}@/sprintf "\\u%x", ord@{:@@S|@1@:}@/ge' < $sample/japanese-path-file.txt | iconv -f utf-8 -t cp950 > expout cd $sample/ env CHARSET=CP950 $progf ./ごみ箱/INFO2-empty ],, [expout], []) AT_CHECK([ PERLIO=":utf8" perl -C -p -e 's/@{:@@<:@\p{Hiragana}@:>@@:}@/sprintf "\\u%x", ord@{:@@S|@1@:}@/ge' < $sample/japanese-path-dir.txt | iconv -f utf-8 -t cp950 > expout cd $sample/ env CHARSET=CP950 $progd ./ごみ箱/dir-empty ],, [expout], []) AT_CLEANUP dnl vim: set fileencoding=utf-8 ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/test_faulty_dir.at000066400000000000000000000003531252727005000177620ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_SETUP([Index files of different versions]) AT_KEYWORDS([recycledir crafted]) _r2_basic_compare([$progd dir-mixed], [dir-mixed.txt]) AT_CLEANUP dnl vim: set ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/test_parse_dir.at000066400000000000000000000012651252727005000175730ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_SETUP([Empty $Recycle.bin]) AT_KEYWORDS([recycledir]) _r2_basic_compare([$progd dir-empty], [dir-empty.txt]) AT_CLEANUP AT_SETUP([$Recycle.bin Sample 1]) AT_KEYWORDS([recycledir]) _r2_basic_compare([$progd -8 dir-sample1], [dir-sample1.txt]) AT_CLEANUP AT_SETUP([$Recycle.bin Sample 2]) AT_KEYWORDS([recycledir]) _r2_basic_compare([$progd -8 dir-win10-01], [dir-win10-01.txt]) AT_CLEANUP AT_SETUP([$Recycle.bin single file]) AT_KEYWORDS([recycledir]) AT_CHECK([ grep 'IHO61YT' $sample/dir-win10-01.txt > expout $set_ascii $progd -n -8 $sample/dir-win10-01/\$IHO61YT ],, [expout], []) AT_CLEANUP dnl vim: set ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/test_parse_info2.at000066400000000000000000000011401252727005000200220ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_SETUP([Empty INFO2]) AT_KEYWORDS([info2]) _r2_basic_compare([$progf INFO2-empty], [INFO2-empty.txt]) AT_CLEANUP AT_SETUP([INFO2 Sample 1]) AT_KEYWORDS([info2]) _r2_basic_compare([$progf -8 INFO2-sample1], [INFO2-sample1.txt]) AT_CLEANUP AT_SETUP([INFO2 Sample 2]) AT_KEYWORDS([info2]) _r2_basic_compare([$progf -8 -l latin1 INFO2-sample2], [INFO2-sample2.txt]) AT_CLEANUP AT_SETUP([Legacy path names]) AT_KEYWORDS([info2]) _r2_basic_compare([$progf -8 -l CP936 INFO2-sample1], [INFO2-sample1-alt.txt]) AT_CLEANUP dnl vim: set ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/test_read_write.at000066400000000000000000000022671252727005000177530ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_SETUP([Err on non-existent input]) AT_KEYWORDS([file]) _r2_check_ignore_err([foobar], [2]) AT_CLEANUP AT_SETUP([Err on non-regular file (Unix)]) AT_KEYWORDS([file]) AT_CHECK([if $is_mingw; then exit 77; fi]) _r2_check_ignore_err([/dev/zero], [2]) AT_CLEANUP dnl g_file_test() was not so usable on Windows: NUL, CON etc are considered as regular files. dnl Therefore file can't be determined early as unusable, they have to be actually parsed. AT_SETUP([Err on non-regular file (Windows)]) AT_KEYWORDS([file]) AT_CHECK([if $is_mingw; then :; else exit 77; fi]) _r2_check_ignore_err([nul], [3]) AT_CLEANUP AT_SETUP([UTF-8 console/file output are equal]) AT_KEYWORDS([file]) AT_CHECK([ $progf -8 -o expout $sample/INFO2-sample1 $progf -8 $sample/INFO2-sample1 ],, [expout]) AT_CHECK([ $progd -8 -o expout $sample/dir-sample1 $progd -8 $sample/dir-sample1 ],, [expout]) AT_CLEANUP AT_SETUP([Read non-ASCII path]) AT_KEYWORDS([file encoding]) AT_CHECK([$progf $sample/ごみ箱/INFO2-empty],, [ignore], [ignore]) AT_CHECK([$progd $sample/ごみ箱/dir-empty],, [ignore], [ignore]) AT_CLEANUP dnl vim: set ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/test_xml.at000066400000000000000000000015721252727005000164240ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_SETUP([INFO2: XML validation]) AT_KEYWORDS([info2 xml]) AT_CHECK([${has_xmllint} || exit 77]) AT_CHECK([ $progf -x $sample/INFO2-sample1 | \ $xmllint --noout - ]) AT_CLEANUP AT_SETUP([INFO2: DTD validation]) AT_KEYWORDS([info2 xml]) AT_CHECK([${has_xmllint} || exit 77]) AT_CHECK([ $progf -x $sample/INFO2-sample1 | \ $xmllint --noout --dtdvalid $srcdir/rifiuti.dtd - ]) AT_CLEANUP AT_SETUP([$Recycle.bin: XML validation]) AT_KEYWORDS([recycledir xml]) AT_CHECK([${has_xmllint} || exit 77]) AT_CHECK([ $progd -x $sample/dir-sample1 | \ $xmllint --noout - ]) AT_CLEANUP AT_SETUP([$Recycle.bin: DTD validation]) AT_KEYWORDS([recycledir xml]) AT_CHECK([${has_xmllint} || exit 77]) AT_CHECK([ $progd -x $sample/dir-sample1 | \ $xmllint --noout --dtdvalid $srcdir/rifiuti.dtd - ]) AT_CLEANUP dnl vim: set ts=4 sw=4 noexpandtab : rifiuti2-0.6.1/test/testsuite.at000066400000000000000000000012151252727005000166100ustar00rootroot00000000000000dnl -*- mode: m4; -*- dnl Test suite for rifiuti2 AT_INIT AT_COPYRIGHT([Copyright (c) 2015, Abel Cheung]) m4_include([test_common.at]) AT_BANNER([Command Line Options]) m4_include([test_cli_option.at]) AT_BANNER([Basic Read/Write Check]) m4_include([test_read_write.at]) AT_BANNER([Parsing INFO2]) m4_include([test_parse_info2.at]) AT_BANNER([Parsing $Recycle.bin folder]) m4_include([test_parse_dir.at]) AT_BANNER([Parse faulty or crafted folder]) m4_include([test_faulty_dir.at]) AT_BANNER([Character Encoding Tests]) m4_include([test_encoding.at]) AT_BANNER([XML Validation]) m4_include([test_xml.at]) dnl vim: set ts=4 sw=4 noexpandtab :