~sergei.glushchenko/+junk/page-scan-hack

« back to all changes in this revision

Viewing changes to src/libarchive/cpio/test/test_format_newc.c

merge parallel compression branch.

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: src/usr.bin/cpio/test/test_format_newc.c,v 1.2 2008/08/22 02:09:10 kientzle Exp $");
 
27
 
 
28
/* Number of bytes needed to pad 'n' to multiple of 'block', assuming
 
29
 * that 'block' is a power of two. This trick can be more easily
 
30
 * remembered as -n & (block - 1), but many compilers quite reasonably
 
31
 * warn about "-n" when n is an unsigned value.  (~(n) + 1) is the
 
32
 * same thing, but written in a way that won't offend anyone. */
 
33
#define PAD(n, block)  ((~(n) + 1) & ((block) - 1))
 
34
 
 
35
static int
 
36
is_hex(const char *p, size_t l)
 
37
{
 
38
        while (l > 0) {
 
39
                if ((*p >= '0' && *p <= '9')
 
40
                    || (*p >= 'a' && *p <= 'f')
 
41
                    || (*p >= 'A' && *p <= 'F'))
 
42
                {
 
43
                        --l;
 
44
                        ++p;
 
45
                } else
 
46
                        return (0);
 
47
 
 
48
        }
 
49
        return (1);
 
50
}
 
51
 
 
52
static int
 
53
from_hex(const char *p, size_t l)
 
54
{
 
55
        int r = 0;
 
56
 
 
57
        while (l > 0) {
 
58
                r *= 16;
 
59
                if (*p >= 'a' && *p <= 'f')
 
60
                        r += *p + 10 - 'a';
 
61
                else if (*p >= 'A' && *p <= 'F')
 
62
                        r += *p + 10 - 'A';
 
63
                else
 
64
                        r += *p - '0';
 
65
                --l;
 
66
                ++p;
 
67
        }
 
68
        return (r);
 
69
}
 
70
 
 
71
DEFINE_TEST(test_format_newc)
 
