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