~stewart/percona-xtrabackup/bug1213036

« back to all changes in this revision

Viewing changes to src/libarchive/libarchive/test/test_read_format_tar.c

  • Committer: Alexey Kopytov
  • Date: 2012-02-10 20:05:56 UTC
  • mto: (391.1.5 staging)
  • mto: This revision was merged to the branch mainline in revision 390.
  • Revision ID: akopytov@gmail.com-20120210200556-6kx41z8wwrqfucro
Rebase of the parallel compression patch on new trunk + post-review
fixes.

Implementation of parallel compression and streaming for XtraBackup.

This revision implements the following changes:

* InnoDB files are now streamed by the xtrabackup binary rather than
innobackupex. As a result, integrity is now verified by xtrabackup and
thus tar4ibd is no longer needed, so it was removed.

* xtrabackup binary now accepts the new '--stream' option which has
exactly the same semantics as the '--stream' option in
innobackupex: it tells xtrabackup to stream all files to the standard
output in the specified format rather than storing them locally.

* The xtrabackup binary can now do parallel compression using the
quicklz library. Two new options were added to xtrabackup to support
this feature:

- '--compress' tells xtrabackup to compress all output data, including
the transaction log file and meta data files, using the specified
compression algorithm. The only currently supported algorithm is
'quicklz'. The resulting files have the qpress archive format,
i.e. every *.qp file produced by xtrabackup is essentially a one-file
qpress archive and can be extracted and uncompressed by the qpress
file archiver (http://www.quicklz.com/).

- '--compress-threads' specifies the number of worker threads used by
xtrabackup for parallel data compression. This option defaults to 1.

Parallel compression ('--compress-threads') can be used together with
parallel file copying ('--parallel'). For example, '--parallel=4
--compress --compress-threads=2' will create 4 IO threads that will
read the data and pipe it to 2 compression threads.

* To support simultaneous compression and streaming, a new custom
streaming format called 'xbstream' was introduced to XtraBackup in
addition to the 'tar' format. That was required to overcome some
limitations of traditional archive formats such as 'tar', 'cpio' and
others that do not allow streaming dynamically generated files, for
example dynamically compressed files.  Other advantages of xbstream over
traditional streaming/archive formats include ability to stream multiple
files concurrently (so it is possible to use streaming in the xbstream
format together with the --parallel option) and more compact data
storage.

* To allow streaming and extracting files to/from the xbstream format
produced by xtrabackup, a new utility aptly called 'xbstream' was
added to the XtraBackup distribution. This utility has a tar-like
interface:

- with the '-x' option it extracts files from the stream read from its
standard input to the current directory unless specified otherwise
with the '-C' option.

- with the '-c' option it streams files specified on the command line
to its standard output.

The utility also tries to minimize its impact on the OS page cache by
using the appropriate posix_fadvise() calls when available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_tar.c 201247 2009-12-30 05:59:21Z kientzle $");
 
27
 
 
28
/*
 
29
 * Each of these archives is a short archive with a single entry.  The
 
30
 * corresponding verify function verifies the entry structure returned
 
31
 * from libarchive is what it should be.  The support functions pad with
 
32
 * lots of zeros, so we can trim trailing zero bytes from each hardcoded
 
33
 * archive to save space.
 
34
 *
 
35
 * The naming here follows the tar file type flags.  E.g. '1' is a hardlink,
 
36
 * '2' is a symlink, '5' is a dir, etc.
 
37
 */
 
38
 
 
39
/* Empty archive. */
 
40
static unsigned char archiveEmpty[] = {
 
41
        /* 512 zero bytes */
 
42
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
43
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
44
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
45
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
46
 
 
47
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
48
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
49
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
50
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
51
 
 
52
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
53
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
54
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
55
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
56
 
 
57
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
58
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
59
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
 
60
        0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
 
61
};
 
62
 
 
63
static void verifyEmpty(void)
 
64
{
 
65
        struct archive_entry *ae;
 
66
        struct archive *a;
 
67
 
 
68
        assert((a = archive_read_new()) != NULL);
 
69
        assertA(0 == archive_read_support_compression_all(a));
 
70
        assertA(0 == archive_read_support_format_all(a));
 
71
        assertA(0 == archive_read_open_memory(a, archiveEmpty, 512));
 
72
        assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
 
73
        assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
 
74
        assertEqualString(archive_compression_name(a), "none");
 
75
        failure("512 zero bytes should be recognized as a tar archive.");
 
76
        assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);
 
77
 
 
78
        assert(0 == archive_read_close(a));
 
79
#if ARCHIVE_VERSION_NUMBER < 2000000
 
80
        archive_read_finish(a);
 
81
#else
 
82
        assert(0 == archive_read_finish(a));
 
83
#endif
 
84
}
 
