pax_global_header 0000666 0000000 0000000 00000000064 12527270050 0014512 g ustar 00root root 0000000 0000000 52 comment=6d512d471ef0f83706c734885125a21012f97825
rifiuti2-0.6.1/ 0000775 0000000 0000000 00000000000 12527270050 0013253 5 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/.travis.yml 0000664 0000000 0000000 00000000350 12527270050 0015362 0 ustar 00root root 0000000 0000000 language: 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/ChangeLog 0000664 0000000 0000000 00000000270 12527270050 0015024 0 ustar 00root root 0000000 0000000 This 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.am 0000664 0000000 0000000 00000001116 12527270050 0015306 0 ustar 00root root 0000000 0000000 AUTOMAKE_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.md 0000664 0000000 0000000 00000003353 12527270050 0014355 0 ustar 00root root 0000000 0000000 ## 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.md 0000664 0000000 0000000 00000006666 12527270050 0014550 0 ustar 00root root 0000000 0000000 `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
*
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.sh 0000775 0000000 0000000 00000000110 12527270050 0015244 0 ustar 00root root 0000000 0000000 #!/bin/sh -ev
glib-gettextize --copy --force
autoreconf -f -i -v "$@"
rifiuti2-0.6.1/configure.ac 0000664 0000000 0000000 00000004024 12527270050 0015541 0 ustar 00root root 0000000 0000000 dnl 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.mk 0000664 0000000 0000000 00000003373 12527270050 0015350 0 ustar 00root root 0000000 0000000 #
# 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@(?)p@\1div@g;' | \
perl -p -e 's/(####CHANGELOG####)/\n$$1\n/' > $$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/ 0000775 0000000 0000000 00000000000 12527270050 0014203 5 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/docs/AUTHORS 0000664 0000000 0000000 00000000166 12527270050 0015256 0 ustar 00root root 0000000 0000000 Current version:
Copyright (C) 2007, 2015 Abel Cheung
Original version of rifiuti:
Copyright (C) 2003 Keith J. Jones
rifiuti2-0.6.1/docs/ChangeLog.old 0000664 0000000 0000000 00000011215 12527270050 0016532 0 ustar 00root root 0000000 0000000 *
*
* 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.md 0000664 0000000 0000000 00000005600 12527270050 0016116 0 ustar 00root root 0000000 0000000 ## 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/LICENSE 0000664 0000000 0000000 00000003141 12527270050 0015207 0 ustar 00root root 0000000 0000000 Other 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/THANKS 0000664 0000000 0000000 00000000745 12527270050 0015124 0 ustar 00root root 0000000 0000000 Obviously, 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.mk 0000664 0000000 0000000 00000023567 12527270050 0014404 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 12527270050 0013671 5 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/po/ChangeLog 0000664 0000000 0000000 00000000000 12527270050 0015431 0 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/po/LINGUAS 0000664 0000000 0000000 00000000006 12527270050 0014712 0 ustar 00root root 0000000 0000000 zh_HK
rifiuti2-0.6.1/po/POTFILES.in 0000664 0000000 0000000 00000000056 12527270050 0015447 0 ustar 00root root 0000000 0000000 src/rifiuti-vista.c
src/rifiuti.c
src/utils.c
rifiuti2-0.6.1/po/zh_HK.po 0000664 0000000 0000000 00000033674 12527270050 0015251 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 12527270050 0014042 5 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/src/.indent.pro 0000664 0000000 0000000 00000001052 12527270050 0016121 0 ustar 00root root 0000000 0000000 /*
* 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.am 0000664 0000000 0000000 00000001645 12527270050 0016104 0 ustar 00root root 0000000 0000000 AM_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.c 0000664 0000000 0000000 00000044536 12527270050 0017021 0 ustar 00root root 0000000 0000000 /*
* 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.h 0000664 0000000 0000000 00000003643 12527270050 0017020 0 ustar 00root root 0000000 0000000 /*
* 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.1 0000664 0000000 0000000 00000032471 12527270050 0015606 0 ustar 00root root 0000000 0000000 .\"-
.\" 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.c 0000664 0000000 0000000 00000037120 12527270050 0015664 0 ustar 00root root 0000000 0000000 /*
* 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.h 0000664 0000000 0000000 00000004441 12527270050 0015671 0 ustar 00root root 0000000 0000000 /*
* 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.c 0000664 0000000 0000000 00000035046 12527270050 0015356 0 ustar 00root root 0000000 0000000 /*
* 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.h 0000664 0000000 0000000 00000011331 12527270050 0015352 0 ustar 00root root 0000000 0000000 /*
* 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/ 0000775 0000000 0000000 00000000000 12527270050 0014232 5 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/test/Makefile.am 0000664 0000000 0000000 00000006627 12527270050 0016301 0 ustar 00root root 0000000 0000000 # 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.in 0000664 0000000 0000000 00000001046 12527270050 0016202 0 ustar 00root root 0000000 0000000 # -*- 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.c 0000664 0000000 0000000 00000000242 12527270050 0016525 0 ustar 00root root 0000000 0000000 #include
#include
#include
int main()
{
const char *charset;
setlocale(LC_ALL, "");
g_get_charset(&charset);
puts (charset);
}
rifiuti2-0.6.1/test/rifiuti.dtd 0000664 0000000 0000000 00000000477 12527270050 0016412 0 ustar 00root root 0000000 0000000
rifiuti2-0.6.1/test/samples/ 0000775 0000000 0000000 00000000000 12527270050 0015676 5 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/test/samples/INFO2-empty 0000664 0000000 0000000 00000000024 12527270050 0017566 0 ustar 00root root 0000000 0000000 rifiuti2-0.6.1/test/samples/INFO2-empty.txt 0000664 0000000 0000000 00000000117 12527270050 0020407 0 ustar 00root root 0000000 0000000 Recycle bin path: 'INFO2-empty'
Version: 5
Index Deleted Time Gone? Size Path
rifiuti2-0.6.1/test/samples/INFO2-sample1 0000664 0000000 0000000 00000031024 12527270050 0017776 0 ustar 00root root 0000000 0000000 D )C:\DOCUME~1\ALLUSE~1\Desktop\е~1.LNK p\еʵ.lnk , J
Z9 C : \ D o c u m e n t s a n d S e t t i n g s \ A l l U s e r s \ D e s k t o p \ gSLhb͋xQ. l n k C:\Documents and Settings\Administrator\Desktop\wongsir_url.txt - @L= C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ w o n g s i r _ u r l . t x t C:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.bin . @Č? p, C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ d d - w r t . v 2 4 _ m i n i _ w r t 5 4 g . b i n C:\Documents and Settings\Administrator\Desktop\theme\.svn / fE C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ t h e m e \ . s v n C:\Documents and Settings\Administrator\Desktop\Config Client 0 E X C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ C o n f i g C l i e n t C:\Documents and Settings\Administrator\Desktop\Config Client.7z 1 E 0 C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ C o n f i g C l i e n t . 7 z C:\Documents and Settings\All Users\Desktop\Wireshark.lnk 2 r+J C : \ D o c u m e n t s a n d S e t t i n g s \ A l l U s e r s \ D e s k t o p \ W i r e s h a r k . l n k C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar 9 FJ ) C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ G e t D a t a B a c k f o r F A T - v 3 . 6 3 _ P C o n l i n e . r a r :\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline @ [J ) C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ G e t D a t a B a c k f o r F A T - v 3 . 6 3 _ P C o n l i n e C:\DOCUME~1\ADMINI~1\Desktop\360~1.LNK esktop\360.lnk A J C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ 3 6 0 Oi{. l n k C:\Documents and Settings\Administrator\Desktop\gdb B `HJ ) C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ g d b C:\Documents and Settings\Administrator\Desktop\gdb.zip C `HJ ) C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ g d b . z i p C:\Documents and Settings\Administrator\Desktop\recovered files D 7:J C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ r e c o v e r e d f i l e s C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline E wJ ) C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ G e t D a t a B a c k f o r F A T - v 3 . 6 3 _ P C o n l i n e C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exe F pwJ N C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ U n e r a s e r _ S e t u p ( 2 ) . e x e C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exe G pwJ N C : \ D o c u m e n t s a n d S e t t i n g s \ A d m i n i s t r a t o r \ D e s k t o p \ U n e r a s e r _ S e t u p . e x e rifiuti2-0.6.1/test/samples/INFO2-sample1-alt.txt 0000664 0000000 0000000 00000003141 12527270050 0021371 0 ustar 00root root 0000000 0000000 Recycle 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.txt 0000664 0000000 0000000 00000003216 12527270050 0020616 0 ustar 00root root 0000000 0000000 Recycle 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.xml 0000664 0000000 0000000 00000006774 12527270050 0020613 0 ustar 00root root 0000000 0000000
test_case/INFO2544N4096C:\Documents and Settings\All Users\Desktop\有道桌面词典.lnk45N4096C:\Documents and Settings\Administrator\Desktop\wongsir_url.txt46N2912256C:\Documents and Settings\Administrator\Desktop\dd-wrt.v24_mini_wrt54g.bin47N765952C:\Documents and Settings\Administrator\Desktop\theme\.svn48N5812224C:\Documents and Settings\Administrator\Desktop\Config Client49N1847296C:\Documents and Settings\Administrator\Desktop\Config Client.7z50N4096C:\Documents and Settings\All Users\Desktop\Wireshark.lnk57N2727936C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline.rar64Y2727936C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline65N4096C:\Documents and Settings\Administrator\Desktop\360保险箱.lnk66N2732032C:\Documents and Settings\Administrator\Desktop\gdb67N2723840C:\Documents and Settings\Administrator\Desktop\gdb.zip68N0C:\Documents and Settings\Administrator\Desktop\recovered files69N2727936C:\Documents and Settings\Administrator\Desktop\GetDataBackforFAT-v3.63_PConline70N5169152C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup(2).exe71N5169152C:\Documents and Settings\Administrator\Desktop\Uneraser_Setup.exe
rifiuti2-0.6.1/test/samples/INFO2-sample2 0000664 0000000 0000000 00000003674 12527270050 0020011 0 ustar 00root root 0000000 0000000 Y Y C:\WINDOWS\All Users\Desktop\Connect to the Internet.LNK ternet.LNK Y C C 0 C &