]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.bin/cpio/test/test_basic.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / usr.bin / cpio / test / test_basic.c
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$");
27
28 static void
29 verify_files(const char *target)
30 {
31         struct stat st, st2;
32 #if !defined(_WIN32) || defined(__CYGWIN__)
33         char buff[128];
34 #endif
35         int r;
36
37         /*
38          * Verify unpacked files.
39          */
40
41         /* Regular file with 2 links. */
42         r = lstat("file", &st);
43         failure("Failed to stat file %s/file, errno=%d", target, errno);
44         assertEqualInt(r, 0);
45         if (r == 0) {
46                 assert(S_ISREG(st.st_mode));
47 #if defined(_WIN32) && !defined(__CYGWIN__)
48                 /* Group members bits and others bits do not work. */
49                 assertEqualInt(0600, st.st_mode & 0700);
50 #else
51                 assertEqualInt(0644, st.st_mode & 0777);
52 #endif
53                 assertEqualInt(10, st.st_size);
54                 failure("file %s/file should have 2 links", target);
55                 assertEqualInt(2, st.st_nlink);
56         }
57
58         /* Another name for the same file. */
59         r = lstat("linkfile", &st2);
60         failure("Failed to stat file %s/linkfile, errno=%d", target, errno);
61         assertEqualInt(r, 0);
62         if (r == 0) {
63                 assert(S_ISREG(st2.st_mode));
64 #if defined(_WIN32) && !defined(__CYGWIN__)
65                 /* Group members bits and others bits do not work. */
66                 assertEqualInt(0600, st2.st_mode & 0700);
67 #else
68                 assertEqualInt(0644, st2.st_mode & 0777);
69 #endif
70                 assertEqualInt(10, st2.st_size);
71                 failure("file %s/linkfile should have 2 links", target);
72                 assertEqualInt(2, st2.st_nlink);
73                 /* Verify that the two are really hardlinked. */
74                 assertEqualInt(st.st_dev, st2.st_dev);
75                 failure("%s/linkfile and %s/file should be hardlinked",
76                     target, target);
77                 assertEqualInt(st.st_ino, st2.st_ino);
78         }
79
80         /* Symlink */
81         r = lstat("symlink", &st);
82         failure("Failed to stat file %s/symlink, errno=%d", target, errno);
83         assertEqualInt(r, 0);
84 #if !defined(_WIN32) || defined(__CYGWIN__)
85         if (r == 0) {
86                 failure("symlink should be a symlink; actual mode is %o",
87                     st.st_mode);
88                 assert(S_ISLNK(st.st_mode));
89                 if (S_ISLNK(st.st_mode)) {
90                         r = readlink("symlink", buff, sizeof(buff));
91                         assertEqualInt(r, 4);
92                         buff[r] = '\0';
93                         assertEqualString(buff, "file");
94                 }
95         }
96 #endif
97
98         /* Another file with 1 link and different permissions. */
99         r = lstat("file2", &st);
100         failure("Failed to stat file %s/file2, errno=%d", target, errno);
101         assertEqualInt(r, 0);
102         if (r == 0) {
103                 assert(S_ISREG(st.st_mode));
104                 failure("%s/file2: st.st_mode = %o", target, st.st_mode);
105 #if defined(_WIN32) && !defined(__CYGWIN__)
106                 /* Execution bit and group members bits and others
107                  * bits do not work. */
108                 assertEqualInt(0600, st.st_mode & 0700);
109 #else
110                 assertEqualInt(0777, st.st_mode & 0777);
111 #endif
112                 assertEqualInt(10, st.st_size);
113                 failure("file %s/file2 should have 1 link", target);
114                 assertEqualInt(1, st.st_nlink);
115         }
116
117         /* dir */
118         r = lstat("dir", &st);
119         if (r == 0) {
120                 assertEqualInt(r, 0);
121                 assert(S_ISDIR(st.st_mode));
122                 failure("%s/dir: st.st_mode = %o", target, st.st_mode);
123 #if defined(_WIN32) && !defined(__CYGWIN__)
124                 assertEqualInt(0700, st.st_mode & 0700);
125 #else
126                 assertEqualInt(0775, st.st_mode & 0777);
127 #endif
128         }
129 }
130
131 static void
132 basic_cpio(const char *target,
133     const char *pack_options,
134     const char *unpack_options,
135     const char *se)
136 {
137         int r;
138
139         if (!assertEqualInt(0, mkdir(target, 0775)))
140             return;
141
142         /* Use the cpio program to create an archive. */
143         r = systemf("%s -o %s < filelist >%s/archive 2>%s/pack.err",
144             testprog, pack_options, target, target);
145         failure("Error invoking %s -o %s", testprog, pack_options);
146         assertEqualInt(r, 0);
147
148         chdir(target);
149
150         /* Verify stderr. */
151         failure("Expected: %s, options=%s", se, pack_options);
152         assertTextFileContents(se, "pack.err");
153
154         /*
155          * Use cpio to unpack the archive into another directory.
156          */
157         r = systemf("%s -i %s< archive >unpack.out 2>unpack.err",
158             testprog, unpack_options);
159         failure("Error invoking %s -i %s", testprog, unpack_options);
160         assertEqualInt(r, 0);
161
162         /* Verify stderr. */
163         failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
164         assertTextFileContents(se, "unpack.err");
165
166         verify_files(target);
167
168         chdir("..");
169 }
170
171 static void
172 passthrough(const char *target)
173 {
174         int r;
175
176         if (!assertEqualInt(0, mkdir(target, 0775)))
177                 return;
178
179         /*
180          * Use cpio passthrough mode to copy files to another directory.
181          */
182         r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr",
183             testprog, target, target, target);
184         failure("Error invoking %s -p", testprog);
185         assertEqualInt(r, 0);
186
187         chdir(target);
188
189         /* Verify stderr. */
190         failure("Error invoking %s -p in dir %s",
191             testprog, target);
192         assertTextFileContents("1 block\n", "stderr");
193
194         verify_files(target);
195         chdir("..");
196 }
197
198 DEFINE_TEST(test_basic)
199 {
200         int fd;
201         int filelist;
202         int oldumask;
203
204         oldumask = umask(0);
205
206         /*
207          * Create an assortment of files on disk.
208          */
209         filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
210
211         /* File with 10 bytes content. */
212         fd = open("file", O_CREAT | O_WRONLY, 0644);
213         assert(fd >= 0);
214         assertEqualInt(10, write(fd, "123456789", 10));
215         close(fd);
216         write(filelist, "file\n", 5);
217
218         /* hardlink to above file. */
219         assertEqualInt(0, link("file", "linkfile"));
220         write(filelist, "linkfile\n", 9);
221
222         /* Symlink to above file. */
223         assertEqualInt(0, symlink("file", "symlink"));
224         write(filelist, "symlink\n", 8);
225
226         /* Another file with different permissions. */
227         fd = open("file2", O_CREAT | O_WRONLY, 0777);
228         assert(fd >= 0);
229         assertEqualInt(10, write(fd, "123456789", 10));
230         close(fd);
231         write(filelist, "file2\n", 6);
232
233         /* Directory. */
234         assertEqualInt(0, mkdir("dir", 0775));
235         write(filelist, "dir\n", 4);
236         /* All done. */
237         close(filelist);
238
239         umask(022);
240
241         /* Archive/dearchive with a variety of options. */
242         basic_cpio("copy", "", "", "2 blocks\n");
243         basic_cpio("copy_odc", "--format=odc", "", "2 blocks\n");
244         basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
245         basic_cpio("copy_cpio", "-H odc", "", "2 blocks\n");
246 #if defined(_WIN32) && !defined(__CYGWIN__)
247         /*
248          * On Windows, symbolic link does not work.
249          * Currentry copying file instead. therefore block size is
250          * different.
251          */
252         basic_cpio("copy_ustar", "-H ustar", "", "10 blocks\n");
253 #else
254         basic_cpio("copy_ustar", "-H ustar", "", "9 blocks\n");
255 #endif
256         /* Copy in one step using -p */
257         passthrough("passthrough");
258
259         umask(oldumask);
260 }