1/*-
2 * Copyright (c) 2003-2007 Tim Kientzle
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25#include "test.h"
26
27static const char *
28make_files(void)
29{
30	FILE *f;
31
32	/* File with 10 bytes content. */
33	f = fopen("file", "wb");
34	assert(f != NULL);
35	assertEqualInt(10, fwrite("123456789", 1, 10, f));
36	fclose(f);
37
38	/* hardlink to above file. */
39	assertMakeHardlink("linkfile", "file");
40	assertIsHardlink("file", "linkfile");
41
42	/* Symlink to above file. */
43	if (canSymlink())
44		assertMakeSymlink("symlink", "file", 0);
45
46	/* Directory. */
47	assertMakeDir("dir", 0775);
48
49	return canSymlink()
50	    ? "file linkfile symlink dir"
51	    : "file linkfile dir";
52}
53
54static void
55verify_files(const char *target)
56{
57	assertChdir(target);
58
59	/* Regular file with 2 links. */
60	failure("%s", target);
61	assertIsReg("file", -1);
62	failure("%s", target);
63	assertFileSize("file", 10);
64	failure("%s", target);
65	assertFileContents("123456789", 10, "file");
66	failure("%s", target);
67	assertFileNLinks("file", 2);
68
69	/* Another name for the same file. */
70	failure("%s", target);
71	assertIsReg("linkfile", -1);
72	failure("%s", target);
73	assertFileSize("linkfile", 10);
74	assertFileContents("123456789", 10, "linkfile");
75	assertFileNLinks("linkfile", 2);
76	assertIsHardlink("file", "linkfile");
77
78	/* Symlink */
79	if (canSymlink())
80		assertIsSymlink("symlink", "file", 0);
81
82	/* dir */
83	failure("%s", target);
84	assertIsDir("dir", 0775);
85	assertChdir("..");
86}
87
88static void
89run_tar(const char *target, const char *pack_options,
90    const char *unpack_options, const char *flist)
91{
92	int r;
93
94	assertMakeDir(target, 0775);
95
96	/* Use the tar program to create an archive. */
97	r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target);
98	failure("Error invoking %s cf -%s", testprog, pack_options);
99	assertEqualInt(r, 0);
100
101	assertChdir(target);
102
103	/* Verify that nothing went to stderr. */
104	assertEmptyFile("pack.err");
105
106	/*
107	 * Use tar to unpack the archive into another directory.
108	 */
109	r = systemf("%s xf archive %s >unpack.out 2>unpack.err",
110	    testprog, unpack_options);
111	failure("Error invoking %s xf archive %s", testprog, unpack_options);
112	assertEqualInt(r, 0);
113
114	/* Verify that nothing went to stderr. */
115	assertEmptyFile("unpack.err");
116	assertChdir("..");
117}
118
119DEFINE_TEST(test_basic)
120{
121	const char *flist;
122
123	assertUmask(0);
124	flist = make_files();
125	/* Archive/dearchive with a variety of options. */
126	run_tar("copy", "", "", flist);
127	verify_files("copy");
128
129	run_tar("copy_ustar", "--format=ustar", "", flist);
130	verify_files("copy_ustar");
131
132	/* tar doesn't handle cpio symlinks correctly */
133	/* run_tar("copy_odc", "--format=odc", ""); */
134}
135