85
 
 
86
/* Single entry with a hardlink. */
 
87
static unsigned char archive1[] = {
 
88
'h','a','r','d','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
89
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
90
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
 
91
'0','6','4','4',' ',0,'0','0','1','7','5','0',' ',0,'0','0','1','7','5','0',
 
92
' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4','6',
 
93
'0','5','2','6','6','2',' ','0','1','3','0','5','7',0,' ','1','f','i','l',
 
94
'e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
95
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
96
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,'0',
 
97
'0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
98
't','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0',
 
99
'0','0','0','0','0',' ',0,'0','0','0','0','0','0',' '};
 
100
 
 
101
static void verify1(struct archive_entry *ae)
 
102
{
 
103
        /* A hardlink is not a symlink. */
 
104
        assert(archive_entry_filetype(ae) != AE_IFLNK);
 
105
        /* Nor is it a directory. */
 
106
        assert(archive_entry_filetype(ae) != AE_IFDIR);
 
107
        assertEqualInt(archive_entry_mode(ae) & 0777, 0644);
 
108
        assertEqualInt(archive_entry_uid(ae), 1000);
 
109
        assertEqualInt(archive_entry_gid(ae), 1000);
 
110
        assertEqualString(archive_entry_uname(ae), "tim");
 
111
        assertEqualString(archive_entry_gname(ae), "tim");
 
112
        assertEqualString(archive_entry_pathname(ae), "hardlink");
 
113
        assertEqualString(archive_entry_hardlink(ae), "file");
 
114
        assert(archive_entry_symlink(ae) == NULL);
 
115
        assertEqualInt(archive_entry_mtime(ae), 1184388530);
 
116
}
 
117
 
 
118
/* Verify that symlinks are read correctly. */
 
