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