Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libarchive/cpio/test/test_option_c.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2003-2007 Tim Kientzle
5
* All rights reserved.
6
*/
7
#include "test.h"
8
9
static int
10
is_octal(const char *p, size_t l)
11
{
12
while (l > 0) {
13
if (*p < '0' || *p > '7')
14
return (0);
15
--l;
16
++p;
17
}
18
return (1);
19
}
20
21
static unsigned long long int
22
from_octal(const char *p, size_t l)
23
{
24
long long int r = 0;
25
26
while (l > 0) {
27
r *= 8;
28
r += *p - '0';
29
--l;
30
++p;
31
}
32
return (r);
33
}
34
35
#if !defined(_WIN32) || defined(__CYGWIN__)
36
static int
37
nlinks(const char *p)
38
{
39
struct stat st;
40
assertEqualInt(0, stat(p, &st));
41
return st.st_nlink;
42
}
43
#endif
44
45
DEFINE_TEST(test_option_c)
46
{
47
FILE *filelist;
48
int r;
49
int uid = 1000;
50
int dev, ino, gid = 1000;
51
time_t t, now;
52
char *p, *e;
53
size_t s;
54
55
assertUmask(0);
56
57
/*
58
* Create an assortment of files.
59
* TODO: Extend this to cover more filetypes.
60
*/
61
filelist = fopen("filelist", "w");
62
63
/* "file" */
64
assertMakeFile("file", 0644, "1234567890");
65
fprintf(filelist, "file\n");
66
67
/* "symlink" */
68
if (canSymlink()) {
69
assertMakeSymlink("symlink", "file", 0);
70
fprintf(filelist, "symlink\n");
71
}
72
73
/* "dir" */
74
assertMakeDir("dir", 0775);
75
/* Record some facts about what we just created: */
76
now = time(NULL); /* They were all created w/in last two seconds. */
77
fprintf(filelist, "dir\n");
78
79
/* Use the cpio program to create an archive. */
80
fclose(filelist);
81
r = systemf("%s -R 1000:1000 -oc <filelist >basic.out 2>basic.err", testprog);
82
/* Verify that nothing went to stderr. */
83
assertTextFileContents("1 block\n", "basic.err");
84
85
/* Assert that the program finished. */
86
failure("%s -oc crashed", testprog);
87
if (!assertEqualInt(r, 0))
88
return;
89
90
/* Verify that stdout is a well-formed cpio file in "odc" format. */
91
p = slurpfile(&s, "basic.out");
92
assertEqualInt(s, 512);
93
e = p;
94
95
/*
96
* Some of these assertions could be stronger, but it's
97
* a little tricky because they depend on the local environment.
98
*/
99
100
/* First entry is "file" */
101
assert(is_octal(e, 76)); /* Entire header is octal digits. */
102
assertEqualMem(e + 0, "070707", 6); /* Magic */
103
assert(is_octal(e + 6, 6)); /* dev */
104
dev = (int)from_octal(e + 6, 6);
105
assert(is_octal(e + 12, 6)); /* ino */
106
ino = (int)from_octal(e + 12, 6);
107
#if defined(_WIN32) && !defined(__CYGWIN__)
108
/* Group members bits and others bits do not work. */
109
assertEqualMem(e + 18, "100666", 6); /* Mode */
110
#else
111
assertEqualMem(e + 18, "100644", 6); /* Mode */
112
#endif
113
if (uid < 0)
114
uid = (int)from_octal(e + 24, 6);
115
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
116
assert(is_octal(e + 30, 6)); /* gid */
117
gid = (int)from_octal(e + 30, 6);
118
assertEqualMem(e + 36, "000001", 6); /* nlink */
119
failure("file entries should not have rdev set (dev field was 0%o)",
120
(unsigned int)dev);
121
assertEqualMem(e + 42, "000000", 6); /* rdev */
122
t = from_octal(e + 48, 11); /* mtime */
123
assert(t <= now); /* File wasn't created in future. */
124
assert(t >= now - 2); /* File was created w/in last 2 secs. */
125
assertEqualMem(e + 59, "000005", 6); /* Name size */
126
assertEqualMem(e + 65, "00000000012", 11); /* File size */
127
assertEqualMem(e + 76, "file\0", 5); /* Name contents */
128
assertEqualMem(e + 81, "1234567890", 10); /* File contents */
129
e += 91;
130
131
/* "symlink" pointing to "file" */
132
if (canSymlink()) {
133
assert(is_octal(e, 76)); /* Entire header is octal digits. */
134
assertEqualMem(e + 0, "070707", 6); /* Magic */
135
assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */
136
assert(ino != (int)from_octal(e + 12, 6)); /* ino */
137
#if !defined(_WIN32) || defined(__CYGWIN__)
138
/* On Windows, symbolic link and group members bits and
139
* others bits do not work. */
140
assertEqualMem(e + 18, "120777", 6); /* Mode */
141
#endif
142
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
143
assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
144
assertEqualMem(e + 36, "000001", 6); /* nlink */
145
failure("file entries should have rdev == 0 (dev was 0%llo)",
146
from_octal(e + 6, 6));
147
assertEqualMem(e + 42, "000000", 6); /* rdev */
148
t = from_octal(e + 48, 11); /* mtime */
149
assert(t <= now); /* File wasn't created in future. */
150
assert(t >= now - 2); /* File was created w/in last 2 secs. */
151
assertEqualMem(e + 59, "000010", 6); /* Name size */
152
assertEqualMem(e + 65, "00000000004", 11); /* File size */
153
assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */
154
assertEqualMem(e + 84, "file", 4); /* Symlink target. */
155
e += 88;
156
}
157
158
/* "dir" */
159
assert(is_octal(e, 76));
160
assertEqualMem(e + 0, "070707", 6); /* Magic */
161
/* Dev should be same as first entry. */
162
assert(is_octal(e + 6, 6)); /* dev */
163
assertEqualInt(dev, from_octal(e + 6, 6));
164
/* Ino must be different from first entry. */
165
assert(is_octal(e + 12, 6)); /* ino */
166
assert(ino != (int)from_octal(e + 12, 6));
167
#if defined(_WIN32) && !defined(__CYGWIN__)
168
/* Group members bits and others bits do not work. */
169
assertEqualMem(e + 18, "040777", 6); /* Mode */
170
#else
171
/* Accept 042775 to accommodate systems where sgid bit propagates. */
172
if (memcmp(e + 18, "042775", 6) != 0)
173
assertEqualMem(e + 18, "040775", 6); /* Mode */
174
#endif
175
assertEqualInt(uid, from_octal(e + 24, 6)); /* uid */
176
/* Gid should be same as first entry. */
177
assert(is_octal(e + 30, 6)); /* gid */
178
assertEqualInt(gid, from_octal(e + 30, 6));
179
180
#if !defined(_WIN32) || defined(__CYGWIN__)
181
assertEqualInt(nlinks("dir"), from_octal(e + 36, 6)); /* Nlink */
182
#endif
183
184
t = from_octal(e + 48, 11); /* mtime */
185
assert(t <= now); /* File wasn't created in future. */
186
assert(t >= now - 2); /* File was created w/in last 2 secs. */
187
assertEqualMem(e + 59, "000004", 6); /* Name size */
188
assertEqualMem(e + 65, "00000000000", 11); /* File size */
189
assertEqualMem(e + 76, "dir\0", 4); /* name */
190
e += 80;
191
192
/* TODO: Verify other types of entries. */
193
194
/* Last entry is end-of-archive marker. */
195
assert(is_octal(e, 76));
196
assertEqualMem(e + 0, "070707", 6); /* Magic */
197
assertEqualMem(e + 6, "000000", 6); /* dev */
198
assertEqualMem(e + 12, "000000", 6); /* ino */
199
assertEqualMem(e + 18, "000000", 6); /* Mode */
200
assertEqualMem(e + 24, "000000", 6); /* uid */
201
assertEqualMem(e + 30, "000000", 6); /* gid */
202
assertEqualMem(e + 36, "000001", 6); /* Nlink */
203
assertEqualMem(e + 42, "000000", 6); /* rdev */
204
assertEqualMem(e + 48, "00000000000", 11); /* mtime */
205
assertEqualMem(e + 59, "000013", 6); /* Name size */
206
assertEqualMem(e + 65, "00000000000", 11); /* File size */
207
assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */
208
209
free(p);
210
}
211
212