119
static unsigned char archive2[] = {
 
120
's','y','m','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
121
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
122
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
 
123
'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
 
124
'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
 
125
'6','0','5','4','1','0','1',' ','0','0','1','3','3','2','3',' ','2','f','i',
 
126
'l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
127
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
128
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
 
129
'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
130
0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
131
'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
 
132
 
 
133
static void verify2(struct archive_entry *ae)
 
134
{
 
135
        assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
 
136
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
137
        assertEqualInt(archive_entry_uid(ae), 1000);
 
138
        assertEqualInt(archive_entry_gid(ae), 1000);
 
139
        assertEqualString(archive_entry_uname(ae), "tim");
 
140
        assertEqualString(archive_entry_gname(ae), "tim");
 
141
        assertEqualString(archive_entry_pathname(ae), "symlink");
 
142
        assertEqualString(archive_entry_symlink(ae), "file");
 
143
        assert(archive_entry_hardlink(ae) == NULL);
 
144
        assertEqualInt(archive_entry_mtime(ae), 1184389185);
 
145
}
 
146
 
 
147
/* Character device node. */
 
148
static unsigned char archive3[] = {
 
149
'd','e','v','c','h','a','r',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
150
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
151
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
 
152
'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
 
153
'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
 
154
'6','0','5','4','1','0','1',' ','0','0','1','2','4','1','2',' ','3',0,0,
 
155
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
156
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
157
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
 
158
'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
159
0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
160
'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
 
161
 
 
162
static void verify3(struct archive_entry *ae)
 
163
{
 
164
        assertEqualInt(archive_entry_filetype(ae), AE_IFCHR);
 
165
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
166
        assertEqualInt(archive_entry_uid(ae), 1000);
 
167
        assertEqualInt(archive_entry_gid(ae), 1000);
 
168
        assertEqualString(archive_entry_uname(ae), "tim");
 
169
        assertEqualString(archive_entry_gname(ae), "tim");
 
170
        assertEqualString(archive_entry_pathname(ae), "devchar");
 
171
        assert(archive_entry_symlink(ae) == NULL);
 
172
        assert(archive_entry_hardlink(ae) == NULL);
 
173
        assertEqualInt(archive_entry_mtime(ae), 1184389185);
 
174
}
 
175
 
 
176
/* Block device node. */
 
177
static unsigned char archive4[] = {
 
178
'd','e','v','b','l','o','c','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
179
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
180
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
 
181
'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
 
182
'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
 
183
'6','0','5','4','1','0','1',' ','0','0','1','2','5','7','0',' ','4',0,0,
 
184
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
185
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
186
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
 
187
'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
188
0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
189
'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
 
190
 
 
191
static void verify4(struct archive_entry *ae)
 
192
{
 
193
        assertEqualInt(archive_entry_filetype(ae), AE_IFBLK);
 
194
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
195
        assertEqualInt(archive_entry_uid(ae), 1000);
 
196
        assertEqualInt(archive_entry_gid(ae), 1000);
 
197
        assertEqualString(archive_entry_uname(ae), "tim");
 
198
        assertEqualString(archive_entry_gname(ae), "tim");
 
199
        assertEqualString(archive_entry_pathname(ae), "devblock");
 
200
        assert(archive_entry_symlink(ae) == NULL);
 
201
        assert(archive_entry_hardlink(ae) == NULL);
 
202
        assertEqualInt(archive_entry_mtime(ae), 1184389185);
 
203
}
 
204
 
 
205
/* Directory. */
 
206
static unsigned char archive5[] = {
 
207
'.',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
208
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
209
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0',
 
210
'7','5','5',' ',0,'0','0','1','7','5','0',' ',0,'0','0','1','7','5','0',
 
211
' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','1','0','3','3',
 
212
'4','0','4','1','7','3','6',' ','0','1','0','5','6','1',0,' ','5',0,0,0,
 
213
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
214
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
215
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
 
216
'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
217
0,0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
218
0,0,'0','0','0','0','0','0',' ',0,'0','0','0','0','0','0',' '};
 
219
 
 
220
static void verify5(struct archive_entry *ae)
 
221
{
 
222
        assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
 
223
        assertEqualInt(archive_entry_mtime(ae), 1131430878);
 
224
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
225
        assertEqualInt(archive_entry_uid(ae), 1000);
 
226
        assertEqualInt(archive_entry_gid(ae), 1000);
 
227
        assertEqualString(archive_entry_uname(ae), "tim");
 
228
        assertEqualString(archive_entry_gname(ae), "tim");
 
229
}
 
230
 
 
231
/* fifo */
 
232
static unsigned char archive6[] = {
 
233
'f','i','f','o',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
234
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
235
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
 
236
'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
 
237
'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
 
238
'6','0','5','4','1','0','1',' ','0','0','1','1','7','2','4',' ','6',0,0,
 
239
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
240
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
241
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
 
242
'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
243
0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
244
'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
 
245
 
 
246
static void verify6(struct archive_entry *ae)
 
247
{
 
248
        assertEqualInt(archive_entry_filetype(ae), AE_IFIFO);
 
249
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
250
        assertEqualInt(archive_entry_uid(ae), 1000);
 
251
        assertEqualInt(archive_entry_gid(ae), 1000);
 
252
        assertEqualString(archive_entry_uname(ae), "tim");
 
253
        assertEqualString(archive_entry_gname(ae), "tim");
 
254
        assertEqualString(archive_entry_pathname(ae), "fifo");
 
255
        assert(archive_entry_symlink(ae) == NULL);
 
256
        assert(archive_entry_hardlink(ae) == NULL);
 
257
        assertEqualInt(archive_entry_mtime(ae), 1184389185);
 
258
}
 
259
 
 
260
/* GNU long link name */
 
261
static unsigned char archiveK[] = {
 
262
'.','/','.','/','@','L','o','n','g','L','i','n','k',0,0,0,0,0,0,0,0,0,0,0,
 
263
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
264
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
265
0,0,'0','0','0','0','0','0','0',0,'0','0','0','0','0','0','0',0,'0','0','0',
 
266
'0','0','0','0',0,'0','0','0','0','0','0','0','0','6','6','6',0,'0','0','0',
 
267
'0','0','0','0','0','0','0','0',0,'0','1','1','7','1','5',0,' ','K',0,0,0,
 
268
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
269
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
270
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',' ',' ',
 
271
0,'r','o','o','t',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
272
'w','h','e','e','l',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
273
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
274
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
275
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
276
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
277
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'t',
 
278
'h','i','s','_','i','s','_','a','_','v','e','r','y','_','l','o','n','g','_',
 
279
's','y','m','l','i','n','k','_','b','o','d','y','_','a','b','c','d','e','f',
 
280
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y',
 
281
'z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
 
282
'r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i',
 
283
'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a',
 
284
'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t',
 
285
'u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l',
 
286
'm','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d',
 
287
'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
 
288
'x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
 
289
'p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g',
 
290
'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
 
291
'_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
 
292
's','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j',
 
293
'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b',
 
294
'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
 
295
'v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m',
 
296
'n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e',
 
297
'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x',
 
298
'y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
 
299
'q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h',
 
300
'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',0,
 
301
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
302
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
303
's','y','m','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
304
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
305
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','1',
 
306
'2','0','7','5','5',0,'0','0','0','1','7','5','0',0,'0','0','0','1','7','5',
 
307
'0',0,'0','0','0','0','0','0','0','0','0','0','0',0,'1','0','6','4','6','0',
 
308
'5','6','7','7','0',0,'0','3','5','4','4','7',0,' ','2','t','h','i','s','_',
 
309
'i','s','_','a','_','v','e','r','y','_','l','o','n','g','_','s','y','m','l',
 
310
'i','n','k','_','b','o','d','y','_','a','b','c','d','e','f','g','h','i','j',
 
311
'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b',
 
312
'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
 
313
'v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l',0,
 
314
'u','s','t','a','r',' ',' ',0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
315
0,0,0,0,0,0,0,0,0,0,0,0,0,'t','i','m'};
 
316
 
 
317
static void verifyK(struct archive_entry *ae)
 
318
{
 
319
        assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
 
320
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
321
        assertEqualInt(archive_entry_uid(ae), 1000);
 
322
        assertEqualInt(archive_entry_gid(ae), 1000);
 
323
        assertEqualString(archive_entry_uname(ae), "tim");
 
324
        assertEqualString(archive_entry_gname(ae), "tim");
 
325
        assertEqualString(archive_entry_pathname(ae), "symlink");
 
326
        assertEqualString(archive_entry_symlink(ae),
 
327
            "this_is_a_very_long_symlink_body_abcdefghijklmnopqrstuvwxyz_"
 
328
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
329
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
330
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
331
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
332
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
333
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
334
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz");
 
335
        assert(archive_entry_hardlink(ae) == NULL);
 
336
        assertEqualInt(archive_entry_mtime(ae), 1184390648);
 
337
}
 
338
 
 
339
/* TODO: GNU long name */
 
340
 
 
341
/* TODO: Solaris ACL */
 
342
 
 
343
/* Pax extended long link name */
 
344
static unsigned char archivexL[] = {
 
345
'.','/','P','a','x','H','e','a','d','e','r','s','.','8','6','9','7','5','/',
 
346
's','y','m','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
347
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
348
0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0','0','6','4','4',0,'0','0','0','1',
 
349
'7','5','0',0,'0','0','0','1','7','5','0',0,'0','0','0','0','0','0','0','0',
 
350
'7','5','3',0,'1','0','6','4','6','0','5','7','6','1','1',0,'0','1','3','7',
 
351
'1','4',0,' ','x',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
352
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
353
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u',
 
354
's','t','a','r',0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
355
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
356
0,0,0,'0','0','0','0','0','0','0',0,'0','0','0','0','0','0','0',0,0,0,0,0,
 
357
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
358
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
359
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
360
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
361
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'4','5','1',' ','l','i','n','k','p','a','t',
 
362
'h','=','t','h','i','s','_','i','s','_','a','_','v','e','r','y','_','l','o',
 
363
'n','g','_','s','y','m','l','i','n','k','_','b','o','d','y','_','a','b','c',
 
364
'd','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
 
365
'w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
 
366
'o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f',
 
367
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y',
 
368
'z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
 
369
'r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i',
 
370
'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a',
 
371
'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t',
 
372
'u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l',
 
373
'm','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d',
 
374
'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
 
375
'x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
 
376
'p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g',
 
377
'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
 
378
'_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
 
379
's','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j',
 
380
'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b',
 
381
'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
 
382
'v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m',
 
383
'n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e',
 
384
'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x',
 
385
'y','z',10,'2','0',' ','a','t','i','m','e','=','1','1','8','4','3','9','1',
 
386
'0','2','5',10,'2','0',' ','c','t','i','m','e','=','1','1','8','4','3','9',
 
387
'0','6','4','8',10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'s','y','m',
 
388
'l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
389
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
390
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0','0','7',
 
391
'5','5',0,'0','0','0','1','7','5','0',0,'0','0','0','1','7','5','0',0,'0',
 
392
'0','0','0','0','0','0','0','0','0','0',0,'1','0','6','4','6','0','5','6',
 
393
'7','7','0',0,'0','3','7','1','2','1',0,' ','2','t','h','i','s','_','i','s',
 
394
'_','a','_','v','e','r','y','_','l','o','n','g','_','s','y','m','l','i','n',
 
395
'k','_','b','o','d','y','_','a','b','c','d','e','f','g','h','i','j','k','l',
 
396
'm','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d',
 
397
'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
 
398
'x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','u','s',
 
399
't','a','r',0,'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
400
0,0,0,0,0,0,0,0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 
401
0,0,0,0,0,0,0,'0','0','0','0','0','0','0',0,'0','0','0','0','0','0','0'};
 
402
 
 
403
static void verifyxL(struct archive_entry *ae)
 
404
{
 
405
        assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
 
406
        assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
 
407
        assertEqualInt(archive_entry_uid(ae), 1000);
 
408
        assertEqualInt(archive_entry_gid(ae), 1000);
 
409
        assertEqualString(archive_entry_uname(ae), "tim");
 
410
        assertEqualString(archive_entry_gname(ae), "tim");
 
411
        assertEqualString(archive_entry_pathname(ae), "symlink");
 
412
        assertEqualString(archive_entry_symlink(ae),
 
413
            "this_is_a_very_long_symlink_body_abcdefghijklmnopqrstuvwxyz_"
 
414
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
415
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
416
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
417
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
418
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
419
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
 
420
            "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz");
 
421
        assert(archive_entry_hardlink(ae) == NULL);
 
422
        assertEqualInt(archive_entry_mtime(ae), 1184390648);
 
423
}
 
424
 
 
425
 
 
426
/* TODO: Any other types of headers? */
 
427
 
 
428
static void verify(unsigned char *d, size_t s,
 
429
    void (*f)(struct archive_entry *),
 
430
    int compression, int format)
 
431
{
 
432
        struct archive_entry *ae;
 
433
        struct archive *a;
 
434
        unsigned char *buff = malloc(100000);
 
435
 
 
436
        memcpy(buff, d, s);
 
437
        memset(buff + s, 0, 2048);
 
438
 
 
439
        assert((a = archive_read_new()) != NULL);
 
440
        assertA(0 == archive_read_support_compression_all(a));
 
441
        assertA(0 == archive_read_support_format_all(a));
 
442
        assertA(0 == archive_read_open_memory(a, buff, s + 1024));
 
443
        assertA(0 == archive_read_next_header(a, &ae));
 
444
        assertEqualInt(archive_compression(a), compression);
 
445
        assertEqualInt(archive_format(a), format);
 
446
 
 
447
        /* Verify the only entry. */
 
448
        f(ae);
 
449
 
 
450
        assert(0 == archive_read_close(a));
 
451
#if ARCHIVE_VERSION_NUMBER < 2000000
 
452
        archive_read_finish(a);
 
453
#else
 
454
        assert(0 == archive_read_finish(a));
 
455
#endif
 
456
        free(buff);
 
457
}
 
458
 
 
459
DEFINE_TEST(test_read_format_tar)
 
460
{
 
461
        verifyEmpty();
 
462
        verify(archive1, sizeof(archive1), verify1,
 
463
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_USTAR);
 
464
        verify(archive2, sizeof(archive2), verify2,
 
465
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_USTAR);
 
466
        verify(archive3, sizeof(archive3), verify3,
 
467
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_USTAR);
 
468
        verify(archive4, sizeof(archive4), verify4,
 
469
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_USTAR);
 
470
        verify(archive5, sizeof(archive5), verify5,
 
471
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_USTAR);
 
472
        verify(archive6, sizeof(archive6), verify6,
 
473
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_USTAR);
 
474
        verify(archiveK, sizeof(archiveK), verifyK,
 
475
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_GNUTAR);
 
476
        verify(archivexL, sizeof(archivexL), verifyxL,
 
477
            ARCHIVE_COMPRESSION_NONE, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
 
478
}
 
479
 
 
480