mirror of https://github.com/MidnightCommander/mc
Merge branch '3730_extfs_tester'
* 3730_extfs_tester: tests/src/vfs/extfs/helpers-list/Makefile.am: create run silently. Move extfs tester from tests/src/extfs-helpers-listcmd into tests/src/vfs/extfs/helpers-list. extfs: lslR: add tests. extfs: lslR: make it testable. extfs: urar: add tests. extfs: urar: make it testable. extfs: uzip: add tests. extfs: uzip: make it testable. extfs: uzoo: add tests. extfs: uzoo: make it testable. extfs: documentation for the tester. extfs: introduce a tester. Ticket #3730: extfs: introduce a command-line tool for parsing file lists.
This commit is contained in:
commit
3a25b7198f
|
@ -638,6 +638,9 @@ tests/src/Makefile
|
|||
tests/src/filemanager/Makefile
|
||||
tests/src/editor/Makefile
|
||||
tests/src/editor/test-data.txt
|
||||
tests/src/vfs/Makefile
|
||||
tests/src/vfs/extfs/Makefile
|
||||
tests/src/vfs/extfs/helpers-list/Makefile
|
||||
])
|
||||
fi
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ case "$1" in
|
|||
*) MYCAT="cat";;
|
||||
esac
|
||||
|
||||
MYCAT=${MC_TEST_EXTFS_LIST_CMD:-$MYCAT} # Let the test framework hook in.
|
||||
|
||||
$MYCAT "$1" | $AWK '
|
||||
BEGIN {
|
||||
dir="";
|
||||
|
|
|
@ -24,6 +24,10 @@ UNRAR=`which unrar 2>/dev/null`
|
|||
# Define $UNRAR version
|
||||
UNRAR_VERSION=`$UNRAR -cfg- -? | grep "Copyright" | sed -e 's/.*\([0-9]\)\..*/\1/'`
|
||||
|
||||
# Let the test framework hook in:
|
||||
UNRAR=${MC_TEST_EXTFS_LIST_CMD:-$UNRAR}
|
||||
UNRAR_VERSION=${MC_TEST_EXTFS_UNRAR_VERSION:-$UNRAR_VERSION}
|
||||
|
||||
mcrar4fs_list ()
|
||||
{
|
||||
$UNRAR v -c- -cfg- "$1" | @AWK@ -v uid=`id -u` -v gid=`id -g` '
|
||||
|
|
|
@ -17,9 +17,9 @@ use strict;
|
|||
# Location of the zip program
|
||||
my $app_zip = "@ZIP@";
|
||||
# Location of the unzip program
|
||||
my $app_unzip = "@UNZIP@";
|
||||
my $app_unzip = $ENV{MC_TEST_EXTFS_LIST_CMD} || "@UNZIP@";
|
||||
# Set this to 1 if zipinfo (unzip -Z) is to be used (recommended), otherwise 0.
|
||||
my $op_has_zipinfo = @HAVE_ZIPINFO@;
|
||||
my $op_has_zipinfo = exists($ENV{MC_TEST_EXTFS_HAVE_ZIPINFO}) ? $ENV{MC_TEST_EXTFS_HAVE_ZIPINFO} : @HAVE_ZIPINFO@;
|
||||
|
||||
# Command used to list archives (zipinfo mode)
|
||||
my $cmd_list_zi = "$app_unzip -Z -l -T";
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Source of zoo can be found at
|
||||
# ftp://ftp.ibiblio.org/pub/Linux/utils/compress/
|
||||
|
||||
ZOO=zoo
|
||||
ZOO=${MC_TEST_EXTFS_LIST_CMD:-zoo}
|
||||
|
||||
# Stupid zoo won't work if the archive name has no .zoo extension, so we
|
||||
# have to make a symlink with a "better" name. Also, zoo can create
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
PACKAGE_STRING = "/src"
|
||||
|
||||
SUBDIRS = . filemanager
|
||||
SUBDIRS = . filemanager vfs
|
||||
|
||||
if USE_INTERNAL_EDIT
|
||||
SUBDIRS += editor
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
SUBDIRS = extfs
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
SUBDIRS = helpers-list
|
|
@ -0,0 +1,91 @@
|
|||
PACKAGE_STRING = "/src/vfs/extfs/helpers-list"
|
||||
|
||||
AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
|
||||
|
||||
# This lets mc_parse_ls_l.c override MC's message() without the linker
|
||||
# complaining about multiple definitions.
|
||||
AM_LDFLAGS = @TESTS_LDFLAGS@
|
||||
|
||||
LIBS = $(top_builddir)/lib/libmc.la
|
||||
|
||||
# Programs/scripts to build on 'make check'.
|
||||
check_PROGRAMS = mc_parse_ls_l
|
||||
check_SCRIPTS = run
|
||||
|
||||
# Tests to run on 'make check'
|
||||
TESTS = run
|
||||
|
||||
# On 'make clean', delete 'run' as well.
|
||||
CLEANFILES = run
|
||||
|
||||
mc_parse_ls_l_SOURCES = \
|
||||
mc_parse_ls_l.c
|
||||
|
||||
data_files_to_distribute = \
|
||||
data/lslR.1.spaces.args \
|
||||
data/lslR.1.spaces.input \
|
||||
data/lslR.1.spaces.output \
|
||||
data/lslR.2.spaces-iso.args \
|
||||
data/lslR.2.spaces-iso.input \
|
||||
data/lslR.2.spaces-iso.output \
|
||||
data/lslR.3.spaces-iso-noslash.args \
|
||||
data/lslR.3.spaces-iso-noslash.input \
|
||||
data/lslR.3.spaces-iso-noslash.output \
|
||||
data/lslR.README \
|
||||
data/urar.README \
|
||||
data/urar.v4,v3.env_vars \
|
||||
data/urar.v4,v3.input \
|
||||
data/urar.v4,v3.output \
|
||||
data/urar.v5.env_vars \
|
||||
data/urar.v5.input \
|
||||
data/urar.v5.output \
|
||||
data/uzip.README \
|
||||
data/uzip.with-zipinfo.env_vars \
|
||||
data/uzip.with-zipinfo.input \
|
||||
data/uzip.with-zipinfo.output \
|
||||
data/uzip.without-zipinfo--mdy.env_vars \
|
||||
data/uzip.without-zipinfo--mdy.input \
|
||||
data/uzip.without-zipinfo--mdy.output \
|
||||
data/uzip.without-zipinfo--ymd.env_vars \
|
||||
data/uzip.without-zipinfo--ymd.input \
|
||||
data/uzip.without-zipinfo--ymd.output \
|
||||
data/uzoo.README \
|
||||
data/uzoo.input \
|
||||
data/uzoo.output \
|
||||
data/dummy
|
||||
|
||||
EXTRA_DIST = mc_xcat test_all $(data_files_to_distribute)
|
||||
|
||||
run:
|
||||
@echo '#!/bin/sh' > $@
|
||||
@echo >> $@
|
||||
@echo '# This script is an easy way to launch the "test_all" script' >> $@
|
||||
@echo '# with all the required arguments.' >> $@
|
||||
@echo '#' >> $@
|
||||
@echo '# Run this script with "--help" to learn more.' >> $@
|
||||
@echo >> $@
|
||||
@echo '# Where to find mc_parse_ls_l and mc_xcat, respectively.' >> $@
|
||||
@echo 'PATH="$(abs_builddir):$(abs_srcdir):$$PATH"' >> $@
|
||||
@echo >> $@
|
||||
# The 'abs_' isn't mandatory. It lets you move this script out of the build tree.
|
||||
@echo '"$(abs_srcdir)"/test_all "$$@" \' >> $@
|
||||
@echo ' --data-dir "$(abs_srcdir)/data" \' >> $@
|
||||
# Before installation, some helpers are in the build tree, some in the src tree.
|
||||
@echo ' --helpers-dir "$(abs_top_builddir)/src/vfs/extfs/helpers" \' >> $@
|
||||
@echo ' --helpers-dir "$(abs_top_srcdir)/src/vfs/extfs/helpers"' >> $@
|
||||
@chmod +x $@
|
||||
# (We can alternatively create run from a run.in template
|
||||
# with 'AC_CONFIG_FILES[run, chmod +x run]'.)
|
||||
|
||||
#
|
||||
# Documentation
|
||||
#
|
||||
|
||||
doc: README.html
|
||||
|
||||
# (Thanks to VPATH we don't need to write "$(srcdir)/README". doc/hlp/Makefile.am needlessly does this.)
|
||||
README.html: README
|
||||
pandoc --include-in-header=$(srcdir)/README.css.inc -N --old-dashes --toc --standalone -o $@ $<
|
||||
|
||||
EXTRA_DIST += README.css.inc
|
||||
CLEANFILES += README.html
|
|
@ -0,0 +1,171 @@
|
|||
---
|
||||
title: A tester for extfs helpers
|
||||
...
|
||||
|
||||
Guide
|
||||
=====
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The extfs filesystem is composed of various helpers (uzip, urar, uarc,
|
||||
...). One command every helper must answer to is "list", to list the
|
||||
files on its filesystem.
|
||||
|
||||
The purpose of this tester is to test this "list" facet of every helper
|
||||
to ensure that it indeed works, at present, and that we won't
|
||||
inadvertently break it, in the future, as we modify its code or MC's
|
||||
code.
|
||||
|
||||
Key concept: Inputs
|
||||
-------------------
|
||||
|
||||
Most helpers work by parsing the output of some 3'rd party software.
|
||||
Which for them becomes the *input*. Helpers sometimes support **several
|
||||
variations** of such input. E.g., the uzip helper supports three
|
||||
variations.
|
||||
|
||||
The tester keeps a repository, in the data folder, of the various inputs
|
||||
each helper proclaims to support. Each input is stored in a file with an
|
||||
`.input` suffix.
|
||||
|
||||
Key concept: Outputs
|
||||
--------------------
|
||||
|
||||
Along with each input file, the data folder also holds the output the
|
||||
helper is expected to produce given the corresponding input. Each output
|
||||
is stored in a file with an `.output` suffix.
|
||||
|
||||
We call this output "the expected output".
|
||||
|
||||
Incidentally, an `.output` file stores not the _raw_ output of the helper
|
||||
but its output _after parsing_. In other words, what's stored is the
|
||||
unambiguous _meaning_ of the helper's output. This means that as long as
|
||||
the helper's code isn't modified in a way that changes the meaning of its
|
||||
output, the `.output` file remains up-to-date.
|
||||
|
||||
How the tester works
|
||||
--------------------
|
||||
|
||||
The tester feeds each helper its prepared inputs and reads back the
|
||||
helper's "list" answer -- the helper's **output**. This output is a list
|
||||
of files in a format similar to `ls -l`, which MC is able to parse. The
|
||||
tester checks that this output parses without errors (errors are, for
|
||||
example, dates in unsupported format). It then compares this parsed
|
||||
output (which we call "the actual output") with a previously saved copy
|
||||
of this output which is known to be correct (and which we call "the
|
||||
expected output", mentioned in the previous section). This previously
|
||||
stored output too is in the data folder, in files with `.output` suffix.
|
||||
|
||||
If there's any discrepancy between the *actual output* and the
|
||||
*expected output*, the test fails.
|
||||
|
||||
Running the tester
|
||||
------------------
|
||||
|
||||
You can run the tester with `make check`.
|
||||
|
||||
But you'll find it more appealing to run the tester with the `run`
|
||||
script. You'll get a colorful description of what's going on.
|
||||
|
||||
(`run` is created by running `make check` for the 1st time, in the build
|
||||
tree.)
|
||||
|
||||
Reference
|
||||
=========
|
||||
|
||||
The data folder
|
||||
---------------
|
||||
|
||||
There are several types of files in the data folder:
|
||||
|
||||
### Input file ###
|
||||
|
||||
An input file is named:
|
||||
|
||||
> `<helper-name>[.optional-embedded-description].input`
|
||||
|
||||
You create such files simply by redirecting the 3'rd party software's
|
||||
output to a file.
|
||||
|
||||
### Output file ###
|
||||
|
||||
This file is named the same as the corresponding input file but with an
|
||||
`.output` suffix.
|
||||
|
||||
The easiest way to create these files is by invoking the `run` script
|
||||
with the `--create-output` option.
|
||||
|
||||
### Environment file ###
|
||||
|
||||
Optional. This file defines environment variables the helper may use to
|
||||
determine the variant of the input. This file is named the same as the
|
||||
corresponding input file but with an `.env_var` suffix.
|
||||
|
||||
### Arguments file ###
|
||||
|
||||
Optional. This file defines extra command-line options to pass to the
|
||||
[parser](#mc_parse_ls_l). This file is named the same as the
|
||||
corresponding input file but with an `.args` suffix.
|
||||
|
||||
The contents of an output file must be the same no matter on what
|
||||
computer and at what time we generate it. Therefore we need to tell the
|
||||
parser to drop any non-fixed elements in that file. E.g., if the dates
|
||||
used are relative (as is the case for the default `ls` dates), we need to
|
||||
drop them with `--drop-mtime`. Similarly, if a helper returns user and
|
||||
group _names_ that are different than the running user's, they must be
|
||||
dropped with `--drop-ids`.
|
||||
|
||||
### Other files ###
|
||||
|
||||
Any other file is ignored by the tester.
|
||||
|
||||
mc_parse_ls_l
|
||||
-------------
|
||||
|
||||
This program (built with `make check`) is at the heart of the tester
|
||||
mechanism. It parses a list of files, in a format similar to `ls -l`,
|
||||
just as MC would. This program is used to parse (and thereby verify) the
|
||||
output of the helpers. _You don't need to invoke it yourself;_ but, for
|
||||
educational purpose, here are a few examples:
|
||||
|
||||
$ LC_ALL=C ls -l | ./mc_parse_ls_l
|
||||
|
||||
$ LC_ALL=C ls -l | ./mc_parse_ls_l --symbolic-ids
|
||||
|
||||
$ LC_ALL=C ls -l | ./mc_parse_ls_l --output-format yaml
|
||||
|
||||
test_all
|
||||
--------
|
||||
|
||||
This is the tester itself. You invoke it with `make check`, or with the
|
||||
`run` script. Invoking it directly is a bit involving because you need to
|
||||
provide it with 2 or 3 directory paths. `run` does this work for you.
|
||||
|
||||
MC_TEST_EXTFS_LIST_CMD
|
||||
----------------------
|
||||
|
||||
When a helper runs under the tester, the environment variable
|
||||
`MC_TEST_EXTFS_LIST_CMD` holds the command that's to provide input. The
|
||||
helper's source code must be modified to use this command instead of the
|
||||
command it usually uses. This is the device which lets us plug our own
|
||||
input into the helper and *without which a helper can't be tested!*
|
||||
|
||||
Let's have a little example. The uzoo helper originally has:
|
||||
|
||||
ZOO=zoo
|
||||
...
|
||||
mczoofs_list () {
|
||||
$ZOO lq "$ARCHIVE" | mawk '......'
|
||||
}
|
||||
...
|
||||
|
||||
To make this helper testable, we need to change the first line to:
|
||||
|
||||
ZOO=${MC_TEST_EXTFS_LIST_CMD:-zoo}
|
||||
|
||||
(or equivalent.)
|
||||
|
||||
The command in `MC_TEST_EXTFS_LIST_CMD` is a black-box for the helper,
|
||||
and it intentionally ignores any arguments passed to it (so that `lq
|
||||
"$ARCHIVE"`, above, won't cause problems).
|
|
@ -0,0 +1,19 @@
|
|||
<style type="text/css">
|
||||
|
||||
body {
|
||||
padding: 1em 2.5em;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
code, pre {
|
||||
background-color: #FFB;
|
||||
padding: 2px 3px;
|
||||
}
|
||||
|
||||
h1, h2 { text-indent: -0.5em; }
|
||||
h1, h2, h3 {
|
||||
color: #005A9C;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
This is a dummy file meant to ensure this directory isn't empty so that git always creates it.
|
||||
|
||||
Otherwise our 'test_all' script will fail complaining the directory doesn't exist.
|
|
@ -0,0 +1 @@
|
|||
--drop-ids --drop-mtime
|
|
@ -0,0 +1,23 @@
|
|||
.:
|
||||
total 12
|
||||
drwxr-xr-x 3 serhiy serhiy 4096 Dec 29 19:12 1 2
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 Dec 29 19:08 1 2
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 Dec 29 19:12 1 2
|
||||
|
||||
./ 1 2:
|
||||
total 4
|
||||
-rw-r--r-- 1 serhiy serhiy 0 Dec 29 19:08 b
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 Dec 29 19:12 z
|
||||
|
||||
./ 1 2/z:
|
||||
total 0
|
||||
|
||||
./1 2:
|
||||
total 0
|
||||
-rw-r--r-- 1 serhiy serhiy 0 Dec 29 19:08 a
|
||||
|
||||
./1 2 :
|
||||
total 0
|
||||
-rw-r--r-- 1 serhiy serhiy 0 Dec 29 19:09 d
|
||||
-rw-r--r-- 1 serhiy serhiy 0 Dec 29 19:08 c
|
||||
-rw-r--r-- 1 serhiy serhiy 0 Dec 29 19:09 x:
|
|
@ -0,0 +1,9 @@
|
|||
drwxr-xr-x 3 4096 ./ 1 2
|
||||
drwxr-xr-x 2 4096 ./1 2
|
||||
drwxr-xr-x 2 4096 ./1 2
|
||||
-rw-r--r-- 1 0 ./ 1 2/b
|
||||
drwxr-xr-x 2 4096 ./ 1 2/z
|
||||
-rw-r--r-- 1 0 ./1 2/a
|
||||
-rw-r--r-- 1 0 ./1 2 / d
|
||||
-rw-r--r-- 1 0 ./1 2 /c
|
||||
-rw-r--r-- 1 0 ./1 2 /x:
|
|
@ -0,0 +1 @@
|
|||
--drop-ids
|
|
@ -0,0 +1,23 @@
|
|||
.:
|
||||
total 12
|
||||
drwxr-xr-x 3 serhiy serhiy 4096 2009-12-29 19:12 1 2
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 2009-12-29 19:08 1 2
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 2009-12-29 19:12 1 2
|
||||
|
||||
./ 1 2:
|
||||
total 4
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:08 b
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 2009-12-29 19:12 z
|
||||
|
||||
./ 1 2/z:
|
||||
total 0
|
||||
|
||||
./1 2:
|
||||
total 0
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:08 a
|
||||
|
||||
./1 2 :
|
||||
total 0
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:08 c
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:09 d
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:09 x:
|
|
@ -0,0 +1,9 @@
|
|||
drwxr-xr-x 3 4096 2009-12-29 19:12:00 ./ 1 2
|
||||
drwxr-xr-x 2 4096 2009-12-29 19:08:00 ./1 2
|
||||
drwxr-xr-x 2 4096 2009-12-29 19:12:00 ./1 2
|
||||
-rw-r--r-- 1 0 2009-12-29 19:08:00 ./ 1 2/b
|
||||
drwxr-xr-x 2 4096 2009-12-29 19:12:00 ./ 1 2/z
|
||||
-rw-r--r-- 1 0 2009-12-29 19:08:00 ./1 2/a
|
||||
-rw-r--r-- 1 0 2009-12-29 19:08:00 ./1 2 /c
|
||||
-rw-r--r-- 1 0 2009-12-29 19:09:00 ./1 2 / d
|
||||
-rw-r--r-- 1 0 2009-12-29 19:09:00 ./1 2 /x:
|
|
@ -0,0 +1 @@
|
|||
--drop-ids
|
|
@ -0,0 +1,17 @@
|
|||
1 2:
|
||||
total 4
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:08 b
|
||||
drwxr-xr-x 2 serhiy serhiy 4096 2009-12-29 19:12 z
|
||||
|
||||
1 2/z:
|
||||
total 0
|
||||
|
||||
1 2:
|
||||
total 0
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:08 a
|
||||
|
||||
1 2 :
|
||||
total 0
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:08 c
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:09 d
|
||||
-rw-r--r-- 1 serhiy serhiy 0 2009-12-29 19:09 x:
|
|
@ -0,0 +1,6 @@
|
|||
-rw-r--r-- 1 0 2009-12-29 19:08:00 ./ 1 2/b
|
||||
drwxr-xr-x 2 4096 2009-12-29 19:12:00 ./ 1 2/z
|
||||
-rw-r--r-- 1 0 2009-12-29 19:08:00 1 2/a
|
||||
-rw-r--r-- 1 0 2009-12-29 19:08:00 1 2 /c
|
||||
-rw-r--r-- 1 0 2009-12-29 19:09:00 1 2 / d
|
||||
-rw-r--r-- 1 0 2009-12-29 19:09:00 1 2 /x:
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
The inputs were taken from:
|
||||
|
||||
http://www.midnight-commander.org/ticket/1921
|
||||
|
||||
These inputs are supposed to cover:
|
||||
|
||||
- "spaces": spaces in dir/file names.
|
||||
|
||||
- "iso": ISO date. The ticket claims this is enabled in en_US.UTF-8
|
||||
locale, but that's untrue. Nevertheless, it's a useful format (the
|
||||
default 'ls' dates are relative and therefore somewhat useless in lslR
|
||||
files) so we don't mind covering it here.
|
||||
|
||||
- "noshalsh": directories not starting with "./".
|
||||
|
||||
Argument files:
|
||||
|
||||
The output produced must be constant anytime. Therefore:
|
||||
|
||||
- For the one input using non-ISO date we must use --drop-mtime.
|
||||
Otherwise, because these are relative dates, next year the output
|
||||
will show a different year.
|
||||
|
||||
- For all inputs we use --drop-ids for the case we have user "serhiy" on
|
||||
our system (and we aren't running as that user).
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
The archive was created thus:
|
||||
|
||||
echo hello > 'filename with spaces.txt'
|
||||
rar a archive.rar 'filename with spaces.txt' ...
|
||||
|
||||
Our 'urar' supports two listing formats: that of version 5, and that of
|
||||
version 4.
|
||||
|
||||
'urar.v5.input' was created with "unrar vt -c- -cfg- archive.rar" using
|
||||
unrar 5.30.
|
||||
|
||||
'urar.v4,v3.input' was created with "unrar v -c- -cfg- archive.rar" using
|
||||
unrar 3.80 for DOS (google "unrar dos"), via DOSBox (and then the "\" was
|
||||
changed to "/" by hand). An inspection of our urar's source code should
|
||||
lead us to conclude that this format is compatible with that of version
|
||||
4.
|
|
@ -0,0 +1 @@
|
|||
MC_TEST_EXTFS_UNRAR_VERSION=4
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
UNRAR 3.80 freeware Copyright (c) 1993-2008 Alexander Roshal
|
||||
|
||||
Archive ARCHIVE.RAR
|
||||
|
||||
Pathname/Comment
|
||||
Size Packed Ratio Date Time Attr CRC Meth Ver
|
||||
-------------------------------------------------------------------------------
|
||||
.viminfo
|
||||
11032 2468 22% 23-11-16 07:10 -rw------- 295ED9AB m3g 2.9
|
||||
.wget-hsts
|
||||
205 181 88% 26-10-16 13:14 -rw-rw-r-- 58429CA4 m3g 2.9
|
||||
.xboardrc
|
||||
7527 2964 39% 17-04-16 01:21 -rw-rw-r-- 1DA6AD04 m3g 2.9
|
||||
.xchm
|
||||
559 382 68% 29-09-16 01:08 -rw-rw-r-- 73DBF2B9 m3g 2.9
|
||||
.xinputrc
|
||||
130 123 94% 27-12-15 17:08 -rw-rw-r-- 70CD8EF3 m3g 2.9
|
||||
.dosbox/dosbox-0.74.conf
|
||||
10730 4005 37% 07-06-16 20:43 -rw-rw-r-- 1D5A9AA6 m3g 2.9
|
||||
log.txt
|
||||
5869937 42114 0% 23-11-16 07:43 -rw-rw-r-- E63DE4A6 m3g 2.9
|
||||
filename with spaces.txt
|
||||
6 16 266% 23-11-16 07:39 -rw-r--r-- 363A3020 m3g 2.9
|
||||
.dosbox
|
||||
0 0 0% 07-06-16 20:43 drwx------ 00000000 m0 2.0
|
||||
-------------------------------------------------------------------------------
|
||||
9 5900126 52253 0%
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
drwx------ 1 <<uid>> <<gid>> 0 2016-06-07 20:43:00 ./.dosbox
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 10730 2016-06-07 20:43:00 ./.dosbox/dosbox-0.74.conf
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 6 2016-11-23 07:39:00 ./filename with spaces.txt
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 5869937 2016-11-23 07:43:00 ./log.txt
|
||||
-rw------- 1 <<uid>> <<gid>> 11032 2016-11-23 07:10:00 ./.viminfo
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 205 2016-10-26 13:14:00 ./.wget-hsts
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 7527 2016-04-17 01:21:00 ./.xboardrc
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 559 2016-09-29 01:08:00 ./.xchm
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 130 2015-12-27 17:08:00 ./.xinputrc
|
|
@ -0,0 +1 @@
|
|||
MC_TEST_EXTFS_UNRAR_VERSION=5
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
UNRAR 5.30 beta 2 freeware Copyright (c) 1993-2015 Alexander Roshal
|
||||
|
||||
Archive: archive.rar
|
||||
Details: RAR 4
|
||||
|
||||
Name: .viminfo
|
||||
Type: File
|
||||
Size: 11032
|
||||
Packed size: 2468
|
||||
Ratio: 22%
|
||||
mtime: 2016-11-23 07:10:39,000
|
||||
Attributes: -rw-------
|
||||
CRC32: 295ED9AB
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: .wget-hsts
|
||||
Type: File
|
||||
Size: 205
|
||||
Packed size: 181
|
||||
Ratio: 88%
|
||||
mtime: 2016-10-26 13:14:09,000
|
||||
Attributes: -rw-rw-r--
|
||||
CRC32: 58429CA4
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: .xboardrc
|
||||
Type: File
|
||||
Size: 7527
|
||||
Packed size: 2964
|
||||
Ratio: 39%
|
||||
mtime: 2016-04-17 01:21:46,000
|
||||
Attributes: -rw-rw-r--
|
||||
CRC32: 1DA6AD04
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: .xchm
|
||||
Type: File
|
||||
Size: 559
|
||||
Packed size: 382
|
||||
Ratio: 68%
|
||||
mtime: 2016-09-29 01:08:46,000
|
||||
Attributes: -rw-rw-r--
|
||||
CRC32: 73DBF2B9
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: .xinputrc
|
||||
Type: File
|
||||
Size: 130
|
||||
Packed size: 123
|
||||
Ratio: 94%
|
||||
mtime: 2015-12-27 17:08:35,000
|
||||
Attributes: -rw-rw-r--
|
||||
CRC32: 70CD8EF3
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: .dosbox/dosbox-0.74.conf
|
||||
Type: File
|
||||
Size: 10730
|
||||
Packed size: 4005
|
||||
Ratio: 37%
|
||||
mtime: 2016-06-07 20:43:58,000
|
||||
Attributes: -rw-rw-r--
|
||||
CRC32: 1D5A9AA6
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: log.txt
|
||||
Type: File
|
||||
Size: 5869937
|
||||
Packed size: 42114
|
||||
Ratio: 0%
|
||||
mtime: 2016-11-23 07:43:18,000
|
||||
Attributes: -rw-rw-r--
|
||||
CRC32: E63DE4A6
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: filename with spaces.txt
|
||||
Type: File
|
||||
Size: 6
|
||||
Packed size: 16
|
||||
Ratio: 266%
|
||||
mtime: 2016-11-23 07:39:15,000
|
||||
Attributes: -rw-r--r--
|
||||
CRC32: 363A3020
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v29) -m3 -md=4M
|
||||
|
||||
Name: .dosbox
|
||||
Type: Directory
|
||||
mtime: 2016-06-07 20:43:58,000
|
||||
Attributes: drwx------
|
||||
CRC32: 00000000
|
||||
Host OS: Unix
|
||||
Compression: RAR 3.0(v20) -m0 -md=0K
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
drwx------ 1 <<uid>> <<gid>> 0 2016-06-07 20:43:00 ./.dosbox
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 10730 2016-06-07 20:43:00 ./.dosbox/dosbox-0.74.conf
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 6 2016-11-23 07:39:00 ./filename with spaces.txt
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 5869937 2016-11-23 07:43:00 ./log.txt
|
||||
-rw------- 1 <<uid>> <<gid>> 11032 2016-11-23 07:10:00 ./.viminfo
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 205 2016-10-26 13:14:00 ./.wget-hsts
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 7527 2016-04-17 01:21:00 ./.xboardrc
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 559 2016-09-29 01:08:00 ./.xchm
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 130 2015-12-27 17:08:00 ./.xinputrc
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
The input files were created thus:
|
||||
|
||||
cd ~/.gimp-2.8
|
||||
echo hello > 'filename with spaces.txt'
|
||||
zip a.zip *
|
||||
unzip -Z -l -T a.zip > uzip.with-zipinfo.input
|
||||
unzip -qq -v a.zip > uzip.without-zipinfo--ymd.input
|
||||
rm a.zip
|
||||
|
||||
uzip supports two date formats for "without-zipinfo" mode: ymd
|
||||
(YYYY-MM-DD) and mdy (MM-DD-YY). To create the
|
||||
'uzip.without-zipinfo--mdy.input' file, with MM-DD-YY dates, I simply
|
||||
altered two dates with an editor (one with year before 70, one after).
|
|
@ -0,0 +1 @@
|
|||
MC_TEST_EXTFS_HAVE_ZIPINFO=1
|
|
@ -0,0 +1,43 @@
|
|||
Archive: a.zip
|
||||
Zip file size: 75222 bytes, number of entries: 40
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 brushes/
|
||||
-rw------- 3.0 unx 739 tx 164 defN 20160918.164557 colorrc
|
||||
-rw------- 3.0 unx 1863 tx 441 defN 20160918.164558 controllerrc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 curves/
|
||||
-rw------- 3.0 unx 1982 tx 423 defN 20160918.164557 dockrc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 dynamics/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 environ/
|
||||
-rw-r--r-- 3.0 unx 6 tx 6 stor 20161123.071336 filename with spaces.txt
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 fonts/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 fractalexplorer/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 gfig/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 gflare/
|
||||
-rw------- 3.0 unx 355 tx 223 defN 20160108.011031 gimprc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 gimpressionist/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 gradients/
|
||||
-rw-r--r-- 3.0 unx 430 tx 251 defN 20151225.001514 gtkrc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 interpreters/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 levels/
|
||||
-rw-r--r-- 3.0 unx 76873 tx 8770 defN 20160918.164558 menurc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 modules/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 palettes/
|
||||
-rw------- 3.0 unx 102 tx 86 defN 20160918.164559 parasiterc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 patterns/
|
||||
-rw-r--r-- 3.0 unx 277486 tx 48556 defN 20151225.001526 pluginrc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 plug-ins/
|
||||
-rw-rw-r-- 3.0 unx 209 tx 143 defN 20160918.164437 print-page-setup
|
||||
-rw-rw-r-- 3.0 unx 506 tx 295 defN 20160918.164437 print-settings
|
||||
-rw------- 3.0 unx 62 tx 43 defN 20160108.010813 profilerc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 scripts/
|
||||
-rw------- 3.0 unx 2370 tx 685 defN 20160918.164557 sessionrc
|
||||
-rw-rw-r-- 3.0 unx 34747 tx 7545 defN 20160918.164559 tags.xml
|
||||
-rw------- 3.0 unx 4817 tx 589 defN 20160918.164559 templaterc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 templates/
|
||||
-rw-rw-r-- 3.0 unx 310 tx 204 defN 20160918.164204 themerc
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 themes/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 tmp/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20160403.000739 tool-options/
|
||||
drwxr-xr-x 3.0 unx 0 bx 0 stor 20151225.001514 tool-presets/
|
||||
-rw------- 3.0 unx 3996 tx 528 defN 20160918.164558 toolrc
|
||||
-rw------- 3.0 unx 1178 tx 388 defN 20160918.164559 unitrc
|
||||
40 files, 408031 bytes uncompressed, 69340 bytes compressed: 83.0%
|
|
@ -0,0 +1,40 @@
|
|||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 brushes/
|
||||
-rw------- 1 <<uid>> <<gid>> 739 2016-09-18 16:45:57 colorrc
|
||||
-rw------- 1 <<uid>> <<gid>> 1863 2016-09-18 16:45:58 controllerrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 curves/
|
||||
-rw------- 1 <<uid>> <<gid>> 1982 2016-09-18 16:45:57 dockrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 dynamics/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 environ/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 6 2016-11-23 07:13:36 filename with spaces.txt
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 fonts/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 fractalexplorer/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 gfig/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 gflare/
|
||||
-rw------- 1 <<uid>> <<gid>> 355 2016-01-08 01:10:31 gimprc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 gimpressionist/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 gradients/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 430 2015-12-25 00:15:14 gtkrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 interpreters/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 levels/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 76873 2016-09-18 16:45:58 menurc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 modules/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 palettes/
|
||||
-rw------- 1 <<uid>> <<gid>> 102 2016-09-18 16:45:59 parasiterc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 patterns/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 277486 2015-12-25 00:15:26 pluginrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 plug-ins/
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 209 2016-09-18 16:44:37 print-page-setup
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 506 2016-09-18 16:44:37 print-settings
|
||||
-rw------- 1 <<uid>> <<gid>> 62 2016-01-08 01:08:13 profilerc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 scripts/
|
||||
-rw------- 1 <<uid>> <<gid>> 2370 2016-09-18 16:45:57 sessionrc
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 34747 2016-09-18 16:45:59 tags.xml
|
||||
-rw------- 1 <<uid>> <<gid>> 4817 2016-09-18 16:45:59 templaterc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 templates/
|
||||
-rw-rw-r-- 1 <<uid>> <<gid>> 310 2016-09-18 16:42:04 themerc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 themes/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 tmp/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2016-04-03 00:07:39 tool-options/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:14 tool-presets/
|
||||
-rw------- 1 <<uid>> <<gid>> 3996 2016-09-18 16:45:58 toolrc
|
||||
-rw------- 1 <<uid>> <<gid>> 1178 2016-09-18 16:45:59 unitrc
|
|
@ -0,0 +1 @@
|
|||
MC_TEST_EXTFS_HAVE_ZIPINFO=0
|
|
@ -0,0 +1,2 @@
|
|||
0 Stored 0 0% 12-25-15 00:15 00000000 brushes/
|
||||
739 Defl:N 164 78% 09-16-78 16:45 2d7277eb colorrc
|
|
@ -0,0 +1,2 @@
|
|||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 brushes/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 739 1978-09-16 16:45:00 colorrc
|
|
@ -0,0 +1 @@
|
|||
MC_TEST_EXTFS_HAVE_ZIPINFO=0
|
|
@ -0,0 +1,40 @@
|
|||
0 Stored 0 0% 2015-12-25 00:15 00000000 brushes/
|
||||
739 Defl:N 164 78% 2016-09-18 16:45 2d7277eb colorrc
|
||||
1863 Defl:N 441 76% 2016-09-18 16:45 4a229bae controllerrc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 curves/
|
||||
1982 Defl:N 423 79% 2016-09-18 16:45 0f21e877 dockrc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 dynamics/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 environ/
|
||||
6 Stored 6 0% 2016-11-23 07:13 363a3020 filename with spaces.txt
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 fonts/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 fractalexplorer/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 gfig/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 gflare/
|
||||
355 Defl:N 223 37% 2016-01-08 01:10 05197193 gimprc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 gimpressionist/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 gradients/
|
||||
430 Defl:N 251 42% 2015-12-25 00:15 a3ed42bc gtkrc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 interpreters/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 levels/
|
||||
76873 Defl:N 8770 89% 2016-09-18 16:45 7d9cb346 menurc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 modules/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 palettes/
|
||||
102 Defl:N 86 16% 2016-09-18 16:45 62252c7b parasiterc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 patterns/
|
||||
277486 Defl:N 48556 83% 2015-12-25 00:15 f846b075 pluginrc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 plug-ins/
|
||||
209 Defl:N 143 32% 2016-09-18 16:44 1c6688d4 print-page-setup
|
||||
506 Defl:N 295 42% 2016-09-18 16:44 ce580111 print-settings
|
||||
62 Defl:N 43 31% 2016-01-08 01:08 d149fa62 profilerc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 scripts/
|
||||
2370 Defl:N 685 71% 2016-09-18 16:45 b31b0c93 sessionrc
|
||||
34747 Defl:N 7545 78% 2016-09-18 16:45 6f219ddd tags.xml
|
||||
4817 Defl:N 589 88% 2016-09-18 16:45 edb121a1 templaterc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 templates/
|
||||
310 Defl:N 204 34% 2016-09-18 16:42 0b2c424e themerc
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 themes/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 tmp/
|
||||
0 Stored 0 0% 2016-04-03 00:07 00000000 tool-options/
|
||||
0 Stored 0 0% 2015-12-25 00:15 00000000 tool-presets/
|
||||
3996 Defl:N 528 87% 2016-09-18 16:45 f51984ae toolrc
|
||||
1178 Defl:N 388 67% 2016-09-18 16:45 b8420722 unitrc
|
|
@ -0,0 +1,40 @@
|
|||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 brushes/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 739 2016-09-18 16:45:00 colorrc
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 1863 2016-09-18 16:45:00 controllerrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 curves/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 1982 2016-09-18 16:45:00 dockrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 dynamics/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 environ/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 6 2016-11-23 07:13:00 filename with spaces.txt
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 fonts/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 fractalexplorer/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 gfig/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 gflare/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 355 2016-01-08 01:10:00 gimprc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 gimpressionist/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 gradients/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 430 2015-12-25 00:15:00 gtkrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 interpreters/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 levels/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 76873 2016-09-18 16:45:00 menurc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 modules/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 palettes/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 102 2016-09-18 16:45:00 parasiterc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 patterns/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 277486 2015-12-25 00:15:00 pluginrc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 plug-ins/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 209 2016-09-18 16:44:00 print-page-setup
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 506 2016-09-18 16:44:00 print-settings
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 62 2016-01-08 01:08:00 profilerc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 scripts/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 2370 2016-09-18 16:45:00 sessionrc
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 34747 2016-09-18 16:45:00 tags.xml
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 4817 2016-09-18 16:45:00 templaterc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 templates/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 310 2016-09-18 16:42:00 themerc
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 themes/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 tmp/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2016-04-03 00:07:00 tool-options/
|
||||
drwxr-xr-x 1 <<uid>> <<gid>> 0 2015-12-25 00:15:00 tool-presets/
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 3996 2016-09-18 16:45:00 toolrc
|
||||
-rw-r--r-- 1 <<uid>> <<gid>> 1178 2016-09-18 16:45:00 unitrc
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
The input file was created by running "zoo lq" on the archive at:
|
||||
|
||||
http://www.midnight-commander.org/ticket/3696
|
||||
|
||||
Known bugs in our uzoo:
|
||||
- It doesn't support filenames with spaces.
|
||||
- It reports '0' gid.
|
|
@ -0,0 +1,18 @@
|
|||
4 0% 4 26 Sep 16 12:56:02+61 тест/тест3/тест2.txt
|
||||
4 0% 4 26 Sep 16 12:56:00+61 тест/тест3/тест1.txt
|
||||
4 0% 4 26 Sep 16 12:56:08+61 тест/тест3/тест3.txt
|
||||
4 0% 4 26 Sep 16 12:56:02+61 тест/тест1/тест2.txt
|
||||
4 0% 4 26 Sep 16 12:56:00+61 тест/тест1/тест1.txt
|
||||
4 0% 4 26 Sep 16 12:56:08+61 тест/тест1/тест3.txt
|
||||
4 0% 4 26 Sep 16 12:56:02+61 тест/тест2/тест2.txt
|
||||
4 0% 4 26 Sep 16 12:56:00+61 тест/тест2/тест1.txt
|
||||
4 0% 4 26 Sep 16 12:56:08+61 тест/тест2/тест3.txt
|
||||
4 0% 4 26 Sep 16 12:56:02+61 тест/test1/тест2.txt
|
||||
4 0% 4 26 Sep 16 12:56:00+61 тест/test1/тест1.txt
|
||||
4 0% 4 26 Sep 16 12:56:08+61 тест/test1/тест3.txt
|
||||
4 0% 4 26 Sep 16 12:56:02+61 тест/test3/тест2.txt
|
||||
4 0% 4 26 Sep 16 12:56:00+61 тест/test3/тест1.txt
|
||||
4 0% 4 26 Sep 16 12:56:08+61 тест/test3/тест3.txt
|
||||
4 0% 4 26 Sep 16 12:56:02+61 тест/test2/тест2.txt
|
||||
4 0% 4 26 Sep 16 12:56:00+61 тест/test2/тест1.txt
|
||||
4 0% 4 26 Sep 16 12:56:08+61 тест/test2/тест3.txt
|
|
@ -0,0 +1,18 @@
|
|||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест3/тест2.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест3/тест1.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест3/тест3.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест1/тест2.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест1/тест1.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест1/тест3.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест2/тест2.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест2/тест1.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/тест2/тест3.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test1/тест2.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test1/тест1.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test1/тест3.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test3/тест2.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test3/тест1.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test3/тест3.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test2/тест2.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test2/тест1.txt
|
||||
-rw-r--r-- 1 <<uid>> 0 4 2016-09-26 12:56:00 тест/test2/тест3.txt
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
A parser for file-listings formatted like 'ls -l'.
|
||||
|
||||
Copyright (C) 2016
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the Midnight Commander.
|
||||
|
||||
The Midnight Commander is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
The Midnight Commander is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief A parser for file-listings formatted like 'ls -l'.
|
||||
*
|
||||
* This program parses file-listings the same way MC does.
|
||||
* It's basically a wrapper around vfs_parse_ls_lga().
|
||||
* You can feed it the output of any of extfs's helpers.
|
||||
*
|
||||
* After parsing, the data is written out to stdout. The output
|
||||
* format can be either YAML or a format similar to 'ls -l'.
|
||||
*
|
||||
* This program is the main tool our tester script is going to use.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
|
||||
#include "lib/vfs/utilvfs.h" /* vfs_parse_ls_lga() */
|
||||
#include "lib/util.h" /* string_perm() */
|
||||
#include "lib/timefmt.h" /* FMT_LOCALTIME */
|
||||
#include "lib/widget.h" /* for the prototype of message() only */
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FORMAT_YAML,
|
||||
FORMAT_LS
|
||||
} output_format_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* Command-line options. */
|
||||
static gboolean opt_drop_mtime = FALSE;
|
||||
static gboolean opt_drop_ids = FALSE;
|
||||
static gboolean opt_symbolic_ids = FALSE;
|
||||
static output_format_t opt_output_format = FORMAT_LS;
|
||||
|
||||
/* Misc. */
|
||||
static int error_count = 0;
|
||||
|
||||
/* forward declarations */
|
||||
static gboolean
|
||||
parse_format_name_argument (const gchar * option_name, const gchar * value, gpointer data,
|
||||
GError ** error);
|
||||
|
||||
static GOptionEntry entries[] = {
|
||||
{"drop-mtime", 0, 0, G_OPTION_ARG_NONE, &opt_drop_mtime, "Don't include mtime in the output.",
|
||||
NULL},
|
||||
{"drop-ids", 0, 0, G_OPTION_ARG_NONE, &opt_drop_ids, "Don't include uid/gid in the output.",
|
||||
NULL},
|
||||
{"symbolic-ids", 0, 0, G_OPTION_ARG_NONE, &opt_symbolic_ids,
|
||||
"Print the strings '<<uid>>'/'<<gid>>' instead of the numeric IDs when they match the process' uid/gid.",
|
||||
NULL},
|
||||
{"format", 'f', 0, G_OPTION_ARG_CALLBACK, parse_format_name_argument,
|
||||
"Output format. Default: ls.", "<ls|yaml>"},
|
||||
{NULL, '\0', 0, 0, NULL, NULL, NULL} /* Make the compiler shut up by initializing everything. */
|
||||
};
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Command-line handling.
|
||||
*/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
parse_format_name_argument (const gchar * option_name, const gchar * value, gpointer data,
|
||||
GError ** error)
|
||||
{
|
||||
(void) option_name;
|
||||
(void) data;
|
||||
|
||||
if (strcmp (value, "yaml") == 0)
|
||||
opt_output_format = FORMAT_YAML;
|
||||
else if (strcmp (value, "ls") == 0)
|
||||
opt_output_format = FORMAT_LS;
|
||||
else
|
||||
{
|
||||
g_set_error (error, MC_ERROR, G_OPTION_ERROR_FAILED, "unknown output format '%s'", value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
parse_command_line (int *argc, char **argv[])
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
|
||||
context =
|
||||
g_option_context_new
|
||||
("- Parses its input, which is expected to be in a format similar to 'ls -l', and writes the result to stdout.");
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, argc, argv, &error))
|
||||
{
|
||||
g_print ("option parsing failed: %s\n", error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Utility functions.
|
||||
*/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static const char *
|
||||
my_itoa (int i)
|
||||
{
|
||||
static char buf[BUF_SMALL];
|
||||
|
||||
sprintf (buf, "%d", i);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Returns the uid as-is, or as "<<uid>>" if the same as current user.
|
||||
*/
|
||||
static const char *
|
||||
symbolic_uid (uid_t uid)
|
||||
{
|
||||
return (opt_symbolic_ids && uid == getuid ())? "<<uid>>" : my_itoa ((int) uid);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static const char *
|
||||
symbolic_gid (gid_t gid)
|
||||
{
|
||||
return (opt_symbolic_ids && gid == getgid ())? "<<gid>>" : my_itoa ((int) gid);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Cuts off a string's line-end (as in Perl).
|
||||
*/
|
||||
static void
|
||||
chomp (char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = strlen (s);
|
||||
|
||||
/* Code taken from vfs_parse_ls_lga(), with modifications. */
|
||||
if ((--i >= 0) && (s[i] == '\r' || s[i] == '\n'))
|
||||
s[i] = '\0';
|
||||
if ((--i >= 0) && (s[i] == '\r' || s[i] == '\n'))
|
||||
s[i] = '\0';
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static const char *
|
||||
string_date (time_t time)
|
||||
{
|
||||
static char buf[BUF_SMALL];
|
||||
|
||||
/*
|
||||
* If we ever want to be able to re-parse the output of this program,
|
||||
* we'll need to use the American brain-damaged MM-DD-YYYY instead of
|
||||
* YYYY-MM-DD because vfs_parse_ls_lga() doesn't currently recognize
|
||||
* the latter.
|
||||
*/
|
||||
FMT_LOCALTIME (buf, sizeof buf, "%Y-%m-%d %H:%M:%S", time);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Override MC's message().
|
||||
*
|
||||
* vfs_parse_ls_lga() calls this on error. Since MC's uses tty/widgets, it
|
||||
* will crash us. We replace it with a plain version.
|
||||
*/
|
||||
void
|
||||
message (int flags, const char *title, const char *text, ...)
|
||||
{
|
||||
char *p;
|
||||
va_list ap;
|
||||
|
||||
(void) flags;
|
||||
(void) title;
|
||||
|
||||
va_start (ap, text);
|
||||
p = g_strdup_vprintf (text, ap);
|
||||
va_end (ap);
|
||||
printf ("message(): vfs_parse_ls_lga(): parsing error at: %s\n", p);
|
||||
g_free (p);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* YAML output format.
|
||||
*/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
yaml_dump_stbuf (const struct stat *st)
|
||||
{
|
||||
/* Various casts and flags here were taken/inspired by info_show_info(). */
|
||||
printf (" perm: %s\n", string_perm (st->st_mode));
|
||||
if (!opt_drop_ids)
|
||||
{
|
||||
printf (" uid: %s\n", symbolic_uid (st->st_uid));
|
||||
printf (" gid: %s\n", symbolic_gid (st->st_gid));
|
||||
}
|
||||
printf (" size: %" PRIuMAX "\n", (uintmax_t) st->st_size);
|
||||
printf (" nlink: %d\n", (int) st->st_nlink);
|
||||
if (!opt_drop_mtime)
|
||||
printf (" mtime: %s\n", string_date (st->st_mtime));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
yaml_dump_string (const char *name, const char *val)
|
||||
{
|
||||
char *q;
|
||||
|
||||
q = g_shell_quote (val);
|
||||
printf (" %s: %s\n", name, q);
|
||||
g_free (q);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
yaml_dump_record (gboolean success, const char *input_line, const struct stat *st,
|
||||
const char *filename, const char *linkname)
|
||||
{
|
||||
printf ("-\n"); /* Start new item in the list. */
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (filename != NULL)
|
||||
yaml_dump_string ("name", filename);
|
||||
if (linkname != NULL)
|
||||
yaml_dump_string ("linkname", linkname);
|
||||
yaml_dump_stbuf (st);
|
||||
}
|
||||
else
|
||||
{
|
||||
yaml_dump_string ("cannot parse input line", input_line);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* 'ls' output format.
|
||||
*/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
ls_dump_stbuf (const struct stat *st)
|
||||
{
|
||||
/* Various casts and flags here were taken/inspired by info_show_info(). */
|
||||
printf ("%s %3d ", string_perm (st->st_mode), (int) st->st_nlink);
|
||||
if (!opt_drop_ids)
|
||||
{
|
||||
printf ("%8s ", symbolic_uid (st->st_uid));
|
||||
printf ("%8s ", symbolic_gid (st->st_gid));
|
||||
}
|
||||
printf ("%10" PRIuMAX " ", (uintmax_t) st->st_size);
|
||||
if (!opt_drop_mtime)
|
||||
printf ("%s ", string_date (st->st_mtime));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
ls_dump_record (gboolean success, const char *input_line, const struct stat *st,
|
||||
const char *filename, const char *linkname)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
ls_dump_stbuf (st);
|
||||
if (filename != NULL)
|
||||
printf ("%s", filename);
|
||||
if (linkname != NULL)
|
||||
printf (" -> %s", linkname);
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("cannot parse input line: '%s'\n", input_line);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
/**
|
||||
* Main code.
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
process_ls_line (const char *line)
|
||||
{
|
||||
struct stat st;
|
||||
char *filename, *linkname;
|
||||
gboolean success;
|
||||
|
||||
memset (&st, 0, sizeof st);
|
||||
filename = NULL;
|
||||
linkname = NULL;
|
||||
|
||||
success = vfs_parse_ls_lga (line, &st, &filename, &linkname, NULL);
|
||||
|
||||
if (!success)
|
||||
error_count++;
|
||||
|
||||
if (opt_output_format == FORMAT_YAML)
|
||||
yaml_dump_record (success, line, &st, filename, linkname);
|
||||
else
|
||||
ls_dump_record (success, line, &st, filename, linkname);
|
||||
|
||||
g_free (filename);
|
||||
g_free (linkname);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
process_input (FILE * input)
|
||||
{
|
||||
char line[BUF_4K];
|
||||
|
||||
while (fgets (line, sizeof line, input) != NULL)
|
||||
{
|
||||
chomp (line); /* Not mandatory. Makes error messages nicer. */
|
||||
if (strncmp (line, "total ", 6) == 0) /* Convenience only: makes 'ls -l' parse cleanly. */
|
||||
continue;
|
||||
process_ls_line (line);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *input;
|
||||
|
||||
if (!parse_command_line (&argc, &argv))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (argc >= 2)
|
||||
{
|
||||
input = fopen (argv[1], "r");
|
||||
if (input == NULL)
|
||||
{
|
||||
perror (argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
input = stdin;
|
||||
}
|
||||
|
||||
process_input (input);
|
||||
|
||||
return (error_count > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------ */
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# This program is intended to be identical to 'cat' with the exception that
|
||||
# it ignores any arguments past the 1st one.
|
||||
#
|
||||
# To understand why it's needed, first read the section about
|
||||
# MC_TEST_EXTFS_LIST_CMD in the README. As explained there, the command in
|
||||
# MC_TEST_EXTFS_LIST_CMD has to ignore any extra arguments passed to it.
|
||||
# The tester achieves this by invoking a helper thus (roughly):
|
||||
#
|
||||
# export MC_TEST_EXTFS_LIST_CMD="mc_xcat /path/to/fake/input"
|
||||
# sh /path/to/helper list /dev/null
|
||||
#
|
||||
|
||||
exec cat "$1"
|
|
@ -0,0 +1,393 @@
|
|||
#!/bin/sh
|
||||
|
||||
# A tester for extfs helpers.
|
||||
#
|
||||
# Copyright (C) 2016
|
||||
# The Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of the Midnight Commander.
|
||||
#
|
||||
# The Midnight Commander is free software: you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
#
|
||||
# The Midnight Commander is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
help() {
|
||||
cat << EOS
|
||||
|
||||
NAME
|
||||
|
||||
$(basename "$0") - Tests the 'list' command of extfs helpers.
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
$(basename "$0") \\
|
||||
--data-dir /path/to/where/data/files/are/stored \\
|
||||
--helpers-dir /path/to/where/helpers/are/stored
|
||||
|
||||
(But you're more likely to invoke this program with the 'run' script
|
||||
created by 'make check'; or by 'make check' itself.)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This program tests extfs helpers by feeding them input and comparing
|
||||
their output to the expected output.
|
||||
|
||||
See README for full details.
|
||||
|
||||
You need to tell this program two things: where the helpers are stored,
|
||||
and where the "data files" are stored. The data files are *.input files
|
||||
that are fed to the helpers and *.output files that are the correct
|
||||
output expected from these helpers.
|
||||
|
||||
EOS
|
||||
}
|
||||
|
||||
#"'
|
||||
|
||||
############################ Global variables ##############################
|
||||
|
||||
# The directories used.
|
||||
DATA_DIR=
|
||||
HELPERS_DIR1=
|
||||
HELPERS_DIR2=
|
||||
|
||||
opt_create_output=no # "yes" if '--create-output' provided.
|
||||
opt_run_mcdiff_on_error=no # "yes" if '--mcdiff' provided.
|
||||
|
||||
############################ Coding guidance ###############################
|
||||
|
||||
#
|
||||
# Portability notes:
|
||||
#
|
||||
# - We do `local var="$whatever"` instead of `local var=$whatever` for
|
||||
# compatibility with Dash. See http://unix.stackexchange.com/questions/97560.
|
||||
#
|
||||
# - The 'local' keyword used in this file isn't mandatory. Feel free to
|
||||
# remove it if it isn't supported by your archaic shell.
|
||||
#
|
||||
|
||||
############################ Utility functions #############################
|
||||
|
||||
#
|
||||
# Does $1 contain $2?
|
||||
#
|
||||
# Accepts basic regex.
|
||||
#
|
||||
has_string() {
|
||||
local haystack="$1" # quotes needed for Dash, as may contain spaces (see notes above).
|
||||
local needle="$2"
|
||||
echo "$haystack" | grep "$needle" > /dev/null
|
||||
}
|
||||
|
||||
#
|
||||
# Given "/path/to/basename.and.some.ext", returns "basename"
|
||||
#
|
||||
basename_sans_extensions() {
|
||||
local base="$(basename "$1")"
|
||||
echo "${base%%.*}"
|
||||
}
|
||||
|
||||
#
|
||||
# Does an executable exist?
|
||||
#
|
||||
has_prog() {
|
||||
# see http://stackoverflow.com/questions/592620
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
#
|
||||
# Can we use colors?
|
||||
#
|
||||
has_colors() {
|
||||
[ -t 1 ] && has_string "$TERM" 'linux\|xterm\|screen\|tmux\|putty'
|
||||
}
|
||||
|
||||
init_colors() {
|
||||
if has_colors; then
|
||||
ESC=$(printf '\033') # for portability
|
||||
C_bold="$ESC[1m"
|
||||
C_green="$ESC[1;32m"
|
||||
C_red="$ESC[1;31m"
|
||||
C_magenta="$ESC[1;35m"
|
||||
C_norm="$ESC[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# A few colorful alternatives to 'echo'.
|
||||
#
|
||||
header() { echo $C_bold"$@"$C_norm; }
|
||||
err() { echo $C_red"$@"$C_norm; }
|
||||
notice() { echo $C_magenta"$@"$C_norm; }
|
||||
success() { echo $C_green"$@"$C_norm; }
|
||||
|
||||
die() {
|
||||
err "Error: $@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert_dir_exists() {
|
||||
[ -d "$1" ] || die "The directory '$1' doesn't exist, or is not a directory."
|
||||
}
|
||||
|
||||
#
|
||||
# Creates a temporary file.
|
||||
#
|
||||
temp_file() {
|
||||
local template="$1"
|
||||
# BSD's doesn't support -t.
|
||||
mktemp "${TMPDIR:-/tmp}/$template"
|
||||
}
|
||||
|
||||
################################ Main code #################################
|
||||
|
||||
#
|
||||
# Prints out the command to run a helper, if it can find it.
|
||||
#
|
||||
# For example,
|
||||
#
|
||||
# find_helper uzip /path/to/helpers/dir
|
||||
#
|
||||
# prints:
|
||||
#
|
||||
# /usr/bin/perl -w /path/to/helpers/dir/uzip
|
||||
#
|
||||
# Since helpers in the build tree don't yet have executable bit set, we
|
||||
# need to extract the shebang line.
|
||||
#
|
||||
find_helper() {
|
||||
local helper_name="$1"
|
||||
local dir="$2"
|
||||
|
||||
local try="$dir/$helper_name"
|
||||
if [ -f "$try" ]; then
|
||||
helper_CMD="$(head -1 $try | cut -c 3-) $try" # reason #1 we don't allow spaces in pathnames.
|
||||
true
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# The crux of this program.
|
||||
#
|
||||
run() {
|
||||
|
||||
local error_count=0
|
||||
local pass_count=0
|
||||
|
||||
for INPUT in "$DATA_DIR"/*.input; do
|
||||
|
||||
has_string "$INPUT" '\*' && break # we can't use 'shopt -s nullglob' as it's bash-specific.
|
||||
|
||||
header "Testing $INPUT"
|
||||
|
||||
has_string "$INPUT" " " && die "Error: filename contains spaces."
|
||||
|
||||
#
|
||||
# Set up variables:
|
||||
#
|
||||
|
||||
local helper_name="$(basename_sans_extensions "$INPUT")"
|
||||
local expected_parsed_output="${INPUT%.input}.output"
|
||||
local env_vars_file="${INPUT%.input}.env_vars"
|
||||
local args_file="${INPUT%.input}.args"
|
||||
|
||||
local do_create_output=no
|
||||
|
||||
if [ ! -f "$expected_parsed_output" ]; then
|
||||
# Corresponding *.output file doesn't exist. We either create it, later, or exit with error.
|
||||
if [ $opt_create_output = "yes" ]; then
|
||||
do_create_output=yes
|
||||
else
|
||||
err
|
||||
err "Missing file: '$expected_parsed_output'."
|
||||
err "You have to create an '.output' file for each '.input' one."
|
||||
err
|
||||
notice "Tip: invoke this program with '--create-output' to"
|
||||
notice "automatically create missing '.output' files."
|
||||
notice
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
find_helper "$helper_name" "$HELPERS_DIR1" ||
|
||||
find_helper "$helper_name" "$HELPERS_DIR2" ||
|
||||
die "I can't find helper '$helper_name' in either $HELPERS_DIR1 or $HELPERS_DIR2"
|
||||
|
||||
local extra_parser_args=""
|
||||
[ -f "$args_file" ] && extra_parser_args="$(cat "$args_file")"
|
||||
|
||||
local actual_output="$(temp_file $helper_name.actual-output.XXXXXXXX)"
|
||||
local actual_parsed_output="$(temp_file $helper_name.actual-parsed-output.XXXXXXXX)"
|
||||
|
||||
#
|
||||
# Variables are all set. Now do the actual stuff:
|
||||
#
|
||||
|
||||
(
|
||||
MC_TEST_EXTFS_LIST_CMD="mc_xcat $INPUT" # reason #2 we don't allow spaces in pathnames.
|
||||
export MC_TEST_EXTFS_LIST_CMD
|
||||
if [ -f "$env_vars_file" ]; then
|
||||
set -a # "allexport: Export all variables assigned to."
|
||||
. "$env_vars_file"
|
||||
set +a
|
||||
fi
|
||||
$helper_CMD list /dev/null > "$actual_output"
|
||||
)
|
||||
|
||||
error_count=$((error_count + 1)) # we'll decrement it later.
|
||||
|
||||
if [ ! -s "$actual_output" ]; then
|
||||
err
|
||||
err "The helper '$helper_name' produced no output for this input. Something is wrong."
|
||||
err
|
||||
err "Make sure this helper supports testability: that it uses \$MC_TEST_EXTFS_LIST_CMD."
|
||||
err
|
||||
err "You may try running the helper yourself with:"
|
||||
err
|
||||
err " \$ MC_TEST_EXTFS_LIST_CMD=\"mc_xcat $INPUT\" \\"
|
||||
err " $helper_CMD list /dev/null"
|
||||
err
|
||||
continue
|
||||
fi
|
||||
|
||||
# '--symbolic-ids': uid/gid aren't portable between computers,
|
||||
# of course, so we always represent them symbolically when possible.
|
||||
if ! mc_parse_ls_l --symbolic-ids $extra_parser_args "$actual_output" > "$actual_parsed_output"; then
|
||||
err
|
||||
err "ERROR: Parsing of the output of the helper '$helper_name' has failed."
|
||||
err "This means that $helper_name has produced output that MC won't be able to parse."
|
||||
err "Run the parsing command yourself ('mc_parse_ls_l $extra_parser_args $actual_output')"
|
||||
err "to figure out the problem."
|
||||
err
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ $do_create_output = "yes" ]; then
|
||||
# We arrive here if we were invoked with '--create-output' and
|
||||
# the .output file doesn't exist. We create it and move to the next iteration.
|
||||
cp "$actual_parsed_output" "$expected_parsed_output"
|
||||
notice "The output file has been created in $expected_parsed_output"
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! cmp "$expected_parsed_output" "$actual_parsed_output"; then
|
||||
err
|
||||
err "ERROR: $helper_name has produced output that's different than the expected output."
|
||||
err
|
||||
err " Expected output (after parsing): $expected_parsed_output"
|
||||
err " Actual output (after parsing): $actual_parsed_output"
|
||||
err
|
||||
err "This might mean that a bug was introduced into $helper_name. Or that a bug was fixed."
|
||||
err "Please compare the files."
|
||||
err
|
||||
err "If the actual output is the correct one, just copy the latter file"
|
||||
err "onto the former (and commit to the git repository)."
|
||||
err
|
||||
if [ $opt_run_mcdiff_on_error = "yes" ]; then
|
||||
notice "Hit ENTER to launch mcdiff ..."
|
||||
read DUMMY_VAR # dash needs this.
|
||||
${MCDIFF:-mcdiff} "$expected_parsed_output" "$actual_parsed_output"
|
||||
else
|
||||
notice "Tip: invoke this program with '--mcdiff' to automatically launch"
|
||||
notice "mcdiff to visually inspect the diff."
|
||||
notice
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
rm "$actual_output" "$actual_parsed_output"
|
||||
|
||||
error_count=$((error_count - 1)) # cancel the earlier "+1".
|
||||
pass_count=$((pass_count + 1))
|
||||
|
||||
success "PASSED."
|
||||
|
||||
done
|
||||
|
||||
[ $pass_count = "0" -a $error_count = "0" ] && notice "Note: The data directory contains no *.input files."
|
||||
|
||||
[ $error_count = "0" ] # exit status of function.
|
||||
}
|
||||
|
||||
parse_command_line_arguments() {
|
||||
# We want --long-options, so we don't use 'getopts'.
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
--data-dir)
|
||||
DATA_DIR=$2
|
||||
shift 2
|
||||
;;
|
||||
--helpers-dir)
|
||||
if [ -z "$HELPERS_DIR1" ]; then
|
||||
HELPERS_DIR1=$2
|
||||
else
|
||||
HELPERS_DIR2=$2
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--create-output)
|
||||
opt_create_output=yes
|
||||
shift
|
||||
;;
|
||||
--mcdiff)
|
||||
opt_run_mcdiff_on_error=yes
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
help
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
die "Unknown command-line option $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Check that everything is set up correctly.
|
||||
#
|
||||
verify_setup() {
|
||||
[ -n "$DATA_DIR" ] || die "You didn't specify the data dir (--data-dir). Run me with --help for info."
|
||||
[ -n "$HELPERS_DIR1" ] || die "You didn't specify the helpers dir (--helpers-dir). Run me with --help for info."
|
||||
[ -z "$HELPERS_DIR2" ] && HELPERS_DIR2=$HELPERS_DIR1 # we're being lazy.
|
||||
|
||||
local dir
|
||||
for dir in "$DATA_DIR" "$HELPERS_DIR1" "$HELPERS_DIR2"; do
|
||||
assert_dir_exists "$dir"
|
||||
has_string "$dir" " " && die "$dir: Sorry, spaces aren't allowed in pathnames." # search "reason", twice, above.
|
||||
done
|
||||
|
||||
local missing_progs=""
|
||||
check_prog() {
|
||||
if ! has_prog "$1"; then
|
||||
err "I can't see the program '$1'."
|
||||
missing_progs="${missing_progs}${missing_progs:+ and }'$1'"
|
||||
fi
|
||||
}
|
||||
|
||||
check_prog "mc_parse_ls_l"
|
||||
check_prog "mc_xcat"
|
||||
check_prog "mktemp" # non-POSIX
|
||||
[ -z "$missing_progs" ] || die "You need to add to your PATH the directories containing the executables $missing_progs."
|
||||
}
|
||||
|
||||
main() {
|
||||
init_colors
|
||||
parse_command_line_arguments "$@"
|
||||
verify_setup
|
||||
run # being the last command executed, its exit status is that of this whole script.
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in New Issue