72
{
 
73
        FILE *list;
 
74
        int r;
 
75
        int devmajor, devminor, ino, gid;
 
76
        int uid = -1;
 
77
        time_t t, t2, now;
 
78
        char *p, *e;
 
79
        size_t s, fs, ns;
 
80
 
 
81
        assertUmask(0);
 
82
 
 
83
#if !defined(_WIN32)
 
84
        uid = getuid();
 
85
#endif
 
86
 
 
87
        /*
 
88
         * Create an assortment of files.
 
89
         * TODO: Extend this to cover more filetypes.
 
90
         */
 
91
        list = fopen("list", "w");
 
92
 
 
93
        /* "file1" */
 
94
        assertMakeFile("file1", 0644, "1234567890");
 
95
        fprintf(list, "file1\n");
 
96
 
 
97
        /* "hardlink" */
 
98
        assertMakeHardlink("hardlink", "file1");
 
99
        fprintf(list, "hardlink\n");
 
100
 
 
101
        /* Another hardlink, but this one won't be archived. */
 
102
        assertMakeHardlink("hardlink2", "file1");
 
103
 
 
104
        /* "symlink" */
 
105
        if (canSymlink()) {
 
106
                assertMakeSymlink("symlink", "file1");
 
107
                fprintf(list, "symlink\n");
 
108
        }
 
109
 
 
110
        /* "dir" */
 
111
        assertMakeDir("dir", 0775);
 
112
        fprintf(list, "dir\n");
 
113
 
 
114
        /* Record some facts about what we just created: */
 
115
        now = time(NULL); /* They were all created w/in last two seconds. */
 
116
 
 
117
        /* Use the cpio program to create an archive. */
 
118
        fclose(list);
 
119
        r = systemf("%s -o --format=newc <list >newc.out 2>newc.err",
 
120
            testprog);
 
121
        if (!assertEqualInt(r, 0))
 
122
                return;
 
123
 
 
124
        /* Verify that nothing went to stderr. */
 
125
        if (canSymlink()) {
 
126
                assertTextFileContents("2 blocks\n", "newc.err");
 
127
        } else {
 
128
                assertTextFileContents("1 block\n", "newc.err");
 
129
        }
 
130
 
 
131
        /* Verify that stdout is a well-formed cpio file in "newc" format. */
 
132
        p = slurpfile(&s, "newc.out");
 
133
        assertEqualInt(s, canSymlink() ? 1024 : 512);
 
134
        e = p;
 
135
 
 
136
        /*
 
137
         * Some of these assertions could be stronger, but it's
 
138
         * a little tricky because they depend on the local environment.
 
139
         */
 
140
 
 
141
        /* First entry is "file1" */
 
142
        assert(is_hex(e, 110)); /* Entire header is octal digits. */
 
143
        assertEqualMem(e + 0, "070701", 6); /* Magic */
 
144
        ino = from_hex(e + 6, 8); /* ino */
 
145
#if defined(_WIN32) && !defined(__CYGWIN__)
 
146
        /* Group members bits and others bits do not work. */ 
 
147
        assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
 
148
#else
 
149
        assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
 
150
#endif  
 
151
        if (uid < 0)
 
152
                uid = from_hex(e + 22, 8);
 
153
        assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
 
154
        gid = from_hex(e + 30, 8); /* gid */
 
155
        assertEqualMem(e + 38, "00000003", 8); /* nlink */
 
156
        t = from_hex(e + 46, 8); /* mtime */
 
157
        failure("t=0x%08x now=0x%08x=%d", t, now, now);
 
158
        assert(t <= now); /* File wasn't created in future. */
 
159
        failure("t=0x%08x now - 2=0x%08x = %d", t, now - 2, now - 2);
 
160
        assert(t >= now - 2); /* File was created w/in last 2 secs. */
 
161
        failure("newc format stores body only with last appearance of a link\n"
 
162
            "       first appearance should be empty, so this file size\n"
 
163
            "       field should be zero");
 
164
        assertEqualInt(0, from_hex(e + 54, 8)); /* File size */
 
165
        fs = from_hex(e + 54, 8);
 
166
        fs += PAD(fs, 4);
 
167
        devmajor = from_hex(e + 62, 8); /* devmajor */
 
168
        devminor = from_hex(e + 70, 8); /* devminor */
 
169
        assert(is_hex(e + 78, 8)); /* rdevmajor */
 
170
        assert(is_hex(e + 86, 8)); /* rdevminor */
 
171
        assertEqualMem(e + 94, "00000006", 8); /* Name size */
 
172
        ns = from_hex(e + 94, 8);
 
173
        ns += PAD(ns + 2, 4);
 
174
        assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 
175
        assertEqualMem(e + 110, "file1\0", 6); /* Name contents */
 
176
        /* Since there's another link, no file contents here. */
 
177
        /* But add in file size so that an error here doesn't cascade. */
 
178
        e += 110 + fs + ns;
 
179
 
 
180
        if (canSymlink()) {
 
181
                /* "symlink" pointing to "file1" */
 
182
                assert(is_hex(e, 110));
 
183
                assertEqualMem(e + 0, "070701", 6); /* Magic */
 
184
                assert(is_hex(e + 6, 8)); /* ino */
 
185
                assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
 
186
                assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
 
187
                assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
 
188
                assertEqualMem(e + 38, "00000001", 8); /* nlink */
 
189
                t2 = from_hex(e + 46, 8); /* mtime */
 
190
                failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
 
191
                assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
 
192
                assertEqualMem(e + 54, "00000005", 8); /* File size */
 
193
                fs = from_hex(e + 54, 8);
 
194
                fs += PAD(fs, 4);
 
195
                assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
 
196
                assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
 
197
                assert(is_hex(e + 78, 8)); /* rdevmajor */
 
198
                assert(is_hex(e + 86, 8)); /* rdevminor */
 
199
                assertEqualMem(e + 94, "00000008", 8); /* Name size */
 
200
                ns = from_hex(e + 94, 8);
 
201
                ns += PAD(ns + 2, 4);
 
202
                assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 
203
                assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
 
204
                assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */
 
205
                e += 110 + fs + ns;
 
206
        }
 
207
 
 
208
        /* "dir" */
 
209
        assert(is_hex(e, 110));
 
210
        assertEqualMem(e + 0, "070701", 6); /* Magic */
 
211
        assert(is_hex(e + 6, 8)); /* ino */
 
212
#if defined(_WIN32) && !defined(__CYGWIN__)
 
213
        /* Group members bits and others bits do not work. */
 
214
        assertEqualInt(0x41c0, from_hex(e + 14, 8) & 0xffc0); /* Mode */
 
215
#else
 
216
        /* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
 
217
        assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
 
218
#endif
 
219
        assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
 
220
        assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
 
221
#ifndef NLINKS_INACCURATE_FOR_DIRS
 
222
        assertEqualMem(e + 38, "00000002", 8); /* nlink */
 
223
#endif
 
224
        t2 = from_hex(e + 46, 8); /* mtime */
 
225
        failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
 
226
        assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
 
227
        assertEqualMem(e + 54, "00000000", 8); /* File size */
 
228
        fs = from_hex(e + 54, 8);
 
229
        fs += PAD(fs, 4);
 
230
        assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
 
231
        assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
 
232
        assert(is_hex(e + 78, 8)); /* rdevmajor */
 
233
        assert(is_hex(e + 86, 8)); /* rdevminor */
 
234
        assertEqualMem(e + 94, "00000004", 8); /* Name size */
 
235
        ns = from_hex(e + 94, 8);
 
236
        ns += PAD(ns + 2, 4);
 
237
        assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 
238
        assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */
 
239
        e += 110 + fs + ns;
 
240
 
 
241
        /* Hardlink identical to "file1" */
 
242
        /* Since we only wrote two of the three links to this
 
243
         * file, this link should get deferred by the hardlink logic. */
 
244
        assert(is_hex(e, 110));
 
245
        assertEqualMem(e + 0, "070701", 6); /* Magic */
 
246
        failure("If these aren't the same, then the hardlink detection failed to match them.");
 
247
        assertEqualInt(ino, from_hex(e + 6, 8)); /* ino */
 
248
#if defined(_WIN32) && !defined(__CYGWIN__)
 
249
        /* Group members bits and others bits do not work. */ 
 
250
        assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
 
251
#else
 
252
        assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
 
253
#endif
 
254
        assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
 
255
        assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
 
256
        assertEqualMem(e + 38, "00000003", 8); /* nlink */
 
257
        t2 = from_hex(e + 46, 8); /* mtime */
 
258
        failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
 
259
        assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
 
260
        assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
 
261
        fs = from_hex(e + 54, 8);
 
262
        fs += PAD(fs, 4);
 
263
        assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
 
264
        assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
 
265
        assert(is_hex(e + 78, 8)); /* rdevmajor */
 
266
        assert(is_hex(e + 86, 8)); /* rdevminor */
 
267
        assertEqualMem(e + 94, "00000009", 8); /* Name size */
 
268
        ns = from_hex(e + 94, 8);
 
269
        ns += PAD(ns + 2, 4);
 
270
        assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 
271
        assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */
 
272
        assertEqualMem(e + 110 + ns, "1234567890\0\0", 12); /* File contents */
 
273
        e += 110 + ns + fs;
 
274
 
 
275
        /* Last entry is end-of-archive marker. */
 
276
        assert(is_hex(e, 110));
 
277
        assertEqualMem(e + 0, "070701", 6); /* Magic */
 
278
        assertEqualMem(e + 8, "00000000", 8); /* ino */
 
279
        assertEqualMem(e + 14, "00000000", 8); /* mode */
 
280
        assertEqualMem(e + 22, "00000000", 8); /* uid */
 
281
        assertEqualMem(e + 30, "00000000", 8); /* gid */
 
282
        assertEqualMem(e + 38, "00000001", 8); /* nlink */
 
283
        assertEqualMem(e + 46, "00000000", 8); /* mtime */
 
284
        assertEqualMem(e + 54, "00000000", 8); /* size */
 
285
        assertEqualMem(e + 62, "00000000", 8); /* devmajor */
 
286
        assertEqualMem(e + 70, "00000000", 8); /* devminor */
 
287
        assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */
 
288
        assertEqualMem(e + 86, "00000000", 8); /* rdevminor */
 
289
        assertEqualInt(11, from_hex(e + 94, 8)); /* name size */
 
290
        assertEqualMem(e + 102, "00000000", 8); /* check field */
 
291
        assertEqualMem(e + 110, "TRAILER!!!\0\0", 12); /* Name */
 
292
 
 
293
        free(p);
 
294
}