summaryrefslogtreecommitdiff
path: root/tests/rm
diff options
context:
space:
mode:
Diffstat (limited to 'tests/rm')
-rwxr-xr-xtests/rm/cycle.sh2
-rwxr-xr-xtests/rm/d-1.sh2
-rwxr-xr-xtests/rm/d-2.sh2
-rwxr-xr-xtests/rm/d-3.sh2
-rwxr-xr-xtests/rm/dangling-symlink.sh2
-rwxr-xr-xtests/rm/deep-1.sh2
-rwxr-xr-xtests/rm/deep-2.sh9
-rwxr-xr-xtests/rm/dir-no-w.sh2
-rwxr-xr-xtests/rm/dir-nonrecur.sh2
-rwxr-xr-xtests/rm/dot-rel.sh2
-rwxr-xr-xtests/rm/empty-inacc.sh2
-rwxr-xr-xtests/rm/empty-name.pl2
-rwxr-xr-xtests/rm/ext3-perf.sh2
-rwxr-xr-xtests/rm/f-1.sh2
-rwxr-xr-xtests/rm/fail-2eperm.sh6
-rwxr-xr-xtests/rm/fail-eacces.sh2
-rwxr-xr-xtests/rm/fail-eperm.xpl2
-rwxr-xr-xtests/rm/hash.sh2
-rwxr-xr-xtests/rm/i-1.sh2
-rwxr-xr-xtests/rm/i-never.sh2
-rwxr-xr-xtests/rm/i-no-r.sh2
-rwxr-xr-xtests/rm/ignorable.sh2
-rwxr-xr-xtests/rm/inaccessible.sh2
-rwxr-xr-xtests/rm/interactive-always.sh6
-rwxr-xr-xtests/rm/interactive-once.sh75
-rwxr-xr-xtests/rm/ir-1.sh2
-rwxr-xr-xtests/rm/isatty.sh2
-rwxr-xr-xtests/rm/many-dir-entries-vs-OOM.sh3
-rwxr-xr-xtests/rm/no-give-up.sh5
-rwxr-xr-xtests/rm/one-file-system.sh2
-rwxr-xr-xtests/rm/one-file-system2.sh2
-rwxr-xr-xtests/rm/r-1.sh2
-rwxr-xr-xtests/rm/r-2.sh2
-rwxr-xr-xtests/rm/r-3.sh2
-rwxr-xr-xtests/rm/r-4.sh27
-rwxr-xr-xtests/rm/r-root.sh256
-rwxr-xr-xtests/rm/read-only.sh4
-rwxr-xr-xtests/rm/readdir-bug.sh2
-rwxr-xr-xtests/rm/rm1.sh2
-rwxr-xr-xtests/rm/rm2.sh2
-rwxr-xr-xtests/rm/rm3.sh2
-rwxr-xr-xtests/rm/rm4.sh2
-rwxr-xr-xtests/rm/rm5.sh2
-rwxr-xr-xtests/rm/sunos-1.sh2
-rwxr-xr-xtests/rm/unread2.sh2
-rwxr-xr-xtests/rm/unread3.sh2
-rwxr-xr-xtests/rm/unreadable.pl2
-rwxr-xr-xtests/rm/v-slash.sh2
48 files changed, 395 insertions, 74 deletions
diff --git a/tests/rm/cycle.sh b/tests/rm/cycle.sh
index 881d84b2..589ee73a 100755
--- a/tests/rm/cycle.sh
+++ b/tests/rm/cycle.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# rm (coreutils-4.5.4) could be tricked into mistakenly reporting a cycle.
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/d-1.sh b/tests/rm/d-1.sh
index cfe38ad5..dd7cfd0f 100755
--- a/tests/rm/d-1.sh
+++ b/tests/rm/d-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm --dir --verbose".
-# Copyright (C) 2012-2013 Free Software Foundation, Inc.
+# Copyright (C) 2012-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/d-2.sh b/tests/rm/d-2.sh
index 3b8ca664..87fb100c 100755
--- a/tests/rm/d-2.sh
+++ b/tests/rm/d-2.sh
@@ -2,7 +2,7 @@
# Ensure that 'rm -d dir' (i.e., without --recursive) gives a reasonable
# diagnostic when failing.
-# Copyright (C) 2012-2013 Free Software Foundation, Inc.
+# Copyright (C) 2012-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/d-3.sh b/tests/rm/d-3.sh
index b3bd0b10..646ecd06 100755
--- a/tests/rm/d-3.sh
+++ b/tests/rm/d-3.sh
@@ -2,7 +2,7 @@
# Ensure that 'rm -d -i dir' (i.e., without --recursive) gives a prompt and
# then deletes the directory if it is empty
-# Copyright (C) 2012-2013 Free Software Foundation, Inc.
+# Copyright (C) 2012-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/dangling-symlink.sh b/tests/rm/dangling-symlink.sh
index 62c66915..1e5cdfa9 100755
--- a/tests/rm/dangling-symlink.sh
+++ b/tests/rm/dangling-symlink.sh
@@ -4,7 +4,7 @@
# But for fileutils-4.1.9, it would do the former and
# for fileutils-4.1.10 the latter.
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/deep-1.sh b/tests/rm/deep-1.sh
index 5f4b63ef..1f1b307c 100755
--- a/tests/rm/deep-1.sh
+++ b/tests/rm/deep-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm" with a deep hierarchy.
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/deep-2.sh b/tests/rm/deep-2.sh
index a03cd965..c3ea0856 100755
--- a/tests/rm/deep-2.sh
+++ b/tests/rm/deep-2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Ensure rm -r DIR does not prompt for very long full relative names in DIR.
-# Copyright (C) 2008-2013 Free Software Foundation, Inc.
+# Copyright (C) 2008-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -25,6 +25,11 @@ require_perl_
# the offending euidaccess_stat call.
skip_if_root_
+# ecryptfs for example uses some of the file name space
+# for encrypting filenames, so we must check dynamically.
+name_max=$(stat -f -c %l .)
+test "$name_max" -ge '200' || skip_ "NAME_MAX=$name_max is not sufficient"
+
mkdir x || framework_failure_
cd x || framework_failure_
@@ -41,7 +46,7 @@ echo n > no || framework_failure_
rm ---presume-input-tty -r x < no > out || fail=1
# expect empty output
-test -s out && fail=1
+compare /dev/null out || fail=1
# the directory must have been removed
test -d x && fail=1
diff --git a/tests/rm/dir-no-w.sh b/tests/rm/dir-no-w.sh
index da52155c..de9035e9 100755
--- a/tests/rm/dir-no-w.sh
+++ b/tests/rm/dir-no-w.sh
@@ -2,7 +2,7 @@
# rm (without -r) must give a diagnostic for any directory.
# It must not prompt, even if that directory is unwritable.
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/dir-nonrecur.sh b/tests/rm/dir-nonrecur.sh
index fa3168e8..45956da7 100755
--- a/tests/rm/dir-nonrecur.sh
+++ b/tests/rm/dir-nonrecur.sh
@@ -2,7 +2,7 @@
# Ensure that 'rm dir' (i.e., without --recursive) gives a reasonable
# diagnostic when failing.
-# Copyright (C) 2005-2013 Free Software Foundation, Inc.
+# Copyright (C) 2005-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/dot-rel.sh b/tests/rm/dot-rel.sh
index 69956c57..4e1a8ce0 100755
--- a/tests/rm/dot-rel.sh
+++ b/tests/rm/dot-rel.sh
@@ -2,7 +2,7 @@
# Use rm -r to remove two non-empty dot-relative directories.
# This would have failed between 2004-10-18 and 2004-10-21.
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/empty-inacc.sh b/tests/rm/empty-inacc.sh
index 78d14155..e3771530 100755
--- a/tests/rm/empty-inacc.sh
+++ b/tests/rm/empty-inacc.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Ensure that rm -rf removes an empty-and-inaccessible directory.
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/empty-name.pl b/tests/rm/empty-name.pl
index 4c94ebc0..b6ee6ad5 100755
--- a/tests/rm/empty-name.pl
+++ b/tests/rm/empty-name.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# Make sure that rm -r '' fails.
-# Copyright (C) 1998-2013 Free Software Foundation, Inc.
+# Copyright (C) 1998-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/ext3-perf.sh b/tests/rm/ext3-perf.sh
index e24c8098..ef4fee46 100755
--- a/tests/rm/ext3-perf.sh
+++ b/tests/rm/ext3-perf.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that "rm -rf DIR-with-many-entries" is not O(N^2)
-# Copyright (C) 2008-2013 Free Software Foundation, Inc.
+# Copyright (C) 2008-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/f-1.sh b/tests/rm/f-1.sh
index 7837580f..0fc95c4f 100755
--- a/tests/rm/f-1.sh
+++ b/tests/rm/f-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm -f" with a nonexistent file.
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/fail-2eperm.sh b/tests/rm/fail-2eperm.sh
index 0f1a4fa5..6e8ce9ba 100755
--- a/tests/rm/fail-2eperm.sh
+++ b/tests/rm/fail-2eperm.sh
@@ -2,7 +2,7 @@
# Like fail-eperm, but the failure must be for a file encountered
# while trying to remove the containing directory with the sticky bit set.
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,14 +32,14 @@ touch a/b || framework_failure_
# Try to ensure that $NON_ROOT_USERNAME can access
# the required version of rm.
rm_version=$(
- setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm --version |
+ chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version |
sed -n '1s/.* //p'
)
case $rm_version in
$PACKAGE_VERSION) ;;
*) skip_ "cannot access just-built rm as user $NON_ROOT_USERNAME";;
esac
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm -rf a 2> out-t && fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm -rf a 2> out-t && fail=1
# On some systems, we get 'Not owner'. Convert it.
# On other systems (HPUX), we get 'Permission denied'. Convert it, too.
diff --git a/tests/rm/fail-eacces.sh b/tests/rm/fail-eacces.sh
index 2167a047..dd31ea4c 100755
--- a/tests/rm/fail-eacces.sh
+++ b/tests/rm/fail-eacces.sh
@@ -4,7 +4,7 @@
# With the symlink, rm from coreutils-6.9 would fail with a misleading
# ELOOP diagnostic.
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/fail-eperm.xpl b/tests/rm/fail-eperm.xpl
index fb46445e..b167d0ba 100755
--- a/tests/rm/fail-eperm.xpl
+++ b/tests/rm/fail-eperm.xpl
@@ -2,7 +2,7 @@
# Ensure that rm gives the expected diagnostic when failing to remove a file
# owned by some other user in a directory with the sticky bit set.
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/hash.sh b/tests/rm/hash.sh
index e10879b8..6bc82bdc 100755
--- a/tests/rm/hash.sh
+++ b/tests/rm/hash.sh
@@ -3,7 +3,7 @@
# Before then, rm would fail occasionally, sometimes via
# a failed assertion, others with a seg fault.
-# Copyright (C) 2000-2013 Free Software Foundation, Inc.
+# Copyright (C) 2000-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/i-1.sh b/tests/rm/i-1.sh
index 32aba21d..6a4ca64b 100755
--- a/tests/rm/i-1.sh
+++ b/tests/rm/i-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm -i".
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/i-never.sh b/tests/rm/i-never.sh
index fc4e9412..6302174a 100755
--- a/tests/rm/i-never.sh
+++ b/tests/rm/i-never.sh
@@ -2,7 +2,7 @@
# Ensure that rm --interactive=never works does not prompt, even for
# an unwritable file.
-# Copyright (C) 2007-2013 Free Software Foundation, Inc.
+# Copyright (C) 2007-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/i-no-r.sh b/tests/rm/i-no-r.sh
index 4304f051..8a535faf 100755
--- a/tests/rm/i-no-r.sh
+++ b/tests/rm/i-no-r.sh
@@ -3,7 +3,7 @@
# recurse into directory DIR. rm -i (without -r) must fail in that case.
# Fixed in coreutils-4.5.2.
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/ignorable.sh b/tests/rm/ignorable.sh
index 645982c5..8d656eea 100755
--- a/tests/rm/ignorable.sh
+++ b/tests/rm/ignorable.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Ensure that rm -f existing-non-dir/anything exits successfully
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/inaccessible.sh b/tests/rm/inaccessible.sh
index 9408a18b..e3c48dfe 100755
--- a/tests/rm/inaccessible.sh
+++ b/tests/rm/inaccessible.sh
@@ -2,7 +2,7 @@
# Ensure that rm works even when run from a directory
# for which the user has no access at all.
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/interactive-always.sh b/tests/rm/interactive-always.sh
index 1dfb5a69..627d923e 100755
--- a/tests/rm/interactive-always.sh
+++ b/tests/rm/interactive-always.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test the --interactive[=WHEN] changes added to coreutils 6.0
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -72,13 +72,13 @@ no WHEN
WHEN=never
.
WHEN=once
-rm: remove all arguments recursively? .
+rm: remove 2 arguments recursively? .
WHEN=always
@remove_empty 'file4-1'? @remove_empty 'file4-2'? .
-f overrides --interactive
.
--interactive overrides -f
-rm: remove all arguments recursively? .
+rm: remove 1 argument recursively? .
EOF
compare expout out || fail=1
diff --git a/tests/rm/interactive-once.sh b/tests/rm/interactive-once.sh
index d138b752..db10bba6 100755
--- a/tests/rm/interactive-once.sh
+++ b/tests/rm/interactive-once.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test the -I option added to coreutils 6.0
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -30,19 +30,36 @@ rm -f out err || framework_failure_
# The prompt has a trailing space, and no newline, so an extra
# 'echo .' is inserted after each rm to make it obvious what was asked.
-echo 'one file, no recursion' > err || fail=1
+echo 'one file, no recursion' > err || framework_failure_
rm -I file1-* < in-n >> out 2>> err || fail=1
echo . >> err || fail=1
test -f file1-1 && fail=1
-echo 'three files, no recursion' >> err || fail=1
+echo 'one file, read only, answer no' >> err || framework_failure_
+if ls /dev/stdin >/dev/null 2>&1; then
+ touch file1-1 || framework_failure_
+ chmod a-w file1-1 || framework_failure_
+ if ! test -w file1-1; then
+ # root won't get prompted
+ write_prot_msg1="rm: remove write-protected regular empty file 'file1-1'? "
+ fi
+ rm ---presume-input-tty -I file1-* < in-n >> out 2>> err || fail=1
+ echo . >> err || fail=1
+ if test "$write_prot_msg1"; then
+ test -f file1-1 || fail=1
+ fi
+else
+ echo '.' >> err || framework_failure_
+fi
+
+echo 'three files, no recursion' >> err || framework_failure_
rm -I file2-* < in-n >> out 2>> err || fail=1
echo . >> err || fail=1
test -f file2-1 && fail=1
test -f file2-2 && fail=1
test -f file2-3 && fail=1
-echo 'four files, no recursion, answer no' >> err || fail=1
+echo 'four files, no recursion, answer no' >> err || framework_failure_
rm -I file3-* < in-n >> out 2>> err || fail=1
echo . >> err || fail=1
test -f file3-1 || fail=1
@@ -50,7 +67,7 @@ test -f file3-2 || fail=1
test -f file3-3 || fail=1
test -f file3-4 || fail=1
-echo 'four files, no recursion, answer yes' >> err || fail=1
+echo 'four files, no recursion, answer yes' >> err || framework_failure_
rm -I file3-* < in-y >> out 2>> err || fail=1
echo . >> err || fail=1
test -f file3-1 && fail=1
@@ -58,23 +75,45 @@ test -f file3-2 && fail=1
test -f file3-3 && fail=1
test -f file3-4 && fail=1
-echo 'one file, recursion, answer no' >> err || fail=1
+echo 'four files, no recursion, 1 read only, answer yes no' >> err \
+ || framework_failure_
+if ls /dev/stdin >/dev/null 2>&1; then
+ touch file3-1 file3-2 file3-3 file3-4 || framework_failure_
+ echo non_empty > file3-4 || framework_failure_ # to shorten diagnostic
+ chmod a-w file3-4 || framework_failure_
+ if ! test -w file3-4; then
+ # root won't get prompted
+ write_prot_msg2="rm: remove write-protected regular file 'file3-4'? "
+ fi
+ cat in-y in-n | rm ---presume-input-tty -I file3-* >> out 2>> err || fail=1
+ echo . >> err || fail=1
+ test -f file3-1 && fail=1
+ test -f file3-2 && fail=1
+ test -f file3-3 && fail=1
+ if test "$write_prot_msg2"; then
+ test -f file3-4 || fail=1
+ fi
+else
+ echo 'rm: remove 4 arguments? .' >> err || framework_failure_
+fi
+
+echo 'one file, recursion, answer no' >> err || framework_failure_
rm -I -R dir1-* < in-n >> out 2>> err || fail=1
echo . >> err || fail=1
test -d dir1-1 || fail=1
-echo 'one file, recursion, answer yes' >> err || fail=1
+echo 'one file, recursion, answer yes' >> err || framework_failure_
rm -I -R dir1-* < in-y >> out 2>> err || fail=1
echo . >> err || fail=1
test -d dir1-1 && fail=1
-echo 'multiple files, recursion, answer no' >> err || fail=1
+echo 'multiple files, recursion, answer no' >> err || framework_failure_
rm -I -R dir2-* < in-n >> out 2>> err || fail=1
echo . >> err || fail=1
test -d dir2-1 || fail=1
test -d dir2-2 || fail=1
-echo 'multiple files, recursion, answer yes' >> err || fail=1
+echo 'multiple files, recursion, answer yes' >> err || framework_failure_
rm -I -R dir2-* < in-y >> out 2>> err || fail=1
echo . >> err || fail=1
test -d dir2-1 && fail=1
@@ -82,23 +121,27 @@ test -d dir2-2 && fail=1
cat <<\EOF > expout || fail=1
EOF
-cat <<\EOF > experr || fail=1
+cat <<EOF > experr || fail=1
one file, no recursion
.
+one file, read only, answer no
+$write_prot_msg1.
three files, no recursion
.
four files, no recursion, answer no
-rm: remove all arguments? .
+rm: remove 4 arguments? .
four files, no recursion, answer yes
-rm: remove all arguments? .
+rm: remove 4 arguments? .
+four files, no recursion, 1 read only, answer yes no
+rm: remove 4 arguments? $write_prot_msg2.
one file, recursion, answer no
-rm: remove all arguments recursively? .
+rm: remove 1 argument recursively? .
one file, recursion, answer yes
-rm: remove all arguments recursively? .
+rm: remove 1 argument recursively? .
multiple files, recursion, answer no
-rm: remove all arguments recursively? .
+rm: remove 2 arguments recursively? .
multiple files, recursion, answer yes
-rm: remove all arguments recursively? .
+rm: remove 2 arguments recursively? .
EOF
compare expout out || fail=1
diff --git a/tests/rm/ir-1.sh b/tests/rm/ir-1.sh
index f2068fd6..86a5595f 100755
--- a/tests/rm/ir-1.sh
+++ b/tests/rm/ir-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm -ir".
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/isatty.sh b/tests/rm/isatty.sh
index b0d7a06a..0ff8d1fa 100755
--- a/tests/rm/isatty.sh
+++ b/tests/rm/isatty.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Make sure 'chown 0 f; rm f' prompts before removing f.
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/many-dir-entries-vs-OOM.sh b/tests/rm/many-dir-entries-vs-OOM.sh
index c867a46e..c45453d7 100755
--- a/tests/rm/many-dir-entries-vs-OOM.sh
+++ b/tests/rm/many-dir-entries-vs-OOM.sh
@@ -2,7 +2,7 @@
# In coreutils-8.12, rm,du,chmod, etc. would use too much memory
# when processing a directory with many entries (as in > 100,000).
-# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
print_ver_ rm du chmod
+require_ulimit_v_
expensive_
diff --git a/tests/rm/no-give-up.sh b/tests/rm/no-give-up.sh
index 915970d1..41070c9d 100755
--- a/tests/rm/no-give-up.sh
+++ b/tests/rm/no-give-up.sh
@@ -2,7 +2,7 @@
# With rm from coreutils-5.2.1 and earlier, 'rm -r' would mistakenly
# give up too early under some conditions.
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -30,7 +30,8 @@ chmod go=x . || framework_failure_
# This must fail, since '.' is not writable by $NON_ROOT_USERNAME.
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm -rf d 2>/dev/null && fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \
+ rm -rf d 2>/dev/null && fail=1
# d must remain.
test -d d || fail=1
diff --git a/tests/rm/one-file-system.sh b/tests/rm/one-file-system.sh
index 54a81892..09a0464b 100755
--- a/tests/rm/one-file-system.sh
+++ b/tests/rm/one-file-system.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Demonstrate rm's new --one-file-system option.
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/one-file-system2.sh b/tests/rm/one-file-system2.sh
index 94bf442e..e4e8a417 100755
--- a/tests/rm/one-file-system2.sh
+++ b/tests/rm/one-file-system2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Verify --one-file-system does delete within a file system
-# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/r-1.sh b/tests/rm/r-1.sh
index 362e6adb..6e1d6089 100755
--- a/tests/rm/r-1.sh
+++ b/tests/rm/r-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm -r --verbose".
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/r-2.sh b/tests/rm/r-2.sh
index 34c9f282..a8049bd2 100755
--- a/tests/rm/r-2.sh
+++ b/tests/rm/r-2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Test "rm -r --verbose".
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/r-3.sh b/tests/rm/r-3.sh
index 91e80516..82c35bed 100755
--- a/tests/rm/r-3.sh
+++ b/tests/rm/r-3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Create and remove a directory with more than 254 files.
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/r-4.sh b/tests/rm/r-4.sh
index 94702a6d..095f1516 100755
--- a/tests/rm/r-4.sh
+++ b/tests/rm/r-4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Try to remove '.' and '..' recursively.
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -22,11 +22,26 @@ print_ver_ rm
mkdir d || framework_failure_
touch d/a || framework_failure_
-rm -fr d/. 2>/dev/null && fail=1
-rm -fr d/./ 2>/dev/null && fail=1
-rm -fr d/.//// 2>/dev/null && fail=1
-rm -fr d/.. 2>/dev/null && fail=1
-rm -fr d/../ 2>/dev/null && fail=1
+# Expected error diagnostic as grep pattern.
+exp="^rm: refusing to remove '\.' or '\.\.' directory: skipping '.*'\$"
+
+rmtest()
+{
+ # Try removing - expecting failure.
+ rm -fr "$1" 2> err && fail=1
+
+ # Ensure the expected error diagnostic is output.
+ grep "$exp" err || { cat err; fail=1; }
+
+ return $fail
+}
+
+rmtest 'd/.' || fail=1
+rmtest 'd/./' || fail=1
+rmtest 'd/.////' || fail=1
+rmtest 'd/..' || fail=1
+rmtest 'd/../' || fail=1
+
# This test is too dangerous -- if there's a bug you're wiped out!
# rm -fr / 2>/dev/null && fail=1
diff --git a/tests/rm/r-root.sh b/tests/rm/r-root.sh
new file mode 100755
index 00000000..e17b85bd
--- /dev/null
+++ b/tests/rm/r-root.sh
@@ -0,0 +1,256 @@
+#!/bin/sh
+# Try to remove '/' recursively.
+
+# Copyright (C) 2013-2014 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ rm
+
+# POSIX mandates rm(1) to skip '/' arguments. This test verifies this mandated
+# behavior as well as the --preserve-root and --no-preserve-root options.
+# Especially the latter case is a live fire exercise as rm(1) is supposed to
+# enter the unlinkat() system call. Therefore, limit the risk as much
+# as possible -- if there's a bug this test would wipe the system out!
+
+# Faint-hearted: skip this test for the 'root' user.
+skip_if_root_
+
+# Pull the teeth from rm(1) by intercepting the unlinkat() system call via the
+# LD_PRELOAD environment variable. This requires shared libraries to work.
+require_gcc_shared_
+
+# This isn't terribly expensive, but it must not be run under heavy load.
+# The reason is the conservative 'timeout' setting below to limit possible
+# damage in the worst case which yields a race under heavy load.
+# Marking this test as "expensive" therefore is a compromise, i.e., adding
+# this test to the list ensures it still gets _some_ (albeit minimal)
+# coverage while not causing false-positive failures in day to day runs.
+expensive_
+
+cat > k.c <<'EOF' || framework_failure_
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int unlinkat (int dirfd, const char *pathname, int flags)
+{
+ /* Prove that LD_PRELOAD works: create the evidence file "x". */
+ fclose (fopen ("x", "w"));
+
+ /* Immediately terminate, unless indicated otherwise. */
+ if (! getenv("CU_TEST_SKIP_EXIT"))
+ _exit (0);
+
+ /* Pretend success. */
+ return 0;
+}
+EOF
+
+# Then compile/link it:
+gcc_shared_ k.c k.so \
+ || framework_failure_ 'failed to build shared library'
+
+#-------------------------------------------------------------------------------
+# exercise_rm_r_root: shell function to test "rm -r '/'"
+# The caller must provide the FILE to remove as well as any options
+# which should be passed to 'rm'.
+# Paranoia mode on:
+# For the worst case where both rm(1) would fail to refuse to process the "/"
+# argument (in the cases without the --no-preserve-root option), and
+# intercepting the unlinkat(1) system call would fail (which actually already
+# has been proven to work above), and the current non root user has
+# write access to "/", limit the damage to the current file system via
+# the --one-file-system option.
+# Furthermore, run rm(1) via timeout(1) that kills that process after
+# a maximum of 2 seconds.
+exercise_rm_r_root ()
+{
+ # Remove the evidence file "x"; verify that.
+ rm -f x || framework_failure_
+ test -f x && framework_failure_
+
+ local skip_exit=
+ if [ "$CU_TEST_SKIP_EXIT" = 1 ]; then
+ # Pass on this variable into 'rm's environment.
+ skip_exit='CU_TEST_SKIP_EXIT=1'
+ fi
+
+ timeout --signal=KILL 2 \
+ env LD_PRELOAD=./k.so $skip_exit \
+ rm -rv --one-file-system "$@" > out 2> err
+
+ return $?
+}
+
+# Verify that "rm -r dir" basically works.
+mkdir dir || framework_failure_
+rm -r dir || framework_failure_
+test -d dir && framework_failure_
+
+# Now verify that intercepting unlinkat() works:
+# rm(1) must succeed as before, but this time both the evidence file "x"
+# and the test file / directory must still exist afterward.
+mkdir dir || framework_failure_
+> file || framework_failure_
+
+skip=
+for file in dir file ; do
+ exercise_rm_r_root "$file" || skip=1
+ test -e "$file" || skip=1
+ test -f x || skip=1
+
+ test $skip = 1 \
+ && { cat out; cat err; \
+ skip_ "internal test failure: maybe LD_PRELOAD doesn't work?"; }
+done
+
+# "rm -r /" without --no-preserve-root should output the following
+# diagnostic error message.
+cat <<EOD > exp || framework_failure_
+rm: it is dangerous to operate recursively on '/'
+rm: use --no-preserve-root to override this failsafe
+EOD
+
+#-------------------------------------------------------------------------------
+# Exercise "rm -r /" without and with the --preserve-root option.
+# Exercise various synonyms of "/" including symlinks to it.
+# Expect a non-Zero exit status.
+# Prepare a few symlinks to "/".
+ln -s / rootlink || framework_failure_
+ln -s rootlink rootlink2 || framework_failure_
+ln -sr / rootlink3 || framework_failure_
+
+for opts in \
+ '/' \
+ '--preserve-root /' \
+ '//' \
+ '///' \
+ '////' \
+ 'rootlink/' \
+ 'rootlink2/' \
+ 'rootlink3/' ; do
+
+ exercise_rm_r_root $opts \
+ && fail=1
+
+ # For some of the synonyms, the error diagnostic slightly differs from that
+ # of the basic "/" case (see gnulib's fts_open' and ROOT_DEV_INO_WARN):
+ # rm: it is dangerous to operate recursively on 'FILE' (same as '/')
+ # Strip that part off for the following comparison.
+ sed "s/\(rm: it is dangerous to operate recursively on\).*$/\1 '\/'/" err \
+ > err2 || framework_failure_
+
+ # Expect nothing in 'out' and the above error diagnostic in 'err2'.
+ # As rm(1) should have skipped the "/" argument, it does not call unlinkat().
+ # Therefore, the evidence file "x" should not exist.
+ compare /dev/null out || fail=1
+ compare exp err2 || fail=1
+ test -f x && fail=1
+
+ # Do nothing more if this test failed.
+ test $fail = 1 && { cat out; cat err; Exit $fail; }
+done
+
+#-------------------------------------------------------------------------------
+# Exercise "rm -r file1 / file2".
+# Expect a non-Zero exit status representing failure to remove "/",
+# yet 'file1' and 'file2' should be removed.
+> file1 || framework_failure_
+> file2 || framework_failure_
+
+# Now that we know that 'rm' won't call the unlinkat() system function for "/",
+# we could probably execute it without the LD_PRELOAD'ed safety net.
+# Nevertheless, it's still better to use it for this test.
+# Tell the unlinkat() replacement function to not _exit(0) immediately
+# by setting the following variable.
+CU_TEST_SKIP_EXIT=1
+
+exercise_rm_r_root --preserve-root file1 '/' file2 \
+ && fail=1
+
+unset CU_TEST_SKIP_EXIT
+
+cat <<EOD > out_removed
+removed 'file1'
+removed 'file2'
+EOD
+
+# The above error diagnostic should appear in 'err'.
+# Both 'file1' and 'file2' should be removed. Simply verify that in the
+# "out" file, as the replacement unlinkat() dummy did not remove them.
+# Expect the evidence file "x" to exist.
+compare out_removed out || fail=1
+compare exp err || fail=1
+test -f x || fail=1
+
+# Do nothing more if this test failed.
+test $fail = 1 && { cat out; cat err; Exit $fail; }
+
+#-------------------------------------------------------------------------------
+# Exercise various synonyms of "/" having a trailing "." or ".." in the name.
+# This triggers another check in the code first and therefore leads to a
+# different diagnostic. However, we want to test anyway to protect against
+# future reordering of the checks in the code.
+# Expect that other error diagnostic in 'err' and nothing in 'out'.
+# Expect a non-Zero exit status. The evidence file "x" should not exist.
+for file in \
+ '//.' \
+ '/./' \
+ '/.//' \
+ '/../' \
+ '/.././' \
+ '/etc/..' \
+ 'rootlink/..' \
+ 'rootlink2/.' \
+ 'rootlink3/./' ; do
+
+ test -d "$file" || continue # if e.g. /etc does not exist.
+
+ exercise_rm_r_root --preserve-root "$file" \
+ && fail=1
+
+ grep "^rm: refusing to remove '\.' or '\.\.' directory: skipping" err \
+ || fail=1
+
+ compare /dev/null out || fail=1
+ test -f x && fail=1
+
+ # Do nothing more if this test failed.
+ test $fail = 1 && { cat out; cat err; Exit $fail; }
+done
+
+#-------------------------------------------------------------------------------
+# Until now, it was all just fun.
+# Now exercise the --no-preserve-root option with which rm(1) should enter
+# the intercepted unlinkat() system call.
+# As the interception code terminates the process immediately via _exit(0),
+# the exit status should be 0.
+# Use the option --interactive=never to bypass the following prompt:
+# "rm: descend into write-protected directory '/'?"
+exercise_rm_r_root --interactive=never --no-preserve-root '/' \
+ || fail=1
+
+# The 'err' file should not contain the above error diagnostic.
+grep "^rm: it is dangerous to operate recursively on '/'" err \
+ && fail=1
+
+# Instead, rm(1) should have called the intercepted unlinkat() function,
+# i.e. the evidence file "x" should exist.
+test -f x || fail=1
+
+test $fail = 1 && { cat out; cat err; }
+
+Exit $fail
diff --git a/tests/rm/read-only.sh b/tests/rm/read-only.sh
index dbb3f540..377305cd 100755
--- a/tests/rm/read-only.sh
+++ b/tests/rm/read-only.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Ensure that rm -f nonexistent-file-on-read-only-fs succeeds.
-# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -42,7 +42,7 @@ test $skip = 1 \
# Applying rm -f to a nonexistent file on a read-only file system must succeed.
rm -f mnt/no-such > out 2>&1 || fail=1
# It must produce no diagnostic.
-test -s out && fail=1
+compare /dev/null out || fail=1
# However, trying to remove an existing file must fail.
rm -f mnt/f > out 2>&1 && fail=1
diff --git a/tests/rm/readdir-bug.sh b/tests/rm/readdir-bug.sh
index 58d864f9..d54a71c1 100755
--- a/tests/rm/readdir-bug.sh
+++ b/tests/rm/readdir-bug.sh
@@ -2,7 +2,7 @@
# Exercise the Darwin/MacOS bug worked around on 2006-09-29,
# whereby rm would fail to remove all entries in a directory.
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/rm1.sh b/tests/rm/rm1.sh
index 6c6b865e..575a78dd 100755
--- a/tests/rm/rm1.sh
+++ b/tests/rm/rm1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# exercise another small part of remove.c
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/rm2.sh b/tests/rm/rm2.sh
index df1990ff..93ca66e2 100755
--- a/tests/rm/rm2.sh
+++ b/tests/rm/rm2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# exercise another small part of remove.c
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/rm3.sh b/tests/rm/rm3.sh
index 4b5e6b32..dda27a60 100755
--- a/tests/rm/rm3.sh
+++ b/tests/rm/rm3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# exercise another small part of remove.c
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/rm4.sh b/tests/rm/rm4.sh
index eff2b583..60eb4a78 100755
--- a/tests/rm/rm4.sh
+++ b/tests/rm/rm4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that 'rm dir' fails without --recursive
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/rm5.sh b/tests/rm/rm5.sh
index 3112026f..6ccd6c6b 100755
--- a/tests/rm/rm5.sh
+++ b/tests/rm/rm5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# a basic test of rm -ri
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/sunos-1.sh b/tests/rm/sunos-1.sh
index 7336540f..cc8a02b7 100755
--- a/tests/rm/sunos-1.sh
+++ b/tests/rm/sunos-1.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Make sure that rm -r '' fails.
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/unread2.sh b/tests/rm/unread2.sh
index 139f9f00..977d557d 100755
--- a/tests/rm/unread2.sh
+++ b/tests/rm/unread2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# exercise one small part of remove.c
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/unread3.sh b/tests/rm/unread3.sh
index b094ae76..a8df825c 100755
--- a/tests/rm/unread3.sh
+++ b/tests/rm/unread3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Ensure that rm works even from an unreadable working directory.
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/unreadable.pl b/tests/rm/unreadable.pl
index 614dcfe9..7f0cd3d6 100755
--- a/tests/rm/unreadable.pl
+++ b/tests/rm/unreadable.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# Test "rm" and unreadable directories.
-# Copyright (C) 1998-2013 Free Software Foundation, Inc.
+# Copyright (C) 1998-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tests/rm/v-slash.sh b/tests/rm/v-slash.sh
index b04e2187..69730a19 100755
--- a/tests/rm/v-slash.sh
+++ b/tests/rm/v-slash.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# avoid extra slashes in --verbose output
-# Copyright (C) 2007-2013 Free Software Foundation, Inc.
+# Copyright (C) 2007-2014 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by