xref: /aosp_15_r20/external/toybox/tests/tar.test (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1#!/bin/bash
2
3[ -f testing.sh ] && . testing.sh
4
5#testing "name" "command" "result" "infile" "stdin"
6
7# For reproducibility: TZ=UTC, umask 0002, override ownership and timestamp
8export TZ=utc
9umask 0002
10TAR='tar c --owner root --group sys --mtime @1234567890'
11
12# 255 bytes, longest VFS name
13LONG=0123456789abcdef0123456789abcdef
14LONG=$LONG$LONG$LONG$LONG$LONG$LONG$LONG$LONG
15LONG=${LONG:1:255}
16
17# We check both sha1sum (to ensure binary identical output) and list contents.
18
19# Check hash of first N 512 byte frames to ensure result is binary identical.
20function SUM()
21{
22  # Different tars add variable trailing NUL padding (1024 bytes is just
23  # minimum) so look at first N 512-byte frames when analyzing header content.
24  tee save.dat | head -c $(($1*512)) | sha1sum | sed "s/ .*//"
25}
26
27# List tarball contents, converting variable tabs into one space
28function LST()
29{
30  tar tv "$@" | sed 's/[ \t][ \t]*/ /g'
31}
32
33# Check that stored empty file is binary identical and decodes as expected.
34touch file
35testing "store file" "$TAR file | SUM 3" \
36  "2735f3a18d770dd0d7145d76108532f72bef9927\n" "" ""
37testing "pass file" "$TAR file | LST" \
38  "-rw-rw-r-- root/sys 0 2009-02-13 23:31 file\n" "" ""
39
40# Two files from -T list
41touch file1 file2
42testing "-T newline" "$TAR -T input | LST" \
43  "-rw-rw-r-- root/sys 0 2009-02-13 23:31 file1\n-rw-rw-r-- root/sys 0 2009-02-13 23:31 file2\n" "file1\nfile2\n" ""
44testing "-T null" "$TAR --null -T input | LST" \
45  "-rw-rw-r-- root/sys 0 2009-02-13 23:31 file1\n-rw-rw-r-- root/sys 0 2009-02-13 23:31 file2\n" "file1\0file2\0" ""
46
47# User "root" is UID 0 and group "sys" is GID 3 (on Linux, BSD, and Mac),
48# inherited from Bell Labs Unix v7
49
50# Note: testing both "tar c" and "tar -c" here.
51testing "specify UID, fetch GID" "tar -c --owner nobody:65534 --mtime @0 file | LST" \
52  "-rw-rw-r-- nobody/$(stat -c %G file) 0 1970-01-01 00:00 file\n" "" ""
53testing "fetch UID, specify GID" "tar c --group nobody:65534 --mtime @0 file | LST" \
54  "-rw-rw-r-- $(stat -c %U file)/nobody 0 1970-01-01 00:00 file\n" "" ""
55
56# Large values switch from ascii numbers to a binary format.
57testing "huge values" "tar c --owner 9999999 --group 8888888 --mtime @0 file | SUM 3" \
58  "396b07fd2f80eeb312462e3bfb7dc1325dc6bcfb\n" "" ""
59
60testcmd "longname" "tf $FILES/tar/long_path.tar" \
61  "$(printf 'long file name%86cTRAILING' ' ' | tr ' ' _)\n" "" ""
62
63touch -t 198701231234.56 file
64testing "pass mtime" \
65  "tar c --owner root --group sys file | LST --full-time" \
66  "-rw-rw-r-- root/sys 0 1987-01-23 12:34:56 file\n" "" ""
67
68testing "adjust mode" \
69  "tar c --owner root --group sys --mode a+x file | LST --full-time" \
70  "-rwxrwxr-x root/sys 0 1987-01-23 12:34:56 file\n" "" ""
71
72mkdir dir
73testing "store dir" "$TAR dir | SUM 3" \
74  "85add1060cfe831ca0cdc945158efe6db485b81e\n" "" ""
75testing "pass dir" "$TAR dir | LST" \
76  "drwxrwxr-x root/sys 0 2009-02-13 23:31 dir/\n" "" ""
77
78# note: does _not_ include dir entry in archive, just file
79touch dir/file
80testing "store file in dir" "$TAR dir/file | SUM 3" \
81  "d9e7fb3884430d29e7eed0dc04a2593dd260df14\n" "" ""
82
83# Test recursion with one file so filesystem sort order can't change result
84testing "store dir and dir/file" "$TAR dir | SUM 3" \
85  "a4e35f87e28c4565b60ba01dbe79e431914f8788\n" "" ""
86
87testing "pass dir/file" "$TAR dir | LST" \
88  "drwxrwxr-x root/sys 0 2009-02-13 23:31 dir/\n-rw-rw-r-- root/sys 0 2009-02-13 23:31 dir/file\n" "" ""
89
90echo boing > dir/that
91testing "tar C" "$TAR -C dir that | SUM 3" \
92  "d469d4bc06def2d8808400ba30025ca295d05e4f\n" "" ""
93
94ln dir/file dir/hardlink
95testing "store hardlink" "$TAR dir/file dir/hardlink | SUM 3" \
96  "519de8abd1b32debd495a0fc1d96082184abbdcc\n" "" ""
97
98skipnot mkfifo dir/fifo 2>/dev/null
99testing "create dir/fifo" "$TAR dir/fifo | SUM 3" \
100  "cad477bd0fc5173d0a43f4774f514035456960e6\n" "" ""
101
102# test L and K records
103
104# 4+96=100 (biggest short name), 4+97=101 (shortest long name)
105touch dir/${LONG:1:96} dir/${LONG:1:97}
106testing "create long fname" "$TAR dir/${LONG:1:97} dir/${LONG:1:96} | SUM 3" \
107  "d70018505fa5df19ae73498cfc74d0281601e42e\n" "" ""
108
109# MacOS X has different symlink permissions, skip these tests there
110[ "$(uname)" == Darwin ] && SKIP=999
111
112  # / and .. only stripped from name, not symlink target.
113  ln -s ../name.././.. dir/link
114  testing "create symlink" "$TAR dir/link | SUM 3" \
115    "f841bf9d757c655c5d37f30be62acb7ae24f433c\n" "" ""
116
117  ln dir/link dir/hlink
118  testing "create hardlink to symlink" "$TAR dir/link dir/hlink | SUM 3" \
119    "de571a6dbf09e1485e513ad13a178b1729267452\n" "" ""
120
121  ln -s dir/${LONG:1:96} dir/lshort
122  ln -s dir/${LONG:1:97} dir/llong
123  testing "create long symlink" "$TAR dir/lshort dir/llong | SUM 3" \
124    "07eaf397634b5443dbf2d3ec38a4302150fcfe82\n" "" ""
125
126  skipnot ln -s $LONG dir/${LONG:5} 2>/dev/null
127  testing "create long->long" "$TAR dir/${LONG:5} | SUM 7" \
128    "b9e24f53e27496c5125445230d201b4a36ff7398\n" "" ""
129
130  # absolute and relative link names, broken and not
131  ln -s file dir/linkok
132  testing "create symlink" "$TAR dir/linkok | SUM 3" \
133    "f5669cfd179ddcdd5ca9f8a1561a99e11e0a08b1\n" "" ""
134
135SKIP=0 # End of tests that don't match MacOS symlink permissions
136
137symlink_perms=lrwxrwxrwx
138[ "$(uname)" == "Darwin" ] && symlink_perms=lrwxrwxr-x
139
140ln -s /dev/null dir/linknull
141testing "pass absolute symlink" "$TAR dir/linknull | LST" \
142  "$symlink_perms root/sys 0 2009-02-13 23:31 dir/linknull -> /dev/null\n" "" ""
143
144ln -s rel/broken dir/relbrok
145testing "pass broken symlink" "$TAR dir/relbrok | LST" \
146  "$symlink_perms root/sys 0 2009-02-13 23:31 dir/relbrok -> rel/broken\n" "" ""
147
148ln -s /does/not/exist dir/linkabsbrok
149testing "pass broken absolute symlink" "$TAR dir/linkabsbrok | LST" \
150  "$symlink_perms root/sys 0 2009-02-13 23:31 dir/linkabsbrok -> /does/not/exist\n" \
151  "" ""
152
153nulldev=1,3 # devtmpfs values
154[ "$(uname)" == "Darwin" ] && nulldev=3,2
155
156testing "pass /dev/null" \
157  "tar c --mtime @0 /dev/null 2>/dev/null | LST" \
158  "crw-rw-rw- $(stat -c %U/%G /dev/null) $nulldev 1970-01-01 00:00 dev/null\n" \
159  "" ""
160testing "--absolute-names" \
161  "tar c --mtime @0 --absolute-names /dev/null 2>/dev/null | LST" \
162  "crw-rw-rw- $(stat -c %U/%G /dev/null) $nulldev 1970-01-01 00:00 /dev/null\n"\
163  "" ""
164
165# compression types
166testing "autodetect gzip" 'LST -f "$FILES"/tar/tar.tgz' \
167  "drwxr-x--- enh/eng 0 2017-05-13 01:05 dir/\n-rw-r----- enh/eng 12 2017-05-13 01:05 dir/file\n" \
168  "" ""
169
170testing "manually specify bz2" 'LST -jf "$FILES"/tar/tar.tbz2' \
171  "drwxr-x--- enh/eng 0 2017-05-13 01:05 dir/\n-rw-r----- enh/eng 12 2017-05-13 01:05 dir/file\n" \
172  "" ""
173
174# -I
175testing "-I gzip c" "$TAR -Igzip file | file - | grep -o 'gzip compressed'" \
176  "gzip compressed\n" "" ""
177testing "-I gzip t" 'LST -Igzip -f "$FILES"/tar/tar.tgz' \
178  "drwxr-x--- enh/eng 0 2017-05-13 01:05 dir/\n-rw-r----- enh/eng 12 2017-05-13 01:05 dir/file\n" \
179  "" ""
180
181skipnot mknod -m 660 dir/char c 12 34 2>/dev/null && chgrp sys dir/char
182NOSPACE=1 testing "character special" "tar --mtime @0 -cf test.tar dir/char && rm -f dir/char && tar xf test.tar && ls -l --full-time dir/char" \
183  "crw-rw---- 1 root sys 12, 34 1970-01-01 00:00:00.000000000 +0000 dir/char\n"\
184  "" ""
185
186skipnot mknod -m 660 dir/block b 23 45 2>/dev/null && chgrp sys dir/block
187NOSPACE=1 testing "block special" "tar --mtime @0 -cf test.tar dir/block && rm -f dir/block && tar xf test.tar && ls -l --full-time dir/block" \
188  "brw-rw---- 1 root sys 23, 45 1970-01-01 00:00:00.000000000 +0000 dir/block\n"\
189  "" ""
190
191skipnot chown nobody:nogroup dir/file 2>/dev/null
192testing "ownership" "$TAR dir/file | SUM 3" \
193  "2d7b96c7025987215f5a41f10eaa84311160afdb\n" "" ""
194
195mkdir -p dd/sub/blah &&
196tar cf test.tar dd/sub/blah &&
197rm -rf dd/sub &&
198skipnot ln -s ../.. dd/sub
199toyonly testing "symlink out of cwd" \
200  "tar xf test.tar 2> /dev/null || echo yes ; [ ! -e dd/sub/blah ] && echo yes" \
201  "yes\nyes\n" "" ""
202
203# If not root can't preserve ownership, so don't try yet.
204
205testing "extract dir/file from tar" \
206  "tar xvCf dd $FILES/tar/tar.tar && stat -c '%A %Y %n' dd/dir dd/dir/file" \
207  "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
208  "" ""
209
210testing "extract dir/file from tgz (autodetect)" \
211  "tar xvCf dd $FILES/tar/tar.tgz && stat -c '%A %Y %n' dd/dir dd/dir/file" \
212  "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
213  "" ""
214
215toyonly testing "cat tgz | extract dir/file (autodetect)" \
216  "cat $FILES/tar/tar.tgz | tar xvC dd && stat -c '%A %Y %n' dd/dir dd/dir/file" \
217  "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
218  "" ""
219
220testing "extract dir/file from tbz2 (autodetect)" \
221  "tar xvCf dd $FILES/tar/tar.tbz2 && stat -c '%A %Y %n' dd/dir dd/dir/file" \
222  "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
223  "" ""
224
225toyonly testing "cat tbz | extract dir/file (autodetect)" \
226  "cat $FILES/tar/tar.tbz2 | tar xvC dd && stat -c '%A %Y %n' dd/dir dd/dir/file" \
227  "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
228  "" ""
229
230mkdir path && ln -s "$(which gzip)" "$(which tar)" path/ && [ -x path/gzip ] ||
231  ((++SKIP))
232toyonly testing "autodetect falls back to gzip -d when no zcat" \
233  "PATH=path; tar tf $FILES/tar/tar.tgz" "dir/\ndir/file\n" "" ""
234rm -rf path
235
236# TODO: run sparse tests on tmpfs mount? (Request filesystem type?)
237# Only run sparse tests if filesystem can handle sparse files @4k granularity
238dd if=/dev/zero bs=4k count=1 seek=1 of=blah.img 2>/dev/null
239[ $(du blah.img | sed 's/[ \t].*//') -ne 4 ] && SKIP=999
240rm -f blah.img
241[ "$(uname)" == "Darwin" ] && SKIP=999
242
243  yes | head -n $((1<<18)) > bang
244  {
245    dd bs=$((1<<16)) count=1 status=none
246    dd bs=8192 seek=14 count=1 status=none
247    dd bs=4096 seek=64 count=5 status=none
248  } < bang > fweep
249  testing "sparse without overflow" "$TAR --sparse fweep | SUM 3" \
250    "50dc56c3c7eed163f0f37c0cfc2562852a612ad0\n" "" ""
251  rm bang fweep
252
253  for i in 1 3 5 7 9 14 27 36 128 256 300 304
254  do
255    dd if=/dev/zero of=fweep bs=65536 seek=$i count=1 2>/dev/null
256  done
257  testing "sparse single overflow" "$TAR --sparse fweep | SUM 6" \
258    "81d59c3a7470201f92d60e63a43318ddde893f6d\n" "" ""
259  rm fweep
260
261  for i in $(seq 8 3 200)
262  do
263    dd if=/dev/zero of=fweep bs=65536 seek=$i count=1 2>/dev/null
264    dd if=/dev/zero of=fweep2 bs=65536 seek=$i count=1 2>/dev/null
265  done
266  truncate -s 20m fweep2
267  testing "sparse double overflow" "$TAR --sparse fweep | SUM 7" \
268    "024aacd955e45f89bafedb3f37c8d39b4d556471\n" "" ""
269
270  tar c --sparse fweep > fweep.tar
271  rm fweep
272  testing "sparse extract" "tar xf fweep.tar && $TAR --sparse fweep | SUM 4" \
273    "b949d3a3b4c6457c873f1ea9918fd9029c5ed4b3\n" "" ""
274  testing "sparse tvf" \
275    "tar tvf fweep.tar | grep -wq 13172736 && echo right size" "right size\n" \
276    "" ""
277  rm fweep fweep.tar
278
279  tar c --sparse fweep2 > fweep2.tar
280  rm fweep2
281  testing "sparse extract hole at end" \
282    "tar xf fweep2.tar && $TAR --sparse fweep2 | SUM 4" \
283    "807664bcad0e827793318ff742991d6f006b2127\n" "" ""
284  rm fweep2 fweep2.tar
285
286  testcmd 'extract obsolete sparse format' \
287    'xf "$FILES"/tar/oldsparse.tgz && sha1sum hello-sparse.c | head -c 12' \
288    '9714dc7ac8c0' '' ''
289  rm -f hello-sparse.c
290
291SKIP=0 # End of sparse tests
292
293mkdir -p links
294touch links/orig
295ln links/{orig,link1}
296ln links/{orig,link2}
297testcmd 'links' '-cf test.tar links' '' '' ''
298rm -rf links
299
300mkdir links
301for i in {0..12}; do touch links/orig$i; ln links/{orig,link}$i; done
302testcmd 'links2' '-cf test.tar links' '' '' ''
303rm -rf links
304
305install -m 000 -d folder/skip/oof &&
306testcmd 'exclude' '--exclude skip -cvf tar.tar folder && echo yes' \
307  'folder/\nyes\n' '' ''
308rm -rf folder tar.tar
309
310mkdir -p one/two; echo hello > one/two/three; tar czf test.tar one/two/three
311rm one/two/three; mkdir one/two/three
312testcmd 'replace dir with file' '-xf test.tar && cat one/two/three' \
313  'hello\n' '' ''
314rm -rf one test.tar
315
316mkdir ..dotsdir
317testing "create ..dotsdir" "$TAR ..dotsdir | SUM 3" \
318  "62ff23c9b427020331992b9bc71f082099c1411f\n" "" ""
319
320testing "pass ..dotsdir" "$TAR ..dotsdir | LST" \
321  "drwxrwxr-x root/sys 0 2009-02-13 23:31 ..dotsdir/\n" "" ""
322rmdir ..dotsdir
323
324mkdir -p one/two/three/four/five
325touch one/two/three/four/five/six
326testing "--strip" "$TAR one | tar t --strip=2 --show-transformed | grep six" \
327  "three/four/five/six\n" "" ""
328
329# toybox tar --xform depends on toybox sed
330[ -z "$TEST_HOST" ] && ! sed --tarxform '' </dev/null 2>/dev/null && SKIP=99
331
332mkdir uno
333ln -s tres uno/dos
334touch uno/tres
335ln uno/tres uno/quatro
336LL() { LST --show-transformed-names $XX | sed 's/^.* 23:31 //'; }
337TT() { $TAR --no-recursion uno uno/{dos,tres,quatro} "$@" | LL; }
338testing 'xform S' \
339  "TT --xform 's/uno/one/S;s/dos/two/S;s/tres/three/S;s/quatro/four/S'" \
340  "one/\none/two -> tres\none/three\none/four link to one/three\n" "" ""
341
342testing 'xform flags=rh starts with all disabled' \
343  "TT --xform 's/uno/one/;flags=rh;s/dos/two/;s/tres/three/;s/quatro/four/'" \
344  "one/\none/two -> tres\none/three\none/four link to one/three\n" "" ""
345
346testing 'xform flags=rHhsS toggles' \
347  "TT --xform 's/uno/one/;flags=rHhsS;s/dos/two/;s/tres/three/;s/quatro/four/'"\
348  "one/\none/two -> tres\none/three\none/four link to one/three\n" "" ""
349
350testing 'xform flags= is not a delta from previous' \
351  "TT --xform 'flags=s;flags=rh;s/uno/one/;s/dos/two/;s/tres/three/;s/quatro/four/'" \
352  "one/\none/two -> tres\none/three\none/four link to one/three\n" "" ""
353
354testing 'xform H' \
355  "TT --xform 'flags=rsH;s/uno/one/;s/dos/two/;s/tres/three/;s/quatro/four/'" \
356  "one/\none/two -> three\none/three\none/four link to uno/tres\n" "" ""
357
358testing 'xform R' \
359  "TT --xform 'flags=rshR;s/uno/one/;s/dos/two/;s/tres/three/;s/quatro/four/'" \
360  "uno/\nuno/dos -> three\nuno/tres\nuno/quatro link to one/three\n" "" ""
361
362testing "xform path" "$TAR one --xform=s@three/four/@zero@ | tar t | grep six" \
363  "one/two/zerofive/six\n" "" ""
364
365testing "xform trailing slash special case" \
366  "$TAR --xform 's#^.+/##x' one/two/three/four/five | tar t" 'five/\nsix\n' '' ''
367
368# The quoting works because default IFS splits on whitepace not ;
369testing "xform extract all" \
370  "XX='--xform s/uno/one/;s/dos/two/;s/tres/three/;s/quatro/four/' TT" \
371  'one/\none/two -> three\none/three\none/four link to one/three\n' '' ''
372
373testing 'xform extract S' \
374  "XX='--xform s/uno/one/S;s/dos/two/S;s/tres/three/S;s/quatro/four/S' TT" \
375  "one/\none/two -> tres\none/three\none/four link to one/three\n" "" ""
376
377testing 'xform extract H' \
378  "XX='--xform flags=rs;s/uno/one/;s/dos/two/;s/tres/three/;s/quatro/four/' TT"\
379  "one/\none/two -> three\none/three\none/four link to uno/tres\n" "" ""
380
381testing 'xform extract R' \
382  "XX='--xform flags=sh;s/uno/one/;s/dos/two/;s/tres/three/;s/quatro/four/' TT"\
383  "uno/\nuno/dos -> three\nuno/tres\nuno/quatro link to one/three\n" "" ""
384
385rm -rf uno
386SKIP=0
387rm -rf one
388
389testing '-P' "$TAR -P --no-recursion -C / /// .. | SUM 3" \
390  "a3e94211582da121845d823374d8f41ead62d7bd\n" "" ""
391
392testing 'without -P' "$TAR --no-recursion -C / /// .. 2>/dev/null | SUM 3" \
393  "077d03243e247b074806904885e6da272fd5857a\n" "" ""
394
395# Wildcards: --exclude, include (create/extract * cmdline/recursive)
396# --anchored, --wildcards, --wildcards-match-slash
397# --no-* versions of each. Span coverage, switching on/off...
398
399#pattern a.c
400#  abcd dabc a/c da/c
401#  top/*
402
403mkdir sub && cd sub && mkdir -p a da top/a top/da &&
404touch abcd dabc a/c da/c top/abcd top/dabc top/a/c top/da/c &&
405$TAR -f ../sub.tar abcd dabc a da top && cd .. || exit 1
406
407# TODO I have not made wildcard state changes positional.
408
409testing 'wildcards do not affect creation cmdline args' \
410  '$TAR -C sub --wildcards a.cd abcd dabc a da top 2>/dev/null | cmp - sub.tar' \
411  '' '' ''
412
413testing 'creation --exclude --no-wildcards'\
414  '$TAR -C sub --no-wildcards --exclude=d?bc abcd dabc | LL' \
415  'abcd\ndabc\n' '' ''
416
417
418testing 'creation --wildcards --exclude'\
419  '$TAR -C sub --wildcards --exclude=d?bc abcd dabc | LL' \
420  'abcd\n' '' ''
421
422# TODO: do we need to set DIRTREE_BREADTH at top level? Come up with test if so.
423mkdir sub2
424touch sub2/{ephebe,klatch,djelibeybi}
425testing 'tsort' '$TAR -c sub2 --sort=name | tar t' \
426  'sub2/\nsub2/djelibeybi\nsub2/ephebe\nsub2/klatch\n' '' ''
427
428touch file
429testing './file bug' 'tar c ./file > tar.tar && tar t ./file < tar.tar' \
430  './file\n' '' ''
431
432skipnot [ $(id -u) -ne 0 ]  # Root defaults to -p
433testing 'honor umask' \
434  'umask 0022 && rm -rf dir && mkdir dir && tar xf $FILES/tar/dir.tar && stat -c%A dir dir/file' \
435  'drwxr-xr-x\n-rwxr-xr-x\n' '' ''
436testing 'extract changes directory permissions' \
437  'umask 0022 && rm -rf dir && mkdir dir && umask 0 && tar xf $FILES/tar/dir.tar && stat -c%A dir dir/file' \
438  'drwxrwxrwx\n-rwxrwxrwx\n' '' ''
439testing '-p overrides umask' \
440  'umask 0022 && rm -rf dir && mkdir dir && tar xpf $FILES/tar/dir.tar && stat -c%A dir dir/file' \
441  'drwxrwxrwx\n-rwxrwxrwx\n' '' ''
442
443if false
444then
445# Sequencing issues that leak implementation details out the interface
446testing "what order are --xform, --strip, and --exclude processed in?"
447testing "--xform vs ../ removal and adding / to dirs"
448
449chmod 700 dir
450tar cpf tar.tgz dir/file
451#chmod 700 dir
452#tar xpf file
453#ls -ld dir/file
454
455# restore ownership of file, dir, and symlink
456
457# merge add_to_tar and write_longname,
458# filter, incl or excl and anchored/wildcards
459
460# extract file not under cwd
461# exclusion defaults to --no-anchored and --wildcards-match-slash
462#  both incl and excl
463
464# catch symlink overwrite
465# add dir with no trailing slash
466# don't allow hardlink target outside cwd
467# extract dir/file without dir in tarball
468# create with and without each flag
469# --owner --group --numeric-owner
470# extract with and without each flag
471# --owner 0 --group 0
472# set symlink owner
473# >256 hardlink inodes
474#   // remove leading / and any .. entries from saved name
475#  // exclusion defaults to --no-anchored and --wildcards-match-slash
476# //bork blah../thing blah/../thing blah/../and/../that blah/.. ../blah
477# tar tv --owner --group --mtime
478# extract file within dir date correct
479# name ending in /.. or just ".." as a name
480
481
482fi
483
484rm -f save.dat
485