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 -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 "Numerical result out of range\n", 151 sizeof(result) - strlen(result) -1); 152 153 /* hardlink to above file. */ 154 assertMakeHardlink("linkfile", "file"); 155 fprintf(filelist, "linkfile\n"); 156 if (is_LargeInode("linkfile")) 157 strncat(result, 158 "bsdcpio: linkfile: large inode number truncated: " 159 "Numerical result out of range\n", 160 sizeof(result) - strlen(result) -1); 161 162 /* Symlink to above file. */ 163 if (canSymlink()) { 164 assertMakeSymlink("symlink", "file"); 165 fprintf(filelist, "symlink\n"); 166 if (is_LargeInode("symlink")) 167 strncat(result, 168 "bsdcpio: symlink: large inode number truncated: " 169 "Numerical result out of range\n", 170 sizeof(result) - strlen(result) -1); 171 } 172 173 /* Another file with different permissions. */ 174 assertMakeFile("file2", 0777, "1234567890"); 175 fprintf(filelist, "file2\n"); 176 if (is_LargeInode("file2")) 177 strncat(result, 178 "bsdcpio: file2: large inode number truncated: " 179 "Numerical result out of range\n", 180 sizeof(result) - strlen(result) -1); 181 182 /* Directory. */ 183 assertMakeDir("dir", 0775); 184 fprintf(filelist, "dir\n"); 185 if (is_LargeInode("dir")) 186 strncat(result, 187 "bsdcpio: dir: large inode number truncated: " 188 "Numerical result out of range\n", 189 sizeof(result) - strlen(result) -1); 190 strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1); 191 192 /* All done. */ 193 fclose(filelist); 194 195 assertUmask(022); 196 197 /* Archive/dearchive with a variety of options. */ 198 msg = canSymlink() ? "2 blocks\n" : "1 block\n"; 199 basic_cpio("copy", "", "", msg, msg); 200 basic_cpio("copy_odc", "--format=odc", "", msg, msg); 201 basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n"); 202 basic_cpio("copy_cpio", "-H odc", "", msg, msg); 203 msg = canSymlink() ? "9 blocks\n" : "8 blocks\n"; 204 basic_cpio("copy_ustar", "-H ustar", "", msg, msg); 205 206 /* Copy in one step using -p */ 207 passthrough("passthrough"); 208 } 209