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 *msg) 30 { 31 /* 32 * Verify unpacked files. 33 */ 34 35 /* Regular file with 2 links. */ 36 failure(msg); 37 assertIsReg("file", 0644); 38 failure(msg); 39 assertFileSize("file", 10); 40 failure(msg); 41 assertFileNLinks("file", 2); 42 43 /* Another name for the same file. */ 44 failure(msg); 45 assertIsHardlink("linkfile", "file"); 46 47 /* Symlink */ 48 if (canSymlink()) 49 assertIsSymlink("symlink", "file"); 50 51 /* Another file with 1 link and different permissions. */ 52 failure(msg); 53 assertIsReg("file2", 0777); 54 failure(msg); 55 assertFileSize("file2", 10); 56 failure(msg); 57 assertFileNLinks("file2", 1); 58 59 /* dir */ 60 assertIsDir("dir", 0775); 61 } 62 63 static void 64 basic_cpio(const char *target, 65 const char *pack_options, 66 const char *unpack_options, 67 const char *se, const char *se2) 68 { 69 int r; 70 71 if (!assertMakeDir(target, 0775)) 72 return; 73 74 /* Use the cpio program to create an archive. */ 75 r = systemf("%s -R 1000:1000 -o %s < filelist >%s/archive 2>%s/pack.err", 76 testprog, pack_options, target, target); 77 failure("Error invoking %s -o %s", testprog, pack_options); 78 assertEqualInt(r, 0); 79 80 assertChdir(target); 81 82 /* Verify stderr. */ 83 failure("Expected: %s, options=%s", se, pack_options); 84 assertTextFileContents(se, "pack.err"); 85 86 /* 87 * Use cpio to unpack the archive into another directory. 88 */ 89 r = systemf("%s -i %s< archive >unpack.out 2>unpack.err", 90 testprog, unpack_options); 91 failure("Error invoking %s -i %s", testprog, unpack_options); 92 assertEqualInt(r, 0); 93 94 /* Verify stderr. */ 95 failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target); 96 assertTextFileContents(se2, "unpack.err"); 97 98 verify_files(pack_options); 99 100 assertChdir(".."); 101 } 102 103 static void 104 passthrough(const char *target) 105 { 106 int r; 107 108 if (!assertMakeDir(target, 0775)) 109 return; 110 111 /* 112 * Use cpio passthrough mode to copy files to another directory. 113 */ 114 r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr", 115 testprog, target, target, target); 116 failure("Error invoking %s -p", testprog); 117 assertEqualInt(r, 0); 118 119 assertChdir(target); 120 121 /* Verify stderr. */ 122 failure("Error invoking %s -p in dir %s", 123 testprog, target); 124 assertTextFileContents("1 block\n", "stderr"); 125 126 verify_files("passthrough"); 127 assertChdir(".."); 128 } 129 130 DEFINE_TEST(test_basic) 131 { 132 FILE *filelist; 133 const char *msg; 134 char result[1024]; 135 136 assertUmask(0); 137 138 /* 139 * Create an assortment of files on disk. 140 */ 141 filelist = fopen("filelist", "w"); 142 memset(result, 0, sizeof(result)); 143 144 /* File with 10 bytes content. */ 145 assertMakeFile("file", 0644, "1234567890"); 146 fprintf(filelist, "file\n"); 147 if (is_LargeInode("file")) { 148 strncat(result, 149 "bsdcpio: file: large inode number truncated: ", 150 sizeof(result) - strlen(result) -1); 151 strncat(result, 152 strerror(ERANGE), 153 sizeof(result) - strlen(result) -1); 154 strncat(result, 155 "\n", 156 sizeof(result) - strlen(result) -1); 157 } 158 159 /* hardlink to above file. */ 160 assertMakeHardlink("linkfile", "file"); 161 fprintf(filelist, "linkfile\n"); 162 if (is_LargeInode("linkfile")) { 163 strncat(result, 164 "bsdcpio: linkfile: large inode number truncated: ", 165 sizeof(result) - strlen(result) -1); 166 strncat(result, 167 strerror(ERANGE), 168 sizeof(result) - strlen(result) -1); 169 strncat(result, 170 "\n", 171 sizeof(result) - strlen(result) -1); 172 } 173 174 /* Symlink to above file. */ 175 if (canSymlink()) { 176 assertMakeSymlink("symlink", "file"); 177 fprintf(filelist, "symlink\n"); 178 if (is_LargeInode("symlink")) { 179 strncat(result, 180 "bsdcpio: symlink: large inode number truncated: ", 181 sizeof(result) - strlen(result) -1); 182 strncat(result, 183 strerror(ERANGE), 184 sizeof(result) - strlen(result) -1); 185 strncat(result, 186 "\n", 187 sizeof(result) - strlen(result) -1); 188 } 189 } 190 191 /* Another file with different permissions. */ 192 assertMakeFile("file2", 0777, "1234567890"); 193 fprintf(filelist, "file2\n"); 194 if (is_LargeInode("file2")) { 195 strncat(result, 196 "bsdcpio: file2: large inode number truncated: ", 197 sizeof(result) - strlen(result) -1); 198 strncat(result, 199 strerror(ERANGE), 200 sizeof(result) - strlen(result) -1); 201 strncat(result, 202 "\n", 203 sizeof(result) - strlen(result) -1); 204 } 205 206 /* Directory. */ 207 assertMakeDir("dir", 0775); 208 fprintf(filelist, "dir\n"); 209 if (is_LargeInode("dir")) { 210 strncat(result, 211 "bsdcpio: dir: large inode number truncated: ", 212 sizeof(result) - strlen(result) -1); 213 strncat(result, 214 strerror(ERANGE), 215 sizeof(result) - strlen(result) -1); 216 strncat(result, 217 "\n", 218 sizeof(result) - strlen(result) -1); 219 } 220 strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1); 221 222 /* All done. */ 223 fclose(filelist); 224 225 assertUmask(022); 226 227 /* Archive/dearchive with a variety of options. */ 228 msg = canSymlink() ? "2 blocks\n" : "1 block\n"; 229 basic_cpio("copy", "", "", msg, msg); 230 basic_cpio("copy_odc", "--format=odc", "", msg, msg); 231 basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n"); 232 basic_cpio("copy_cpio", "-H odc", "", msg, msg); 233 msg = canSymlink() ? "9 blocks\n" : "8 blocks\n"; 234 basic_cpio("copy_ustar", "-H ustar", "", msg, msg); 235 236 /* Copy in one step using -p */ 237 passthrough("passthrough"); 238 } 239