1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * Copyright (c) 2011-2012 Michihiro NAKAJIMA 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 #include "test.h" 27 __FBSDID("$FreeBSD$"); 28 29 static void 30 test_read_format_mtree1(void) 31 { 32 const char reffile[] = "test_read_format_mtree.mtree"; 33 char buff[16]; 34 struct archive_entry *ae; 35 struct archive *a; 36 FILE *f; 37 /* Compute max 64-bit signed twos-complement value 38 * without relying on overflow. This assumes that long long 39 * is at least 64 bits. */ 40 static const long long max_int64 = ((((long long)1) << 62) - 1) + (((long long)1) << 62); 41 time_t min_time; 42 volatile time_t t; 43 44 extract_reference_file(reffile); 45 46 /* 47 * An access error occurred on some platform when mtree 48 * format handling open a directory. It is for through 49 * the routine which open a directory that we create 50 * "dir" and "dir2" directories. 51 */ 52 assertMakeDir("dir", 0775); 53 assertMakeDir("dir2", 0775); 54 55 assert((a = archive_read_new()) != NULL); 56 assertEqualIntA(a, ARCHIVE_OK, 57 archive_read_support_filter_all(a)); 58 assertEqualIntA(a, ARCHIVE_OK, 59 archive_read_support_format_all(a)); 60 assertEqualIntA(a, ARCHIVE_OK, 61 archive_read_open_filename(a, reffile, 11)); 62 63 /* 64 * Read "file", whose data is available on disk. 65 */ 66 f = fopen("file", "wb"); 67 assert(f != NULL); 68 assertEqualInt(3, fwrite("hi\n", 1, 3, f)); 69 fclose(f); 70 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 71 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); 72 assertEqualString(archive_entry_pathname(ae), "file"); 73 assertEqualInt(archive_entry_uid(ae), 18); 74 assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 75 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); 76 assertEqualInt(archive_entry_size(ae), 3); 77 assertEqualInt(3, archive_read_data(a, buff, 3)); 78 assertEqualMem(buff, "hi\n", 3); 79 80 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 81 assertEqualString(archive_entry_pathname(ae), "dir"); 82 assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); 83 84 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 85 assertEqualString(archive_entry_pathname(ae), "dir/file with space"); 86 87 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 88 assertEqualString(archive_entry_pathname(ae), "file with space"); 89 90 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 91 assertEqualString(archive_entry_pathname(ae), "dir2"); 92 93 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 94 assertEqualString(archive_entry_pathname(ae), "dir2/dir3a"); 95 96 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 97 assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a"); 98 99 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 100 assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2"); 101 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 102 103 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 104 assertEqualString(archive_entry_pathname(ae), "dir2/indir2"); 105 106 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 107 assertEqualString(archive_entry_pathname(ae), "dir2/dir3b"); 108 109 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 110 assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b"); 111 112 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 113 assertEqualString(archive_entry_pathname(ae), "notindir"); 114 115 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 116 assertEqualString(archive_entry_pathname(ae), "dir2/emptyfile"); 117 assertEqualInt(archive_entry_size(ae), 0); 118 119 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 120 assertEqualString(archive_entry_pathname(ae), "dir2/smallfile"); 121 assertEqualInt(archive_entry_size(ae), 1); 122 123 /* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */ 124 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 125 assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile"); 126 assertEqualInt(archive_entry_size(ae), -1); 127 128 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 129 assertEqualString(archive_entry_pathname(ae), "dir2/bigfile"); 130 assertEqualInt(archive_entry_size(ae), max_int64); 131 132 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 133 assertEqualString(archive_entry_pathname(ae), "dir2/toobigfile"); 134 /* Size in mtree is max_int64 + 1; should return max_int64. */ 135 assertEqualInt(archive_entry_size(ae), max_int64); 136 137 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 138 assertEqualString(archive_entry_pathname(ae), "dir2/veryoldfile"); 139 /* The value in the file is MIN_INT64_T, but time_t may be narrower. */ 140 /* Verify min_time is the smallest possible time_t. */ 141 min_time = archive_entry_mtime(ae); 142 assert(min_time <= 0); 143 /* Simply asserting min_time - 1 > 0 breaks with some compiler optimizations. */ 144 t = min_time - 1; 145 assert(t > 0); 146 147 /* toooldfile is 1 sec older, which should overflow and get returned 148 * with the same value. */ 149 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 150 assertEqualString(archive_entry_pathname(ae), "dir2/toooldfile"); 151 assertEqualInt(archive_entry_mtime(ae), min_time); 152 153 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 154 assertEqualInt(19, archive_file_count(a)); 155 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 156 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 157 } 158 159 static void 160 test_read_format_mtree2(void) 161 { 162 static char archive[] = 163 "#mtree\n" 164 "d type=dir content=.\n"; 165 struct archive_entry *ae; 166 struct archive *a; 167 168 assert((a = archive_read_new()) != NULL); 169 assertEqualIntA(a, ARCHIVE_OK, 170 archive_read_support_filter_all(a)); 171 assertEqualIntA(a, ARCHIVE_OK, 172 archive_read_support_format_all(a)); 173 assertEqualIntA(a, ARCHIVE_OK, 174 archive_read_open_memory(a, archive, sizeof(archive))); 175 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 176 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); 177 assertEqualString(archive_entry_pathname(ae), "d"); 178 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 179 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 180 assertEqualInt(1, archive_file_count(a)); 181 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 182 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 183 } 184 185 /* 186 * Reported to libarchive.googlecode.com as Issue 121. 187 */ 188 static void 189 test_read_format_mtree3(void) 190 { 191 static char archive[] = 192 "#mtree\n" 193 "a type=file contents=file\n" 194 "b type=link link=a\n" 195 "c type=file contents=file\n"; 196 struct archive_entry *ae; 197 struct archive *a; 198 199 assertMakeDir("mtree3", 0777); 200 assertChdir("mtree3"); 201 assertMakeFile("file", 0644, "file contents"); 202 203 assert((a = archive_read_new()) != NULL); 204 assertEqualIntA(a, ARCHIVE_OK, 205 archive_read_support_filter_all(a)); 206 assertEqualIntA(a, ARCHIVE_OK, 207 archive_read_support_format_all(a)); 208 assertEqualIntA(a, ARCHIVE_OK, 209 archive_read_open_memory(a, archive, sizeof(archive))); 210 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 211 assertEqualString(archive_entry_pathname(ae), "a"); 212 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 213 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 214 assertEqualString(archive_entry_pathname(ae), "b"); 215 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 216 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 217 assertEqualString(archive_entry_pathname(ae), "c"); 218 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 219 220 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 221 assertEqualInt(3, archive_file_count(a)); 222 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 223 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 224 225 assertChdir(".."); 226 } 227 228 DEFINE_TEST(test_read_format_mtree) 229 { 230 test_read_format_mtree1(); 231 test_read_format_mtree2(); 232 test_read_format_mtree3(); 233 } 234 235 DEFINE_TEST(test_read_format_mtree_filenames_only) 236 { 237 static char archive[] = 238 "/set type=file mode=0644\n" 239 "./a\n" 240 "./b\n" 241 "./c\n" 242 "./d\n" 243 "./e\n" 244 "./f mode=0444\n"; 245 struct archive_entry *ae; 246 struct archive *a; 247 248 assertMakeFile("file", 0644, "file contents"); 249 250 assert((a = archive_read_new()) != NULL); 251 assertEqualIntA(a, ARCHIVE_OK, 252 archive_read_support_filter_all(a)); 253 assertEqualIntA(a, ARCHIVE_OK, 254 archive_read_support_format_all(a)); 255 assertEqualIntA(a, ARCHIVE_OK, 256 archive_read_open_memory(a, archive, sizeof(archive))); 257 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 258 assertEqualString(archive_entry_pathname(ae), "./a"); 259 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 260 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 261 assertEqualString(archive_entry_pathname(ae), "./b"); 262 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 263 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 264 assertEqualString(archive_entry_pathname(ae), "./c"); 265 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 266 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 267 assertEqualString(archive_entry_pathname(ae), "./d"); 268 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 269 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 270 assertEqualString(archive_entry_pathname(ae), "./e"); 271 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 272 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 273 assertEqualString(archive_entry_pathname(ae), "./f"); 274 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444); 275 276 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 277 assertEqualInt(6, archive_file_count(a)); 278 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 279 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 280 } 281 282 DEFINE_TEST(test_read_format_mtree_nochange) 283 { 284 static char archive[] = 285 "#mtree\n" 286 "./a type=file mode=0644 time=123\n" 287 "./b type=file mode=0644 time=234\n" 288 "./c type=file mode=0644 time=345\n"; 289 static char archive2[] = 290 "#mtree\n" 291 "./a type=file mode=0644 time=123 nochange\n" 292 "./b type=file mode=0644 time=234\n" 293 "./c type=file mode=0644 time=345 nochange\n"; 294 struct archive_entry *ae; 295 struct archive *a; 296 297 assertMakeFile("a", 0640, "12345"); 298 assertMakeFile("b", 0664, "123456"); 299 assertMakeFile("c", 0755, "1234567"); 300 301 /* 302 * Test 1. Read a mtree archive without `nochange' keyword. 303 */ 304 assert((a = archive_read_new()) != NULL); 305 assertEqualIntA(a, ARCHIVE_OK, 306 archive_read_support_filter_all(a)); 307 assertEqualIntA(a, ARCHIVE_OK, 308 archive_read_support_format_all(a)); 309 assertEqualIntA(a, ARCHIVE_OK, 310 archive_read_open_memory(a, archive, sizeof(archive))); 311 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 312 assertEqualString(archive_entry_pathname(ae), "./a"); 313 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 314 assertEqualInt(archive_entry_mtime(ae), 123); 315 assertEqualInt(archive_entry_size(ae), 5); 316 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 317 assertEqualString(archive_entry_pathname(ae), "./b"); 318 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 319 assertEqualInt(archive_entry_mtime(ae), 234); 320 assertEqualInt(archive_entry_size(ae), 6); 321 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 322 assertEqualString(archive_entry_pathname(ae), "./c"); 323 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 324 assertEqualInt(archive_entry_mtime(ae), 345); 325 assertEqualInt(archive_entry_size(ae), 7); 326 327 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 328 assertEqualInt(3, archive_file_count(a)); 329 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 330 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 331 332 /* 333 * Test 2. Read a mtree archive with `nochange' keyword. 334 */ 335 assert((a = archive_read_new()) != NULL); 336 assertEqualIntA(a, ARCHIVE_OK, 337 archive_read_support_filter_all(a)); 338 assertEqualIntA(a, ARCHIVE_OK, 339 archive_read_support_format_all(a)); 340 assertEqualIntA(a, ARCHIVE_OK, 341 archive_read_open_memory(a, archive2, sizeof(archive2))); 342 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 343 assertEqualString(archive_entry_pathname(ae), "./a"); 344 #if !defined(_WIN32) || defined(__CYGWIN__) 345 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0640); 346 #endif 347 assert(archive_entry_mtime(ae) != 123); 348 assertEqualInt(archive_entry_size(ae), 5); 349 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 350 assertEqualString(archive_entry_pathname(ae), "./b"); 351 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 352 assertEqualInt(archive_entry_mtime(ae), 234); 353 assertEqualInt(archive_entry_size(ae), 6); 354 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 355 assertEqualString(archive_entry_pathname(ae), "./c"); 356 #if !defined(_WIN32) || defined(__CYGWIN__) 357 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0755); 358 #endif 359 assert(archive_entry_mtime(ae) != 345); 360 assertEqualInt(archive_entry_size(ae), 7); 361 362 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 363 assertEqualInt(3, archive_file_count(a)); 364 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 365 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 366 } 367 368 DEFINE_TEST(test_read_format_mtree_nomagic_v1_form) 369 { 370 const char reffile[] = "test_read_format_mtree_nomagic.mtree"; 371 char buff[16]; 372 struct archive_entry *ae; 373 struct archive *a; 374 FILE *f; 375 376 extract_reference_file(reffile); 377 378 assert((a = archive_read_new()) != NULL); 379 assertEqualIntA(a, ARCHIVE_OK, 380 archive_read_support_filter_all(a)); 381 assertEqualIntA(a, ARCHIVE_OK, 382 archive_read_support_format_all(a)); 383 assertEqualIntA(a, ARCHIVE_OK, 384 archive_read_open_filename(a, reffile, 11)); 385 386 /* 387 * Read "file", whose data is available on disk. 388 */ 389 f = fopen("file", "wb"); 390 assert(f != NULL); 391 assertEqualInt(3, fwrite("hi\n", 1, 3, f)); 392 fclose(f); 393 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 394 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); 395 assertEqualString(archive_entry_pathname(ae), "file"); 396 assertEqualInt(archive_entry_uid(ae), 18); 397 assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 398 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); 399 assertEqualInt(archive_entry_size(ae), 3); 400 assertEqualInt(3, archive_read_data(a, buff, 3)); 401 assertEqualMem(buff, "hi\n", 3); 402 403 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 404 assertEqualString(archive_entry_pathname(ae), "dir"); 405 assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); 406 407 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 408 assertEqualString(archive_entry_pathname(ae), "dir/file with space"); 409 410 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 411 assertEqualString(archive_entry_pathname(ae), "file with space"); 412 413 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 414 assertEqualString(archive_entry_pathname(ae), "dir2"); 415 416 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 417 assertEqualString(archive_entry_pathname(ae), "dir2/dir3a"); 418 419 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 420 assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a"); 421 422 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 423 assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2"); 424 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 425 426 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 427 assertEqualString(archive_entry_pathname(ae), "dir2/indir2"); 428 429 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 430 assertEqualString(archive_entry_pathname(ae), "dir2/dir3b"); 431 432 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 433 assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b"); 434 435 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 436 assertEqualString(archive_entry_pathname(ae), "notindir"); 437 438 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 439 assertEqualInt(12, archive_file_count(a)); 440 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 441 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 442 } 443 444 /* 445 * Test for a format that NetBSD mtree -C generates. 446 */ 447 DEFINE_TEST(test_read_format_mtree_nomagic_v2_form) 448 { 449 const char reffile[] = "test_read_format_mtree_nomagic2.mtree"; 450 char buff[16]; 451 struct archive_entry *ae; 452 struct archive *a; 453 FILE *f; 454 455 extract_reference_file(reffile); 456 457 assert((a = archive_read_new()) != NULL); 458 assertEqualIntA(a, ARCHIVE_OK, 459 archive_read_support_filter_all(a)); 460 assertEqualIntA(a, ARCHIVE_OK, 461 archive_read_support_format_all(a)); 462 assertEqualIntA(a, ARCHIVE_OK, 463 archive_read_open_filename(a, reffile, 11)); 464 465 /* 466 * Read "file", whose data is available on disk. 467 */ 468 f = fopen("file", "wb"); 469 assert(f != NULL); 470 assertEqualInt(3, fwrite("hi\n", 1, 3, f)); 471 fclose(f); 472 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 473 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); 474 assertEqualString(archive_entry_pathname(ae), "./file"); 475 assertEqualInt(archive_entry_uid(ae), 18); 476 assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 477 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); 478 assertEqualInt(archive_entry_size(ae), 3); 479 assertEqualInt(3, archive_read_data(a, buff, 3)); 480 assertEqualMem(buff, "hi\n", 3); 481 482 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 483 assertEqualString(archive_entry_pathname(ae), "./dir"); 484 assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); 485 486 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 487 assertEqualString(archive_entry_pathname(ae), "./dir/file with space"); 488 assertEqualInt(archive_entry_uid(ae), 18); 489 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 490 491 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 492 assertEqualString(archive_entry_pathname(ae), "./file with space"); 493 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 494 495 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 496 assertEqualString(archive_entry_pathname(ae), "./dir2"); 497 assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); 498 499 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 500 assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a"); 501 assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); 502 503 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 504 assertEqualInt(6, archive_file_count(a)); 505 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 506 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 507 } 508 509 /* 510 * Test for a format that NetBSD mtree -D generates. 511 */ 512 DEFINE_TEST(test_read_format_mtree_nomagic_v2_netbsd_form) 513 { 514 const char reffile[] = "test_read_format_mtree_nomagic3.mtree"; 515 char buff[16]; 516 struct archive_entry *ae; 517 struct archive *a; 518 FILE *f; 519 520 extract_reference_file(reffile); 521 522 assert((a = archive_read_new()) != NULL); 523 assertEqualIntA(a, ARCHIVE_OK, 524 archive_read_support_filter_all(a)); 525 assertEqualIntA(a, ARCHIVE_OK, 526 archive_read_support_format_all(a)); 527 assertEqualIntA(a, ARCHIVE_OK, 528 archive_read_open_filename(a, reffile, 11)); 529 530 /* 531 * Read "file", whose data is available on disk. 532 */ 533 f = fopen("file", "wb"); 534 assert(f != NULL); 535 assertEqualInt(3, fwrite("hi\n", 1, 3, f)); 536 fclose(f); 537 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 538 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); 539 assertEqualString(archive_entry_pathname(ae), "./file"); 540 assertEqualInt(archive_entry_uid(ae), 18); 541 assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 542 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); 543 assertEqualInt(archive_entry_size(ae), 3); 544 assertEqualInt(3, archive_read_data(a, buff, 3)); 545 assertEqualMem(buff, "hi\n", 3); 546 547 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 548 assertEqualString(archive_entry_pathname(ae), "./dir"); 549 assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); 550 551 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 552 assertEqualString(archive_entry_pathname(ae), "./dir/file with space"); 553 assertEqualInt(archive_entry_uid(ae), 18); 554 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 555 556 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 557 assertEqualString(archive_entry_pathname(ae), "./file with space"); 558 assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); 559 560 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 561 assertEqualString(archive_entry_pathname(ae), "./dir2"); 562 assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); 563 564 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 565 assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a"); 566 assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); 567 568 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 569 assertEqualInt(6, archive_file_count(a)); 570 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 571 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 572 } 573 574 /* 575 * We should get a warning if the contents file doesn't exist. 576 */ 577 DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file) 578 { 579 static char archive[] = 580 "#mtree\n" 581 "a type=file contents=nonexistent_file\n"; 582 struct archive_entry *ae; 583 struct archive *a; 584 585 assert((a = archive_read_new()) != NULL); 586 assertEqualIntA(a, ARCHIVE_OK, 587 archive_read_support_filter_all(a)); 588 assertEqualIntA(a, ARCHIVE_OK, 589 archive_read_support_format_all(a)); 590 assertEqualIntA(a, ARCHIVE_OK, 591 archive_read_open_memory(a, archive, sizeof(archive))); 592 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 593 assert(strlen(archive_error_string(a)) > 0); 594 assertEqualString(archive_entry_pathname(ae), "a"); 595 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 596 597 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 598 assertEqualInt(1, archive_file_count(a)); 599 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 600 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 601 } 602 603