1caf54c4fSMartin Matuska /*- 2caf54c4fSMartin Matuska * Copyright (c) 2003-2007 Tim Kientzle 3caf54c4fSMartin Matuska * All rights reserved. 4caf54c4fSMartin Matuska * 5caf54c4fSMartin Matuska * Redistribution and use in source and binary forms, with or without 6caf54c4fSMartin Matuska * modification, are permitted provided that the following conditions 7caf54c4fSMartin Matuska * are met: 8caf54c4fSMartin Matuska * 1. Redistributions of source code must retain the above copyright 9caf54c4fSMartin Matuska * notice, this list of conditions and the following disclaimer. 10caf54c4fSMartin Matuska * 2. Redistributions in binary form must reproduce the above copyright 11caf54c4fSMartin Matuska * notice, this list of conditions and the following disclaimer in the 12caf54c4fSMartin Matuska * documentation and/or other materials provided with the distribution. 13caf54c4fSMartin Matuska * 14caf54c4fSMartin Matuska * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15caf54c4fSMartin Matuska * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16caf54c4fSMartin Matuska * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17caf54c4fSMartin Matuska * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18caf54c4fSMartin Matuska * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19caf54c4fSMartin Matuska * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20caf54c4fSMartin Matuska * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21caf54c4fSMartin Matuska * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22caf54c4fSMartin Matuska * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23caf54c4fSMartin Matuska * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24caf54c4fSMartin Matuska */ 25caf54c4fSMartin Matuska #include "test.h" 266c22d9efSMartin Matuska __FBSDID("$FreeBSD$"); 27caf54c4fSMartin Matuska 28caf54c4fSMartin Matuska static void 29caf54c4fSMartin Matuska verify_files(const char *msg) 30caf54c4fSMartin Matuska { 31caf54c4fSMartin Matuska /* 32caf54c4fSMartin Matuska * Verify unpacked files. 33caf54c4fSMartin Matuska */ 34caf54c4fSMartin Matuska 35caf54c4fSMartin Matuska /* Regular file with 2 links. */ 366c95142eSMartin Matuska failure(msg); 37caf54c4fSMartin Matuska assertIsReg("file", 0644); 38caf54c4fSMartin Matuska failure(msg); 39caf54c4fSMartin Matuska assertFileSize("file", 10); 406c95142eSMartin Matuska failure(msg); 41caf54c4fSMartin Matuska assertFileNLinks("file", 2); 42caf54c4fSMartin Matuska 43caf54c4fSMartin Matuska /* Another name for the same file. */ 446c95142eSMartin Matuska failure(msg); 45caf54c4fSMartin Matuska assertIsHardlink("linkfile", "file"); 46caf54c4fSMartin Matuska 47caf54c4fSMartin Matuska /* Symlink */ 48caf54c4fSMartin Matuska if (canSymlink()) 49caf54c4fSMartin Matuska assertIsSymlink("symlink", "file"); 50caf54c4fSMartin Matuska 51caf54c4fSMartin Matuska /* Another file with 1 link and different permissions. */ 526c95142eSMartin Matuska failure(msg); 53caf54c4fSMartin Matuska assertIsReg("file2", 0777); 546c95142eSMartin Matuska failure(msg); 55caf54c4fSMartin Matuska assertFileSize("file2", 10); 566c95142eSMartin Matuska failure(msg); 57caf54c4fSMartin Matuska assertFileNLinks("file2", 1); 58caf54c4fSMartin Matuska 59caf54c4fSMartin Matuska /* dir */ 60caf54c4fSMartin Matuska assertIsDir("dir", 0775); 61caf54c4fSMartin Matuska } 62caf54c4fSMartin Matuska 63caf54c4fSMartin Matuska static void 64caf54c4fSMartin Matuska basic_cpio(const char *target, 65caf54c4fSMartin Matuska const char *pack_options, 66caf54c4fSMartin Matuska const char *unpack_options, 676c95142eSMartin Matuska const char *se, const char *se2) 68caf54c4fSMartin Matuska { 69caf54c4fSMartin Matuska int r; 70caf54c4fSMartin Matuska 71caf54c4fSMartin Matuska if (!assertMakeDir(target, 0775)) 72caf54c4fSMartin Matuska return; 73caf54c4fSMartin Matuska 74caf54c4fSMartin Matuska /* Use the cpio program to create an archive. */ 75*cdf63a70SMartin Matuska r = systemf("%s -R 1000:1000 -o %s < filelist >%s/archive 2>%s/pack.err", 76caf54c4fSMartin Matuska testprog, pack_options, target, target); 77caf54c4fSMartin Matuska failure("Error invoking %s -o %s", testprog, pack_options); 78caf54c4fSMartin Matuska assertEqualInt(r, 0); 79caf54c4fSMartin Matuska 80caf54c4fSMartin Matuska assertChdir(target); 81caf54c4fSMartin Matuska 82caf54c4fSMartin Matuska /* Verify stderr. */ 83caf54c4fSMartin Matuska failure("Expected: %s, options=%s", se, pack_options); 84caf54c4fSMartin Matuska assertTextFileContents(se, "pack.err"); 85caf54c4fSMartin Matuska 86caf54c4fSMartin Matuska /* 87caf54c4fSMartin Matuska * Use cpio to unpack the archive into another directory. 88caf54c4fSMartin Matuska */ 89caf54c4fSMartin Matuska r = systemf("%s -i %s< archive >unpack.out 2>unpack.err", 90caf54c4fSMartin Matuska testprog, unpack_options); 91caf54c4fSMartin Matuska failure("Error invoking %s -i %s", testprog, unpack_options); 92caf54c4fSMartin Matuska assertEqualInt(r, 0); 93caf54c4fSMartin Matuska 94caf54c4fSMartin Matuska /* Verify stderr. */ 95caf54c4fSMartin Matuska failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target); 966c95142eSMartin Matuska assertTextFileContents(se2, "unpack.err"); 97caf54c4fSMartin Matuska 98caf54c4fSMartin Matuska verify_files(pack_options); 99caf54c4fSMartin Matuska 100caf54c4fSMartin Matuska assertChdir(".."); 101caf54c4fSMartin Matuska } 102caf54c4fSMartin Matuska 103caf54c4fSMartin Matuska static void 104caf54c4fSMartin Matuska passthrough(const char *target) 105caf54c4fSMartin Matuska { 106caf54c4fSMartin Matuska int r; 107caf54c4fSMartin Matuska 108caf54c4fSMartin Matuska if (!assertMakeDir(target, 0775)) 109caf54c4fSMartin Matuska return; 110caf54c4fSMartin Matuska 111caf54c4fSMartin Matuska /* 112caf54c4fSMartin Matuska * Use cpio passthrough mode to copy files to another directory. 113caf54c4fSMartin Matuska */ 114caf54c4fSMartin Matuska r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr", 115caf54c4fSMartin Matuska testprog, target, target, target); 116caf54c4fSMartin Matuska failure("Error invoking %s -p", testprog); 117caf54c4fSMartin Matuska assertEqualInt(r, 0); 118caf54c4fSMartin Matuska 119caf54c4fSMartin Matuska assertChdir(target); 120caf54c4fSMartin Matuska 121caf54c4fSMartin Matuska /* Verify stderr. */ 122caf54c4fSMartin Matuska failure("Error invoking %s -p in dir %s", 123caf54c4fSMartin Matuska testprog, target); 124caf54c4fSMartin Matuska assertTextFileContents("1 block\n", "stderr"); 125caf54c4fSMartin Matuska 126caf54c4fSMartin Matuska verify_files("passthrough"); 127caf54c4fSMartin Matuska assertChdir(".."); 128caf54c4fSMartin Matuska } 129caf54c4fSMartin Matuska 130caf54c4fSMartin Matuska DEFINE_TEST(test_basic) 131caf54c4fSMartin Matuska { 132caf54c4fSMartin Matuska FILE *filelist; 133caf54c4fSMartin Matuska const char *msg; 1346c95142eSMartin Matuska char result[1024]; 135caf54c4fSMartin Matuska 136caf54c4fSMartin Matuska assertUmask(0); 137caf54c4fSMartin Matuska 138caf54c4fSMartin Matuska /* 139caf54c4fSMartin Matuska * Create an assortment of files on disk. 140caf54c4fSMartin Matuska */ 141caf54c4fSMartin Matuska filelist = fopen("filelist", "w"); 1426c95142eSMartin Matuska memset(result, 0, sizeof(result)); 143caf54c4fSMartin Matuska 144caf54c4fSMartin Matuska /* File with 10 bytes content. */ 145caf54c4fSMartin Matuska assertMakeFile("file", 0644, "1234567890"); 146caf54c4fSMartin Matuska fprintf(filelist, "file\n"); 1476c95142eSMartin Matuska if (is_LargeInode("file")) 1486c95142eSMartin Matuska strncat(result, 1496c95142eSMartin Matuska "bsdcpio: file: large inode number truncated: " 1506c95142eSMartin Matuska "Numerical result out of range\n", 151acc60b03SMartin Matuska sizeof(result) - strlen(result) -1); 152caf54c4fSMartin Matuska 153caf54c4fSMartin Matuska /* hardlink to above file. */ 154caf54c4fSMartin Matuska assertMakeHardlink("linkfile", "file"); 155caf54c4fSMartin Matuska fprintf(filelist, "linkfile\n"); 1566c95142eSMartin Matuska if (is_LargeInode("linkfile")) 1576c95142eSMartin Matuska strncat(result, 1586c95142eSMartin Matuska "bsdcpio: linkfile: large inode number truncated: " 1596c95142eSMartin Matuska "Numerical result out of range\n", 160acc60b03SMartin Matuska sizeof(result) - strlen(result) -1); 161caf54c4fSMartin Matuska 162caf54c4fSMartin Matuska /* Symlink to above file. */ 163caf54c4fSMartin Matuska if (canSymlink()) { 164caf54c4fSMartin Matuska assertMakeSymlink("symlink", "file"); 165caf54c4fSMartin Matuska fprintf(filelist, "symlink\n"); 1666c95142eSMartin Matuska if (is_LargeInode("symlink")) 1676c95142eSMartin Matuska strncat(result, 1686c95142eSMartin Matuska "bsdcpio: symlink: large inode number truncated: " 1696c95142eSMartin Matuska "Numerical result out of range\n", 170acc60b03SMartin Matuska sizeof(result) - strlen(result) -1); 171caf54c4fSMartin Matuska } 172caf54c4fSMartin Matuska 173caf54c4fSMartin Matuska /* Another file with different permissions. */ 174caf54c4fSMartin Matuska assertMakeFile("file2", 0777, "1234567890"); 175caf54c4fSMartin Matuska fprintf(filelist, "file2\n"); 1766c95142eSMartin Matuska if (is_LargeInode("file2")) 1776c95142eSMartin Matuska strncat(result, 1786c95142eSMartin Matuska "bsdcpio: file2: large inode number truncated: " 1796c95142eSMartin Matuska "Numerical result out of range\n", 180acc60b03SMartin Matuska sizeof(result) - strlen(result) -1); 181caf54c4fSMartin Matuska 182caf54c4fSMartin Matuska /* Directory. */ 183caf54c4fSMartin Matuska assertMakeDir("dir", 0775); 184caf54c4fSMartin Matuska fprintf(filelist, "dir\n"); 1856c95142eSMartin Matuska if (is_LargeInode("dir")) 1866c95142eSMartin Matuska strncat(result, 1876c95142eSMartin Matuska "bsdcpio: dir: large inode number truncated: " 1886c95142eSMartin Matuska "Numerical result out of range\n", 189acc60b03SMartin Matuska sizeof(result) - strlen(result) -1); 190acc60b03SMartin Matuska strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1); 1916c95142eSMartin Matuska 192caf54c4fSMartin Matuska /* All done. */ 193caf54c4fSMartin Matuska fclose(filelist); 194caf54c4fSMartin Matuska 195caf54c4fSMartin Matuska assertUmask(022); 196caf54c4fSMartin Matuska 197caf54c4fSMartin Matuska /* Archive/dearchive with a variety of options. */ 198caf54c4fSMartin Matuska msg = canSymlink() ? "2 blocks\n" : "1 block\n"; 1996c95142eSMartin Matuska basic_cpio("copy", "", "", msg, msg); 2006c95142eSMartin Matuska basic_cpio("copy_odc", "--format=odc", "", msg, msg); 2016c95142eSMartin Matuska basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n"); 2026c95142eSMartin Matuska basic_cpio("copy_cpio", "-H odc", "", msg, msg); 203caf54c4fSMartin Matuska msg = canSymlink() ? "9 blocks\n" : "8 blocks\n"; 2046c95142eSMartin Matuska basic_cpio("copy_ustar", "-H ustar", "", msg, msg); 205caf54c4fSMartin Matuska 206caf54c4fSMartin Matuska /* Copy in one step using -p */ 207caf54c4fSMartin Matuska passthrough("passthrough"); 208caf54c4fSMartin Matuska } 209