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 28static void test_linkify_tar(void) 29{ 30 struct archive_entry *entry, *e2; 31 struct archive_entry_linkresolver *resolver; 32 33 /* Initialize the resolver. */ 34 assert(NULL != (resolver = archive_entry_linkresolver_new())); 35 archive_entry_linkresolver_set_strategy(resolver, 36 ARCHIVE_FORMAT_TAR_USTAR); 37 38 /* Create an entry with only 1 link and try to linkify it. */ 39 assert(NULL != (entry = archive_entry_new())); 40 archive_entry_set_pathname(entry, "test1"); 41 archive_entry_set_ino(entry, 1); 42 archive_entry_set_dev(entry, 2); 43 archive_entry_set_nlink(entry, 1); 44 archive_entry_set_size(entry, 10); 45 archive_entry_linkify(resolver, &entry, &e2); 46 47 /* Shouldn't have been changed. */ 48 assert(e2 == NULL); 49 assertEqualInt(10, archive_entry_size(entry)); 50 assertEqualString("test1", archive_entry_pathname(entry)); 51 52 /* Now, try again with an entry that has 2 links. */ 53 archive_entry_set_pathname(entry, "test2"); 54 archive_entry_set_nlink(entry, 2); 55 archive_entry_set_ino(entry, 2); 56 archive_entry_linkify(resolver, &entry, &e2); 57 /* Shouldn't be altered, since it wasn't seen before. */ 58 assert(e2 == NULL); 59 assertEqualString("test2", archive_entry_pathname(entry)); 60 assertEqualString(NULL, archive_entry_hardlink(entry)); 61 assertEqualInt(10, archive_entry_size(entry)); 62 63 /* Match again and make sure it does get altered. */ 64 archive_entry_linkify(resolver, &entry, &e2); 65 assert(e2 == NULL); 66 assertEqualString("test2", archive_entry_pathname(entry)); 67 assertEqualString("test2", archive_entry_hardlink(entry)); 68 assertEqualInt(0, archive_entry_size(entry)); 69 70 71 /* Dirs should never be matched as hardlinks, regardless. */ 72 archive_entry_set_pathname(entry, "test3"); 73 archive_entry_set_nlink(entry, 2); 74 archive_entry_set_filetype(entry, AE_IFDIR); 75 archive_entry_set_ino(entry, 3); 76 archive_entry_set_hardlink(entry, NULL); 77 archive_entry_linkify(resolver, &entry, &e2); 78 /* Shouldn't be altered, since it wasn't seen before. */ 79 assert(e2 == NULL); 80 assertEqualString("test3", archive_entry_pathname(entry)); 81 assertEqualString(NULL, archive_entry_hardlink(entry)); 82 83 /* Dir, so it shouldn't get matched. */ 84 archive_entry_linkify(resolver, &entry, &e2); 85 assert(e2 == NULL); 86 assertEqualString("test3", archive_entry_pathname(entry)); 87 assertEqualString(NULL, archive_entry_hardlink(entry)); 88 89 archive_entry_free(entry); 90 archive_entry_linkresolver_free(resolver); 91} 92 93static void test_linkify_old_cpio(void) 94{ 95 struct archive_entry *entry, *e2; 96 struct archive_entry_linkresolver *resolver; 97 98 /* Initialize the resolver. */ 99 assert(NULL != (resolver = archive_entry_linkresolver_new())); 100 archive_entry_linkresolver_set_strategy(resolver, 101 ARCHIVE_FORMAT_CPIO_POSIX); 102 103 /* Create an entry with 2 link and try to linkify it. */ 104 assert(NULL != (entry = archive_entry_new())); 105 archive_entry_set_pathname(entry, "test1"); 106 archive_entry_set_ino(entry, 1); 107 archive_entry_set_dev(entry, 2); 108 archive_entry_set_nlink(entry, 2); 109 archive_entry_set_size(entry, 10); 110 archive_entry_linkify(resolver, &entry, &e2); 111 112 /* Shouldn't have been changed. */ 113 assert(e2 == NULL); 114 assertEqualInt(10, archive_entry_size(entry)); 115 assertEqualString("test1", archive_entry_pathname(entry)); 116 117 /* Still shouldn't be matched. */ 118 archive_entry_linkify(resolver, &entry, &e2); 119 assert(e2 == NULL); 120 assertEqualString("test1", archive_entry_pathname(entry)); 121 assertEqualString(NULL, archive_entry_hardlink(entry)); 122 assertEqualInt(10, archive_entry_size(entry)); 123 124 archive_entry_free(entry); 125 archive_entry_linkresolver_free(resolver); 126} 127 128static void test_linkify_new_cpio(void) 129{ 130 struct archive_entry *entry, *e2; 131 struct archive_entry_linkresolver *resolver; 132 133 /* Initialize the resolver. */ 134 assert(NULL != (resolver = archive_entry_linkresolver_new())); 135 archive_entry_linkresolver_set_strategy(resolver, 136 ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); 137 138 /* Create an entry with only 1 link and try to linkify it. */ 139 assert(NULL != (entry = archive_entry_new())); 140 archive_entry_set_pathname(entry, "test1"); 141 archive_entry_set_ino(entry, 1); 142 archive_entry_set_dev(entry, 2); 143 archive_entry_set_nlink(entry, 1); 144 archive_entry_set_size(entry, 10); 145 archive_entry_linkify(resolver, &entry, &e2); 146 147 /* Shouldn't have been changed. */ 148 assert(e2 == NULL); 149 assertEqualInt(10, archive_entry_size(entry)); 150 assertEqualString("test1", archive_entry_pathname(entry)); 151 152 /* Now, try again with an entry that has 3 links. */ 153 archive_entry_set_pathname(entry, "test2"); 154 archive_entry_set_nlink(entry, 3); 155 archive_entry_set_ino(entry, 2); 156 archive_entry_linkify(resolver, &entry, &e2); 157 158 /* First time, it just gets swallowed. */ 159 assert(entry == NULL); 160 assert(e2 == NULL); 161 162 /* Match again. */ 163 assert(NULL != (entry = archive_entry_new())); 164 archive_entry_set_pathname(entry, "test3"); 165 archive_entry_set_ino(entry, 2); 166 archive_entry_set_dev(entry, 2); 167 archive_entry_set_nlink(entry, 2); 168 archive_entry_set_size(entry, 10); 169 archive_entry_linkify(resolver, &entry, &e2); 170 171 /* Should get back "test2" and nothing else. */ 172 assertEqualString("test2", archive_entry_pathname(entry)); 173 assertEqualInt(0, archive_entry_size(entry)); 174 archive_entry_free(entry); 175 assert(NULL == e2); 176 archive_entry_free(e2); /* This should be a no-op. */ 177 178 /* Match a third time. */ 179 assert(NULL != (entry = archive_entry_new())); 180 archive_entry_set_pathname(entry, "test4"); 181 archive_entry_set_ino(entry, 2); 182 archive_entry_set_dev(entry, 2); 183 archive_entry_set_nlink(entry, 3); 184 archive_entry_set_size(entry, 10); 185 archive_entry_linkify(resolver, &entry, &e2); 186 187 /* Should get back "test3". */ 188 assertEqualString("test3", archive_entry_pathname(entry)); 189 assertEqualInt(0, archive_entry_size(entry)); 190 191 /* Since "test4" was the last link, should get it back also. */ 192 assertEqualString("test4", archive_entry_pathname(e2)); 193 assertEqualInt(10, archive_entry_size(e2)); 194 195 archive_entry_free(entry); 196 archive_entry_free(e2); 197 archive_entry_linkresolver_free(resolver); 198} 199 200DEFINE_TEST(test_link_resolver) 201{ 202 test_linkify_tar(); 203 test_linkify_old_cpio(); 204 test_linkify_new_cpio(); 205} 206