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