1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm#include "test.h" 26228763Smm__FBSDID("$FreeBSD$"); 27228753Smm 28228753Smmstatic void 29228753Smmverify_files(const char *msg) 30228753Smm{ 31228753Smm /* 32228753Smm * Verify unpacked files. 33228753Smm */ 34228753Smm 35228753Smm /* Regular file with 2 links. */ 36232153Smm failure(msg); 37228753Smm assertIsReg("file", 0644); 38228753Smm failure(msg); 39228753Smm assertFileSize("file", 10); 40232153Smm failure(msg); 41228753Smm assertFileNLinks("file", 2); 42228753Smm 43228753Smm /* Another name for the same file. */ 44232153Smm failure(msg); 45228753Smm assertIsHardlink("linkfile", "file"); 46228753Smm 47228753Smm /* Symlink */ 48228753Smm if (canSymlink()) 49228753Smm assertIsSymlink("symlink", "file"); 50228753Smm 51228753Smm /* Another file with 1 link and different permissions. */ 52232153Smm failure(msg); 53228753Smm assertIsReg("file2", 0777); 54232153Smm failure(msg); 55228753Smm assertFileSize("file2", 10); 56232153Smm failure(msg); 57228753Smm assertFileNLinks("file2", 1); 58228753Smm 59228753Smm /* dir */ 60228753Smm assertIsDir("dir", 0775); 61228753Smm} 62228753Smm 63228753Smmstatic void 64228753Smmbasic_cpio(const char *target, 65228753Smm const char *pack_options, 66228753Smm const char *unpack_options, 67232153Smm const char *se, const char *se2) 68228753Smm{ 69228753Smm int r; 70228753Smm 71228753Smm if (!assertMakeDir(target, 0775)) 72228753Smm return; 73228753Smm 74228753Smm /* Use the cpio program to create an archive. */ 75228753Smm r = systemf("%s -o %s < filelist >%s/archive 2>%s/pack.err", 76228753Smm testprog, pack_options, target, target); 77228753Smm failure("Error invoking %s -o %s", testprog, pack_options); 78228753Smm assertEqualInt(r, 0); 79228753Smm 80228753Smm assertChdir(target); 81228753Smm 82228753Smm /* Verify stderr. */ 83228753Smm failure("Expected: %s, options=%s", se, pack_options); 84228753Smm assertTextFileContents(se, "pack.err"); 85228753Smm 86228753Smm /* 87228753Smm * Use cpio to unpack the archive into another directory. 88228753Smm */ 89228753Smm r = systemf("%s -i %s< archive >unpack.out 2>unpack.err", 90228753Smm testprog, unpack_options); 91228753Smm failure("Error invoking %s -i %s", testprog, unpack_options); 92228753Smm assertEqualInt(r, 0); 93228753Smm 94228753Smm /* Verify stderr. */ 95228753Smm failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target); 96232153Smm assertTextFileContents(se2, "unpack.err"); 97228753Smm 98228753Smm verify_files(pack_options); 99228753Smm 100228753Smm assertChdir(".."); 101228753Smm} 102228753Smm 103228753Smmstatic void 104228753Smmpassthrough(const char *target) 105228753Smm{ 106228753Smm int r; 107228753Smm 108228753Smm if (!assertMakeDir(target, 0775)) 109228753Smm return; 110228753Smm 111228753Smm /* 112228753Smm * Use cpio passthrough mode to copy files to another directory. 113228753Smm */ 114228753Smm r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr", 115228753Smm testprog, target, target, target); 116228753Smm failure("Error invoking %s -p", testprog); 117228753Smm assertEqualInt(r, 0); 118228753Smm 119228753Smm assertChdir(target); 120228753Smm 121228753Smm /* Verify stderr. */ 122228753Smm failure("Error invoking %s -p in dir %s", 123228753Smm testprog, target); 124228753Smm assertTextFileContents("1 block\n", "stderr"); 125228753Smm 126228753Smm verify_files("passthrough"); 127228753Smm assertChdir(".."); 128228753Smm} 129228753Smm 130228753SmmDEFINE_TEST(test_basic) 131228753Smm{ 132228753Smm FILE *filelist; 133228753Smm const char *msg; 134232153Smm char result[1024]; 135228753Smm 136228753Smm assertUmask(0); 137228753Smm 138228753Smm /* 139228753Smm * Create an assortment of files on disk. 140228753Smm */ 141228753Smm filelist = fopen("filelist", "w"); 142232153Smm memset(result, 0, sizeof(result)); 143228753Smm 144228753Smm /* File with 10 bytes content. */ 145228753Smm assertMakeFile("file", 0644, "1234567890"); 146228753Smm fprintf(filelist, "file\n"); 147232153Smm if (is_LargeInode("file")) 148232153Smm strncat(result, 149232153Smm "bsdcpio: file: large inode number truncated: " 150232153Smm "Numerical result out of range\n", 151248616Smm sizeof(result) - strlen(result) -1); 152228753Smm 153228753Smm /* hardlink to above file. */ 154228753Smm assertMakeHardlink("linkfile", "file"); 155228753Smm fprintf(filelist, "linkfile\n"); 156232153Smm if (is_LargeInode("linkfile")) 157232153Smm strncat(result, 158232153Smm "bsdcpio: linkfile: large inode number truncated: " 159232153Smm "Numerical result out of range\n", 160248616Smm sizeof(result) - strlen(result) -1); 161228753Smm 162228753Smm /* Symlink to above file. */ 163228753Smm if (canSymlink()) { 164228753Smm assertMakeSymlink("symlink", "file"); 165228753Smm fprintf(filelist, "symlink\n"); 166232153Smm if (is_LargeInode("symlink")) 167232153Smm strncat(result, 168232153Smm "bsdcpio: symlink: large inode number truncated: " 169232153Smm "Numerical result out of range\n", 170248616Smm sizeof(result) - strlen(result) -1); 171228753Smm } 172228753Smm 173228753Smm /* Another file with different permissions. */ 174228753Smm assertMakeFile("file2", 0777, "1234567890"); 175228753Smm fprintf(filelist, "file2\n"); 176232153Smm if (is_LargeInode("file2")) 177232153Smm strncat(result, 178232153Smm "bsdcpio: file2: large inode number truncated: " 179232153Smm "Numerical result out of range\n", 180248616Smm sizeof(result) - strlen(result) -1); 181228753Smm 182228753Smm /* Directory. */ 183228753Smm assertMakeDir("dir", 0775); 184228753Smm fprintf(filelist, "dir\n"); 185232153Smm if (is_LargeInode("dir")) 186232153Smm strncat(result, 187232153Smm "bsdcpio: dir: large inode number truncated: " 188232153Smm "Numerical result out of range\n", 189248616Smm sizeof(result) - strlen(result) -1); 190248616Smm strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1); 191232153Smm 192228753Smm /* All done. */ 193228753Smm fclose(filelist); 194228753Smm 195228753Smm assertUmask(022); 196228753Smm 197228753Smm /* Archive/dearchive with a variety of options. */ 198228753Smm msg = canSymlink() ? "2 blocks\n" : "1 block\n"; 199232153Smm basic_cpio("copy", "", "", msg, msg); 200232153Smm basic_cpio("copy_odc", "--format=odc", "", msg, msg); 201232153Smm basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n"); 202232153Smm basic_cpio("copy_cpio", "-H odc", "", msg, msg); 203228753Smm msg = canSymlink() ? "9 blocks\n" : "8 blocks\n"; 204232153Smm basic_cpio("copy_ustar", "-H ustar", "", msg, msg); 205228753Smm 206228753Smm /* Copy in one step using -p */ 207228753Smm passthrough("passthrough"); 208228753Smm} 209