1/*- 2 * Copyright (c) 2010-2012 Michihiro NAKAJIMA 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#include <limits.h> 29#if defined(_WIN32) && !defined(__CYGWIN__) 30# if !defined(__BORLANDC__) 31# define getcwd _getcwd 32# endif 33#endif 34 35/* 36 * Test if the current filesystem is mounted with noatime option. 37 */ 38static int 39atimeIsUpdated(void) 40{ 41 const char *fn = "fs_noatime"; 42 struct stat st; 43#if defined(_WIN32) && !defined(CYGWIN) 44 char *buff = NULL; 45 char *ptr; 46 int r; 47 48 r = systemf("fsutil behavior query disableLastAccess > query_atime"); 49 if (r == 0) { 50 buff = slurpfile(NULL, "query_atime"); 51 if (buff != NULL) { 52 ptr = buff; 53 while(*ptr != '\0' && !isdigit(*ptr)) { 54 ptr++; 55 } 56 if (*ptr == '0') { 57 free(buff); 58 return(1); 59 } else if (*ptr == '1' || *ptr == '2') { 60 free(buff); 61 return(0); 62 } 63 free(buff); 64 } 65 } 66#endif 67 if (!assertMakeFile(fn, 0666, "a")) 68 return (0); 69 if (!assertUtimes(fn, 1, 0, 1, 0)) 70 return (0); 71 /* Test the file contents in order to update its atime. */ 72 if (!assertTextFileContents("a", fn)) 73 return (0); 74 if (stat(fn, &st) != 0) 75 return (0); 76 /* Is atime updated? */ 77 if (st.st_atime > 1) 78 return (1); 79 return (0); 80} 81 82static void 83test_basic(void) 84{ 85 struct archive *a; 86 struct archive_entry *ae; 87 const void *p; 88 char *initial_cwd, *cwd; 89 size_t size; 90 int64_t offset; 91 int file_count; 92#if defined(_WIN32) && !defined(__CYGWIN__) 93 wchar_t *wcwd, *wp, *fullpath; 94#endif 95 96 assertMakeDir("dir1", 0755); 97 assertMakeFile("dir1/file1", 0644, "0123456789"); 98 assertMakeFile("dir1/file2", 0644, "hello world"); 99 assertMakeDir("dir1/sub1", 0755); 100 assertMakeFile("dir1/sub1/file1", 0644, "0123456789"); 101 assertMakeDir("dir1/sub2", 0755); 102 assertMakeFile("dir1/sub2/file1", 0644, "0123456789"); 103 assertMakeFile("dir1/sub2/file2", 0644, "0123456789"); 104 assertMakeDir("dir1/sub2/sub1", 0755); 105 assertMakeDir("dir1/sub2/sub2", 0755); 106 assertMakeDir("dir1/sub2/sub3", 0755); 107 assertMakeFile("dir1/sub2/sub3/file", 0644, "xyz"); 108 file_count = 12; 109 110 assert((ae = archive_entry_new()) != NULL); 111 assert((a = archive_read_disk_new()) != NULL); 112 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); 113 114 while (file_count--) { 115 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 116 if (strcmp(archive_entry_pathname(ae), "dir1") == 0) { 117 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 118 assertEqualInt(1, archive_read_disk_can_descend(a)); 119 } else if (strcmp(archive_entry_pathname(ae), 120 "dir1/file1") == 0) { 121 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 122 assertEqualInt(archive_entry_size(ae), 10); 123 assertEqualIntA(a, ARCHIVE_OK, 124 archive_read_data_block(a, &p, &size, &offset)); 125 assertEqualInt((int)size, 10); 126 assertEqualInt((int)offset, 0); 127 assertEqualMem(p, "0123456789", 10); 128 assertEqualInt(ARCHIVE_EOF, 129 archive_read_data_block(a, &p, &size, &offset)); 130 assertEqualInt((int)size, 0); 131 assertEqualInt((int)offset, 10); 132 assertEqualInt(0, archive_read_disk_can_descend(a)); 133 } else if (strcmp(archive_entry_pathname(ae), 134 "dir1/file2") == 0) { 135 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 136 assertEqualInt(archive_entry_size(ae), 11); 137 assertEqualIntA(a, ARCHIVE_OK, 138 archive_read_data_block(a, &p, &size, &offset)); 139 assertEqualInt((int)size, 11); 140 assertEqualInt((int)offset, 0); 141 assertEqualMem(p, "hello world", 11); 142 assertEqualInt(ARCHIVE_EOF, 143 archive_read_data_block(a, &p, &size, &offset)); 144 assertEqualInt((int)size, 0); 145 assertEqualInt((int)offset, 11); 146 assertEqualInt(0, archive_read_disk_can_descend(a)); 147 } else if (strcmp(archive_entry_pathname(ae), 148 "dir1/sub1") == 0) { 149 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 150 assertEqualInt(1, archive_read_disk_can_descend(a)); 151 } else if (strcmp(archive_entry_pathname(ae), 152 "dir1/sub1/file1") == 0) { 153 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 154 assertEqualInt(archive_entry_size(ae), 10); 155 assertEqualIntA(a, ARCHIVE_OK, 156 archive_read_data_block(a, &p, &size, &offset)); 157 assertEqualInt((int)size, 10); 158 assertEqualInt((int)offset, 0); 159 assertEqualMem(p, "0123456789", 10); 160 assertEqualInt(ARCHIVE_EOF, 161 archive_read_data_block(a, &p, &size, &offset)); 162 assertEqualInt((int)size, 0); 163 assertEqualInt((int)offset, 10); 164 assertEqualInt(0, archive_read_disk_can_descend(a)); 165 } else if (strcmp(archive_entry_pathname(ae), 166 "dir1/sub2") == 0) { 167 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 168 assertEqualInt(1, archive_read_disk_can_descend(a)); 169 } else if (strcmp(archive_entry_pathname(ae), 170 "dir1/sub2/file1") == 0) { 171 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 172 assertEqualInt(archive_entry_size(ae), 10); 173 assertEqualIntA(a, ARCHIVE_OK, 174 archive_read_data_block(a, &p, &size, &offset)); 175 assertEqualInt((int)size, 10); 176 assertEqualInt((int)offset, 0); 177 assertEqualMem(p, "0123456789", 10); 178 assertEqualInt(ARCHIVE_EOF, 179 archive_read_data_block(a, &p, &size, &offset)); 180 assertEqualInt((int)size, 0); 181 assertEqualInt((int)offset, 10); 182 assertEqualInt(0, archive_read_disk_can_descend(a)); 183 } else if (strcmp(archive_entry_pathname(ae), 184 "dir1/sub2/file2") == 0) { 185 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 186 assertEqualInt(archive_entry_size(ae), 10); 187 assertEqualIntA(a, ARCHIVE_OK, 188 archive_read_data_block(a, &p, &size, &offset)); 189 assertEqualInt((int)size, 10); 190 assertEqualInt((int)offset, 0); 191 assertEqualMem(p, "0123456789", 10); 192 assertEqualInt(ARCHIVE_EOF, 193 archive_read_data_block(a, &p, &size, &offset)); 194 assertEqualInt((int)size, 0); 195 assertEqualInt((int)offset, 10); 196 assertEqualInt(0, archive_read_disk_can_descend(a)); 197 } else if (strcmp(archive_entry_pathname(ae), 198 "dir1/sub2/sub1") == 0) { 199 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 200 assertEqualInt(1, archive_read_disk_can_descend(a)); 201 } else if (strcmp(archive_entry_pathname(ae), 202 "dir1/sub2/sub2") == 0) { 203 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 204 assertEqualInt(1, archive_read_disk_can_descend(a)); 205 } else if (strcmp(archive_entry_pathname(ae), 206 "dir1/sub2/sub3") == 0) { 207 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 208 assertEqualInt(1, archive_read_disk_can_descend(a)); 209 } else if (strcmp(archive_entry_pathname(ae), 210 "dir1/sub2/sub3/file") == 0) { 211 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 212 assertEqualInt(archive_entry_size(ae), 3); 213 assertEqualIntA(a, ARCHIVE_OK, 214 archive_read_data_block(a, &p, &size, &offset)); 215 assertEqualInt((int)size, 3); 216 assertEqualInt((int)offset, 0); 217 assertEqualMem(p, "xyz", 3); 218 assertEqualInt(ARCHIVE_EOF, 219 archive_read_data_block(a, &p, &size, &offset)); 220 assertEqualInt((int)size, 0); 221 assertEqualInt((int)offset, 3); 222 assertEqualInt(0, archive_read_disk_can_descend(a)); 223 } 224 if (archive_entry_filetype(ae) == AE_IFDIR) { 225 /* Descend into the current object */ 226 assertEqualIntA(a, ARCHIVE_OK, 227 archive_read_disk_descend(a)); 228 } 229 } 230 /* There is no entry. */ 231 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 232 233 /* Close the disk object. */ 234 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 235 236 /* 237 * Test that call archive_read_disk_open_w, wchar_t version. 238 */ 239 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, L"dir1")); 240 241 file_count = 12; 242 while (file_count--) { 243 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 244 if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) { 245 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 246 assertEqualInt(1, archive_read_disk_can_descend(a)); 247 } else if (wcscmp(archive_entry_pathname_w(ae), 248 L"dir1/file1") == 0) { 249 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 250 assertEqualInt(archive_entry_size(ae), 10); 251 assertEqualIntA(a, ARCHIVE_OK, 252 archive_read_data_block(a, &p, &size, &offset)); 253 assertEqualInt((int)size, 10); 254 assertEqualInt((int)offset, 0); 255 assertEqualMem(p, "0123456789", 10); 256 assertEqualInt(ARCHIVE_EOF, 257 archive_read_data_block(a, &p, &size, &offset)); 258 assertEqualInt((int)size, 0); 259 assertEqualInt((int)offset, 10); 260 assertEqualInt(0, archive_read_disk_can_descend(a)); 261 } else if (wcscmp(archive_entry_pathname_w(ae), 262 L"dir1/file2") == 0) { 263 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 264 assertEqualInt(archive_entry_size(ae), 11); 265 assertEqualIntA(a, ARCHIVE_OK, 266 archive_read_data_block(a, &p, &size, &offset)); 267 assertEqualInt((int)size, 11); 268 assertEqualInt((int)offset, 0); 269 assertEqualMem(p, "hello world", 11); 270 assertEqualInt(ARCHIVE_EOF, 271 archive_read_data_block(a, &p, &size, &offset)); 272 assertEqualInt((int)size, 0); 273 assertEqualInt((int)offset, 11); 274 assertEqualInt(0, archive_read_disk_can_descend(a)); 275 } else if (wcscmp(archive_entry_pathname_w(ae), 276 L"dir1/sub1") == 0) { 277 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 278 assertEqualInt(1, archive_read_disk_can_descend(a)); 279 } else if (wcscmp(archive_entry_pathname_w(ae), 280 L"dir1/sub1/file1") == 0) { 281 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 282 assertEqualInt(archive_entry_size(ae), 10); 283 assertEqualIntA(a, ARCHIVE_OK, 284 archive_read_data_block(a, &p, &size, &offset)); 285 assertEqualInt((int)size, 10); 286 assertEqualInt((int)offset, 0); 287 assertEqualMem(p, "0123456789", 10); 288 assertEqualInt(ARCHIVE_EOF, 289 archive_read_data_block(a, &p, &size, &offset)); 290 assertEqualInt((int)size, 0); 291 assertEqualInt((int)offset, 10); 292 assertEqualInt(0, archive_read_disk_can_descend(a)); 293 } else if (wcscmp(archive_entry_pathname_w(ae), 294 L"dir1/sub2") == 0) { 295 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 296 assertEqualInt(1, archive_read_disk_can_descend(a)); 297 } else if (wcscmp(archive_entry_pathname_w(ae), 298 L"dir1/sub2/file1") == 0) { 299 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 300 assertEqualInt(archive_entry_size(ae), 10); 301 assertEqualIntA(a, ARCHIVE_OK, 302 archive_read_data_block(a, &p, &size, &offset)); 303 assertEqualInt((int)size, 10); 304 assertEqualInt((int)offset, 0); 305 assertEqualMem(p, "0123456789", 10); 306 assertEqualInt(ARCHIVE_EOF, 307 archive_read_data_block(a, &p, &size, &offset)); 308 assertEqualInt((int)size, 0); 309 assertEqualInt((int)offset, 10); 310 assertEqualInt(0, archive_read_disk_can_descend(a)); 311 } else if (wcscmp(archive_entry_pathname_w(ae), 312 L"dir1/sub2/file2") == 0) { 313 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 314 assertEqualInt(archive_entry_size(ae), 10); 315 assertEqualIntA(a, ARCHIVE_OK, 316 archive_read_data_block(a, &p, &size, &offset)); 317 assertEqualInt((int)size, 10); 318 assertEqualInt((int)offset, 0); 319 assertEqualMem(p, "0123456789", 10); 320 assertEqualInt(ARCHIVE_EOF, 321 archive_read_data_block(a, &p, &size, &offset)); 322 assertEqualInt((int)size, 0); 323 assertEqualInt((int)offset, 10); 324 assertEqualInt(0, archive_read_disk_can_descend(a)); 325 } else if (wcscmp(archive_entry_pathname_w(ae), 326 L"dir1/sub2/sub1") == 0) { 327 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 328 assertEqualInt(1, archive_read_disk_can_descend(a)); 329 } else if (wcscmp(archive_entry_pathname_w(ae), 330 L"dir1/sub2/sub2") == 0) { 331 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 332 assertEqualInt(1, archive_read_disk_can_descend(a)); 333 } else if (wcscmp(archive_entry_pathname_w(ae), 334 L"dir1/sub2/sub3") == 0) { 335 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 336 assertEqualInt(1, archive_read_disk_can_descend(a)); 337 } else if (wcscmp(archive_entry_pathname_w(ae), 338 L"dir1/sub2/sub3/file") == 0) { 339 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 340 assertEqualInt(archive_entry_size(ae), 3); 341 assertEqualIntA(a, ARCHIVE_OK, 342 archive_read_data_block(a, &p, &size, &offset)); 343 assertEqualInt((int)size, 3); 344 assertEqualInt((int)offset, 0); 345 assertEqualMem(p, "xyz", 3); 346 assertEqualInt(ARCHIVE_EOF, 347 archive_read_data_block(a, &p, &size, &offset)); 348 assertEqualInt((int)size, 0); 349 assertEqualInt((int)offset, 3); 350 assertEqualInt(0, archive_read_disk_can_descend(a)); 351 } 352 if (archive_entry_filetype(ae) == AE_IFDIR) { 353 /* Descend into the current object */ 354 assertEqualIntA(a, ARCHIVE_OK, 355 archive_read_disk_descend(a)); 356 } 357 } 358 /* There is no entry. */ 359 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 360 361 /* Close the disk object. */ 362 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 363 364 /* 365 * Test that call archive_read_disk_open with a regular file. 366 */ 367 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/file1")); 368 369 /* dir1/file1 */ 370 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 371 assertEqualInt(0, archive_read_disk_can_descend(a)); 372 assertEqualString(archive_entry_pathname(ae), "dir1/file1"); 373 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 374 assertEqualInt(archive_entry_size(ae), 10); 375 assertEqualIntA(a, ARCHIVE_OK, 376 archive_read_data_block(a, &p, &size, &offset)); 377 assertEqualInt((int)size, 10); 378 assertEqualInt((int)offset, 0); 379 assertEqualMem(p, "0123456789", 10); 380 381 /* There is no entry. */ 382 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 383 384 /* Close the disk object. */ 385 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 386 387 388#if defined(_WIN32) && !defined(__CYGWIN__) 389 /* 390 * Test for wildcard '*' or '?' 391 */ 392 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/*1")); 393 394 /* dir1/file1 */ 395 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 396 assertEqualInt(0, archive_read_disk_can_descend(a)); 397 assertEqualString(archive_entry_pathname(ae), "dir1/file1"); 398 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 399 assertEqualInt(archive_entry_size(ae), 10); 400 assertEqualIntA(a, ARCHIVE_OK, 401 archive_read_data_block(a, &p, &size, &offset)); 402 assertEqualInt((int)size, 10); 403 assertEqualInt((int)offset, 0); 404 assertEqualMem(p, "0123456789", 10); 405 406 /* dir1/sub1 */ 407 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 408 assertEqualInt(1, archive_read_disk_can_descend(a)); 409 assertEqualString(archive_entry_pathname(ae), "dir1/sub1"); 410 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 411 412 /* Descend into the current object */ 413 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); 414 415 /* dir1/sub1/file1 */ 416 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 417 assertEqualInt(0, archive_read_disk_can_descend(a)); 418 assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1"); 419 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 420 assertEqualInt(archive_entry_size(ae), 10); 421 assertEqualIntA(a, ARCHIVE_OK, 422 archive_read_data_block(a, &p, &size, &offset)); 423 assertEqualInt((int)size, 10); 424 assertEqualInt((int)offset, 0); 425 assertEqualMem(p, "0123456789", 10); 426 427 /* There is no entry. */ 428 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 429 430 /* Close the disk object. */ 431 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 432 433 /* 434 * Test for a full-path beginning with "//?/" 435 */ 436 wcwd = _wgetcwd(NULL, 0); 437 fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); 438 wcscpy(fullpath, L"//?/"); 439 wcscat(fullpath, wcwd); 440 wcscat(fullpath, L"/dir1/file1"); 441 free(wcwd); 442 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); 443 while ((wcwd = wcschr(fullpath, L'\\')) != NULL) 444 *wcwd = L'/'; 445 446 /* dir1/file1 */ 447 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 448 assertEqualInt(0, archive_read_disk_can_descend(a)); 449 assertEqualWString(archive_entry_pathname_w(ae), fullpath); 450 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 451 assertEqualInt(archive_entry_size(ae), 10); 452 assertEqualIntA(a, ARCHIVE_OK, 453 archive_read_data_block(a, &p, &size, &offset)); 454 assertEqualInt((int)size, 10); 455 assertEqualInt((int)offset, 0); 456 assertEqualMem(p, "0123456789", 10); 457 458 /* There is no entry. */ 459 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 460 461 /* Close the disk object. */ 462 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 463 free(fullpath); 464 465 /* 466 * Test for wild card '*' or '?' with "//?/" prefix. 467 */ 468 wcwd = _wgetcwd(NULL, 0); 469 fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); 470 wcscpy(fullpath, L"//?/"); 471 wcscat(fullpath, wcwd); 472 wcscat(fullpath, L"/dir1/*1"); 473 free(wcwd); 474 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); 475 while ((wcwd = wcschr(fullpath, L'\\')) != NULL) 476 *wcwd = L'/'; 477 478 /* dir1/file1 */ 479 wp = wcsrchr(fullpath, L'/'); 480 wcscpy(wp+1, L"file1"); 481 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 482 assertEqualInt(0, archive_read_disk_can_descend(a)); 483 assertEqualWString(archive_entry_pathname_w(ae), fullpath); 484 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 485 assertEqualInt(archive_entry_size(ae), 10); 486 assertEqualIntA(a, ARCHIVE_OK, 487 archive_read_data_block(a, &p, &size, &offset)); 488 assertEqualInt((int)size, 10); 489 assertEqualInt((int)offset, 0); 490 assertEqualMem(p, "0123456789", 10); 491 492 /* dir1/sub1 */ 493 wcscpy(wp+1, L"sub1"); 494 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 495 assertEqualInt(1, archive_read_disk_can_descend(a)); 496 assertEqualWString(archive_entry_pathname_w(ae), fullpath); 497 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 498 499 /* Descend into the current object */ 500 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); 501 502 /* dir1/sub1/file1 */ 503 wcscpy(wp+1, L"sub1/file1"); 504 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 505 assertEqualInt(0, archive_read_disk_can_descend(a)); 506 assertEqualWString(archive_entry_pathname_w(ae), fullpath); 507 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 508 assertEqualInt(archive_entry_size(ae), 10); 509 assertEqualIntA(a, ARCHIVE_OK, 510 archive_read_data_block(a, &p, &size, &offset)); 511 assertEqualInt((int)size, 10); 512 assertEqualInt((int)offset, 0); 513 assertEqualMem(p, "0123456789", 10); 514 515 /* There is no entry. */ 516 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 517 518 /* Close the disk object. */ 519 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 520 free(fullpath); 521 522#endif 523 524 /* 525 * We should be on the initial directory where we performed 526 * archive_read_disk_new() after we perform archive_read_free() 527 * even if we broke off the directory traversals. 528 */ 529 530 /* Save current working directory. */ 531#ifdef PATH_MAX 532 initial_cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ 533#else 534 initial_cwd = getcwd(NULL, 0); 535#endif 536 537 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); 538 539 /* Step in a deep directory. */ 540 file_count = 12; 541 while (file_count--) { 542 assertEqualIntA(a, ARCHIVE_OK, 543 archive_read_next_header2(a, ae)); 544 if (strcmp(archive_entry_pathname(ae), 545 "dir1/sub1/file1") == 0) 546 /* 547 * We are on an another directory at this time. 548 */ 549 break; 550 if (archive_entry_filetype(ae) == AE_IFDIR) { 551 /* Descend into the current object */ 552 assertEqualIntA(a, ARCHIVE_OK, 553 archive_read_disk_descend(a)); 554 } 555 } 556 /* Destroy the disk object. */ 557 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 558 559 /* We should be on the initial working directory. */ 560 failure( 561 "Current working directory does not return to the initial" 562 "directory"); 563#ifdef PATH_MAX 564 cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ 565#else 566 cwd = getcwd(NULL, 0); 567#endif 568 assertEqualString(initial_cwd, cwd); 569 free(initial_cwd); 570 free(cwd); 571 572 archive_entry_free(ae); 573} 574 575static void 576test_symlink_hybrid(void) 577{ 578 struct archive *a; 579 struct archive_entry *ae; 580 const void *p; 581 size_t size; 582 int64_t offset; 583 int file_count; 584 585 if (!canSymlink()) { 586 skipping("Can't test symlinks on this filesystem"); 587 return; 588 } 589 590 /* 591 * Create a sample archive. 592 */ 593 assertMakeDir("h", 0755); 594 assertChdir("h"); 595 assertMakeDir("d1", 0755); 596 assertMakeSymlink("ld1", "d1", 1); 597 assertMakeFile("d1/file1", 0644, "d1/file1"); 598 assertMakeFile("d1/file2", 0644, "d1/file2"); 599 assertMakeSymlink("d1/link1", "file1", 0); 600 assertMakeSymlink("d1/linkX", "fileX", 0); 601 assertMakeSymlink("link2", "d1/file2", 0); 602 assertMakeSymlink("linkY", "d1/fileY", 0); 603 assertChdir(".."); 604 605 assert((ae = archive_entry_new()) != NULL); 606 assert((a = archive_read_disk_new()) != NULL); 607 assertEqualIntA(a, ARCHIVE_OK, 608 archive_read_disk_set_symlink_hybrid(a)); 609 610 /* 611 * Specified file is a symbolic link file. 612 */ 613 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h/ld1")); 614 file_count = 5; 615 616 while (file_count--) { 617 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 618 if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) { 619 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 620 } else if (strcmp(archive_entry_pathname(ae), 621 "h/ld1/file1") == 0) { 622 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 623 assertEqualInt(archive_entry_size(ae), 8); 624 assertEqualIntA(a, ARCHIVE_OK, 625 archive_read_data_block(a, &p, &size, &offset)); 626 assertEqualInt((int)size, 8); 627 assertEqualInt((int)offset, 0); 628 assertEqualMem(p, "d1/file1", 8); 629 assertEqualInt(ARCHIVE_EOF, 630 archive_read_data_block(a, &p, &size, &offset)); 631 assertEqualInt((int)size, 0); 632 assertEqualInt((int)offset, 8); 633 } else if (strcmp(archive_entry_pathname(ae), 634 "h/ld1/file2") == 0) { 635 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 636 assertEqualInt(archive_entry_size(ae), 8); 637 assertEqualIntA(a, ARCHIVE_OK, 638 archive_read_data_block(a, &p, &size, &offset)); 639 assertEqualInt((int)size, 8); 640 assertEqualInt((int)offset, 0); 641 assertEqualMem(p, "d1/file2", 8); 642 assertEqualInt(ARCHIVE_EOF, 643 archive_read_data_block(a, &p, &size, &offset)); 644 assertEqualInt((int)size, 0); 645 assertEqualInt((int)offset, 8); 646 } else if (strcmp(archive_entry_pathname(ae), 647 "h/ld1/link1") == 0) { 648 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 649 } else if (strcmp(archive_entry_pathname(ae), 650 "h/ld1/linkX") == 0) { 651 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 652 } 653 if (archive_entry_filetype(ae) == AE_IFDIR) { 654 /* Descend into the current object */ 655 assertEqualIntA(a, ARCHIVE_OK, 656 archive_read_disk_descend(a)); 657 } 658 } 659 /* There is no entry. */ 660 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 661 /* Close the disk object. */ 662 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 663 664 /* 665 * Specified file is a directory and it has symbolic files. 666 */ 667 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h")); 668 file_count = 9; 669 670 while (file_count--) { 671 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 672 if (strcmp(archive_entry_pathname(ae), "h") == 0) { 673 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 674 } else if (strcmp(archive_entry_pathname(ae), "h/d1") == 0) { 675 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 676 } else if (strcmp(archive_entry_pathname(ae), 677 "h/d1/file1") == 0) { 678 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 679 assertEqualInt(archive_entry_size(ae), 8); 680 assertEqualIntA(a, ARCHIVE_OK, 681 archive_read_data_block(a, &p, &size, &offset)); 682 assertEqualInt((int)size, 8); 683 assertEqualInt((int)offset, 0); 684 assertEqualMem(p, "d1/file1", 8); 685 assertEqualInt(ARCHIVE_EOF, 686 archive_read_data_block(a, &p, &size, &offset)); 687 assertEqualInt((int)size, 0); 688 assertEqualInt((int)offset, 8); 689 } else if (strcmp(archive_entry_pathname(ae), 690 "h/d1/file2") == 0) { 691 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 692 assertEqualInt(archive_entry_size(ae), 8); 693 assertEqualIntA(a, ARCHIVE_OK, 694 archive_read_data_block(a, &p, &size, &offset)); 695 assertEqualInt((int)size, 8); 696 assertEqualInt((int)offset, 0); 697 assertEqualMem(p, "d1/file2", 8); 698 assertEqualInt(ARCHIVE_EOF, 699 archive_read_data_block(a, &p, &size, &offset)); 700 assertEqualInt((int)size, 0); 701 assertEqualInt((int)offset, 8); 702 } else if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) { 703 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 704 } else if (strcmp(archive_entry_pathname(ae), 705 "h/d1/link1") == 0) { 706 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 707 } else if (strcmp(archive_entry_pathname(ae), 708 "h/d1/linkX") == 0) { 709 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 710 } else if (strcmp(archive_entry_pathname(ae), 711 "h/link2") == 0) { 712 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 713 } else if (strcmp(archive_entry_pathname(ae), 714 "h/linkY") == 0) { 715 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 716 } 717 if (archive_entry_filetype(ae) == AE_IFDIR) { 718 /* Descend into the current object */ 719 assertEqualIntA(a, ARCHIVE_OK, 720 archive_read_disk_descend(a)); 721 } 722 } 723 /* There is no entry. */ 724 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 725 /* Close the disk object. */ 726 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 727 /* Destroy the disk object. */ 728 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 729 archive_entry_free(ae); 730} 731 732static void 733test_symlink_logical(void) 734{ 735 struct archive *a; 736 struct archive_entry *ae; 737 const void *p; 738 size_t size; 739 int64_t offset; 740 int file_count; 741 742 if (!canSymlink()) { 743 skipping("Can't test symlinks on this filesystem"); 744 return; 745 } 746 747 /* 748 * Create a sample archive. 749 */ 750 assertMakeDir("l", 0755); 751 assertChdir("l"); 752 assertMakeDir("d1", 0755); 753 assertMakeSymlink("ld1", "d1", 1); 754 assertMakeFile("d1/file1", 0644, "d1/file1"); 755 assertMakeFile("d1/file2", 0644, "d1/file2"); 756 assertMakeSymlink("d1/link1", "file1", 0); 757 assertMakeSymlink("d1/linkX", "fileX", 0); 758 assertMakeSymlink("link2", "d1/file2", 0); 759 assertMakeSymlink("linkY", "d1/fileY", 0); 760 assertChdir(".."); 761 762 /* Note: this test uses archive_read_next_header() 763 instead of archive_read_next_header2() */ 764 assert((a = archive_read_disk_new()) != NULL); 765 assertEqualIntA(a, ARCHIVE_OK, 766 archive_read_disk_set_symlink_logical(a)); 767 768 /* 769 * Specified file is a symbolic link file. 770 */ 771 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l/ld1")); 772 file_count = 5; 773 774 while (file_count--) { 775 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 776 if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) { 777 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 778 } else if (strcmp(archive_entry_pathname(ae), 779 "l/ld1/file1") == 0) { 780 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 781 assertEqualInt(archive_entry_size(ae), 8); 782 assertEqualIntA(a, ARCHIVE_OK, 783 archive_read_data_block(a, &p, &size, &offset)); 784 assertEqualInt((int)size, 8); 785 assertEqualInt((int)offset, 0); 786 assertEqualMem(p, "d1/file1", 8); 787 assertEqualInt(ARCHIVE_EOF, 788 archive_read_data_block(a, &p, &size, &offset)); 789 assertEqualInt((int)size, 0); 790 assertEqualInt((int)offset, 8); 791 } else if (strcmp(archive_entry_pathname(ae), 792 "l/ld1/file2") == 0) { 793 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 794 assertEqualInt(archive_entry_size(ae), 8); 795 assertEqualIntA(a, ARCHIVE_OK, 796 archive_read_data_block(a, &p, &size, &offset)); 797 assertEqualInt((int)size, 8); 798 assertEqualInt((int)offset, 0); 799 assertEqualMem(p, "d1/file2", 8); 800 assertEqualInt(ARCHIVE_EOF, 801 archive_read_data_block(a, &p, &size, &offset)); 802 assertEqualInt((int)size, 0); 803 assertEqualInt((int)offset, 8); 804 } else if (strcmp(archive_entry_pathname(ae), 805 "l/ld1/link1") == 0) { 806 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 807 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 808 assertEqualInt(archive_entry_size(ae), 8); 809 assertEqualIntA(a, ARCHIVE_OK, 810 archive_read_data_block(a, &p, &size, &offset)); 811 assertEqualInt((int)size, 8); 812 assertEqualInt((int)offset, 0); 813 assertEqualMem(p, "d1/file1", 8); 814 assertEqualInt(ARCHIVE_EOF, 815 archive_read_data_block(a, &p, &size, &offset)); 816 assertEqualInt((int)size, 0); 817 assertEqualInt((int)offset, 8); 818 } else if (strcmp(archive_entry_pathname(ae), 819 "l/ld1/linkX") == 0) { 820 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 821 } 822 if (archive_entry_filetype(ae) == AE_IFDIR) { 823 /* Descend into the current object */ 824 assertEqualIntA(a, ARCHIVE_OK, 825 archive_read_disk_descend(a)); 826 } 827 } 828 /* There is no entry. */ 829 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 830 /* Close the disk object. */ 831 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 832 833 /* 834 * Specified file is a directory and it has symbolic files. 835 */ 836 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l")); 837 file_count = 13; 838 839 while (file_count--) { 840 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 841 if (strcmp(archive_entry_pathname(ae), "l") == 0) { 842 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 843 } else if (strcmp(archive_entry_pathname(ae), "l/d1") == 0) { 844 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 845 } else if (strcmp(archive_entry_pathname(ae), 846 "l/d1/file1") == 0) { 847 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 848 assertEqualInt(archive_entry_size(ae), 8); 849 assertEqualIntA(a, ARCHIVE_OK, 850 archive_read_data_block(a, &p, &size, &offset)); 851 assertEqualInt((int)size, 8); 852 assertEqualInt((int)offset, 0); 853 assertEqualMem(p, "d1/file1", 8); 854 assertEqualInt(ARCHIVE_EOF, 855 archive_read_data_block(a, &p, &size, &offset)); 856 assertEqualInt((int)size, 0); 857 assertEqualInt((int)offset, 8); 858 } else if (strcmp(archive_entry_pathname(ae), 859 "l/d1/file2") == 0) { 860 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 861 assertEqualInt(archive_entry_size(ae), 8); 862 assertEqualIntA(a, ARCHIVE_OK, 863 archive_read_data_block(a, &p, &size, &offset)); 864 assertEqualInt((int)size, 8); 865 assertEqualInt((int)offset, 0); 866 assertEqualMem(p, "d1/file2", 8); 867 assertEqualInt(ARCHIVE_EOF, 868 archive_read_data_block(a, &p, &size, &offset)); 869 assertEqualInt((int)size, 0); 870 assertEqualInt((int)offset, 8); 871 } else if (strcmp(archive_entry_pathname(ae), 872 "l/d1/link1") == 0) { 873 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 874 assertEqualInt(archive_entry_size(ae), 8); 875 assertEqualIntA(a, ARCHIVE_OK, 876 archive_read_data_block(a, &p, &size, &offset)); 877 assertEqualInt((int)size, 8); 878 assertEqualInt((int)offset, 0); 879 assertEqualMem(p, "d1/file1", 8); 880 assertEqualInt(ARCHIVE_EOF, 881 archive_read_data_block(a, &p, &size, &offset)); 882 assertEqualInt((int)size, 0); 883 assertEqualInt((int)offset, 8); 884 } else if (strcmp(archive_entry_pathname(ae), 885 "l/d1/linkX") == 0) { 886 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 887 } else if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) { 888 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 889 } else if (strcmp(archive_entry_pathname(ae), 890 "l/ld1/file1") == 0) { 891 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 892 assertEqualInt(archive_entry_size(ae), 8); 893 assertEqualIntA(a, ARCHIVE_OK, 894 archive_read_data_block(a, &p, &size, &offset)); 895 assertEqualInt((int)size, 8); 896 assertEqualInt((int)offset, 0); 897 assertEqualMem(p, "d1/file1", 8); 898 assertEqualInt(ARCHIVE_EOF, 899 archive_read_data_block(a, &p, &size, &offset)); 900 assertEqualInt((int)size, 0); 901 assertEqualInt((int)offset, 8); 902 } else if (strcmp(archive_entry_pathname(ae), 903 "l/ld1/file2") == 0) { 904 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 905 assertEqualInt(archive_entry_size(ae), 8); 906 assertEqualIntA(a, ARCHIVE_OK, 907 archive_read_data_block(a, &p, &size, &offset)); 908 assertEqualInt((int)size, 8); 909 assertEqualInt((int)offset, 0); 910 assertEqualMem(p, "d1/file2", 8); 911 assertEqualInt(ARCHIVE_EOF, 912 archive_read_data_block(a, &p, &size, &offset)); 913 assertEqualInt((int)size, 0); 914 assertEqualInt((int)offset, 8); 915 } else if (strcmp(archive_entry_pathname(ae), 916 "l/ld1/link1") == 0) { 917 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 918 assertEqualInt(archive_entry_size(ae), 8); 919 assertEqualIntA(a, ARCHIVE_OK, 920 archive_read_data_block(a, &p, &size, &offset)); 921 assertEqualInt((int)size, 8); 922 assertEqualInt((int)offset, 0); 923 assertEqualMem(p, "d1/file1", 8); 924 assertEqualInt(ARCHIVE_EOF, 925 archive_read_data_block(a, &p, &size, &offset)); 926 assertEqualInt((int)size, 0); 927 assertEqualInt((int)offset, 8); 928 } else if (strcmp(archive_entry_pathname(ae), 929 "l/ld1/linkX") == 0) { 930 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 931 } else if (strcmp(archive_entry_pathname(ae), 932 "l/link2") == 0) { 933 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 934 assertEqualInt(archive_entry_size(ae), 8); 935 assertEqualIntA(a, ARCHIVE_OK, 936 archive_read_data_block(a, &p, &size, &offset)); 937 assertEqualInt((int)size, 8); 938 assertEqualInt((int)offset, 0); 939 assertEqualMem(p, "d1/file2", 8); 940 assertEqualInt(ARCHIVE_EOF, 941 archive_read_data_block(a, &p, &size, &offset)); 942 assertEqualInt((int)size, 0); 943 assertEqualInt((int)offset, 8); 944 } else if (strcmp(archive_entry_pathname(ae), 945 "l/linkY") == 0) { 946 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 947 } 948 if (archive_entry_filetype(ae) == AE_IFDIR) { 949 /* Descend into the current object */ 950 assertEqualIntA(a, ARCHIVE_OK, 951 archive_read_disk_descend(a)); 952 } 953 } 954 /* There is no entry. */ 955 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 956 /* Close the disk object. */ 957 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 958 /* Destroy the disk object. */ 959 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 960} 961 962static void 963test_symlink_logical_loop(void) 964{ 965 struct archive *a; 966 struct archive_entry *ae; 967 const void *p; 968 size_t size; 969 int64_t offset; 970 int file_count; 971 972 if (!canSymlink()) { 973 skipping("Can't test symlinks on this filesystem"); 974 return; 975 } 976 977 /* 978 * Create a sample archive. 979 */ 980 assertMakeDir("l2", 0755); 981 assertChdir("l2"); 982 assertMakeDir("d1", 0755); 983 assertMakeDir("d1/d2", 0755); 984 assertMakeDir("d1/d2/d3", 0755); 985 assertMakeDir("d2", 0755); 986 assertMakeFile("d2/file1", 0644, "d2/file1"); 987 assertMakeSymlink("d1/d2/ld1", "../../d1", 1); 988 assertMakeSymlink("d1/d2/ld2", "../../d2", 1); 989 assertChdir(".."); 990 991 assert((ae = archive_entry_new()) != NULL); 992 assert((a = archive_read_disk_new()) != NULL); 993 assertEqualIntA(a, ARCHIVE_OK, 994 archive_read_disk_set_symlink_logical(a)); 995 996 /* 997 * Specified file is a symbolic link file. 998 */ 999 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l2/d1")); 1000 file_count = 6; 1001 1002 while (file_count--) { 1003 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1004 if (strcmp(archive_entry_pathname(ae), "l2/d1") == 0) { 1005 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1006 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2") == 0) { 1007 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1008 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/d3") == 0) { 1009 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1010 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld1") == 0) { 1011 assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); 1012 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld2") == 0) { 1013 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1014 } else if (strcmp(archive_entry_pathname(ae), 1015 "l2/d1/d2/ld2/file1") == 0) { 1016 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1017 assertEqualInt(archive_entry_size(ae), 8); 1018 assertEqualIntA(a, ARCHIVE_OK, 1019 archive_read_data_block(a, &p, &size, &offset)); 1020 assertEqualInt((int)size, 8); 1021 assertEqualInt((int)offset, 0); 1022 assertEqualMem(p, "d2/file1", 8); 1023 assertEqualInt(ARCHIVE_EOF, 1024 archive_read_data_block(a, &p, &size, &offset)); 1025 assertEqualInt((int)size, 0); 1026 assertEqualInt((int)offset, 8); 1027 } 1028 if (archive_entry_filetype(ae) == AE_IFDIR) { 1029 /* Descend into the current object */ 1030 assertEqualIntA(a, ARCHIVE_OK, 1031 archive_read_disk_descend(a)); 1032 } 1033 } 1034 /* There is no entry. */ 1035 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1036 /* Destroy the disk object. */ 1037 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1038 archive_entry_free(ae); 1039} 1040 1041static void 1042test_restore_atime(void) 1043{ 1044 struct archive *a; 1045 struct archive_entry *ae; 1046 const void *p; 1047 size_t size; 1048 int64_t offset; 1049 int file_count; 1050 1051 if (!atimeIsUpdated()) { 1052 skipping("Can't test restoring atime on this filesystem"); 1053 return; 1054 } 1055 1056 assertMakeDir("at", 0755); 1057 assertMakeFile("at/f1", 0644, "0123456789"); 1058 assertMakeFile("at/f2", 0644, "hello world"); 1059 assertMakeFile("at/fe", 0644, NULL); 1060 assertUtimes("at/f1", 886600, 0, 886600, 0); 1061 assertUtimes("at/f2", 886611, 0, 886611, 0); 1062 assertUtimes("at/fe", 886611, 0, 886611, 0); 1063 assertUtimes("at", 886622, 0, 886622, 0); 1064 file_count = 4; 1065 1066 assert((ae = archive_entry_new()) != NULL); 1067 assert((a = archive_read_disk_new()) != NULL); 1068 1069 /* 1070 * Test1: Traversals without archive_read_disk_set_atime_restored(). 1071 */ 1072 failure("Directory traversals should work as well"); 1073 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1074 while (file_count--) { 1075 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1076 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1077 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1078 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { 1079 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1080 assertEqualInt(archive_entry_size(ae), 10); 1081 assertEqualIntA(a, ARCHIVE_OK, 1082 archive_read_data_block(a, &p, &size, &offset)); 1083 assertEqualInt((int)size, 10); 1084 assertEqualInt((int)offset, 0); 1085 assertEqualMem(p, "0123456789", 10); 1086 assertEqualInt(ARCHIVE_EOF, 1087 archive_read_data_block(a, &p, &size, &offset)); 1088 assertEqualInt((int)size, 0); 1089 assertEqualInt((int)offset, 10); 1090 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { 1091 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1092 assertEqualInt(archive_entry_size(ae), 11); 1093 assertEqualIntA(a, ARCHIVE_OK, 1094 archive_read_data_block(a, &p, &size, &offset)); 1095 assertEqualInt((int)size, 11); 1096 assertEqualInt((int)offset, 0); 1097 assertEqualMem(p, "hello world", 11); 1098 assertEqualInt(ARCHIVE_EOF, 1099 archive_read_data_block(a, &p, &size, &offset)); 1100 assertEqualInt((int)size, 0); 1101 assertEqualInt((int)offset, 11); 1102 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1103 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1104 assertEqualInt(archive_entry_size(ae), 0); 1105 } 1106 if (archive_entry_filetype(ae) == AE_IFDIR) { 1107 /* Descend into the current object */ 1108 assertEqualIntA(a, ARCHIVE_OK, 1109 archive_read_disk_descend(a)); 1110 } 1111 } 1112 /* There is no entry. */ 1113 failure("There must be no entry"); 1114 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1115 1116 /* On FreeBSD (and likely other systems), atime on 1117 dirs does not change when it is read. */ 1118 /* failure("Atime should be restored"); */ 1119 /* assertFileAtimeRecent("at"); */ 1120 failure("Atime should be restored"); 1121 assertFileAtimeRecent("at/f1"); 1122 failure("Atime should be restored"); 1123 assertFileAtimeRecent("at/f2"); 1124 failure("The atime of a empty file should not be changed"); 1125 assertFileAtime("at/fe", 886611, 0); 1126 1127 /* Close the disk object. */ 1128 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1129 1130 /* 1131 * Test2: Traversals with archive_read_disk_set_atime_restored(). 1132 */ 1133 assertUtimes("at/f1", 886600, 0, 886600, 0); 1134 assertUtimes("at/f2", 886611, 0, 886611, 0); 1135 assertUtimes("at/fe", 886611, 0, 886611, 0); 1136 assertUtimes("at", 886622, 0, 886622, 0); 1137 file_count = 4; 1138 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); 1139 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1140 1141 failure("Directory traversals should work as well"); 1142 while (file_count--) { 1143 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1144 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1145 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1146 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { 1147 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1148 assertEqualInt(archive_entry_size(ae), 10); 1149 assertEqualIntA(a, ARCHIVE_OK, 1150 archive_read_data_block(a, &p, &size, &offset)); 1151 assertEqualInt((int)size, 10); 1152 assertEqualInt((int)offset, 0); 1153 assertEqualMem(p, "0123456789", 10); 1154 assertEqualInt(ARCHIVE_EOF, 1155 archive_read_data_block(a, &p, &size, &offset)); 1156 assertEqualInt((int)size, 0); 1157 assertEqualInt((int)offset, 10); 1158 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { 1159 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1160 assertEqualInt(archive_entry_size(ae), 11); 1161 assertEqualIntA(a, ARCHIVE_OK, 1162 archive_read_data_block(a, &p, &size, &offset)); 1163 assertEqualInt((int)size, 11); 1164 assertEqualInt((int)offset, 0); 1165 assertEqualMem(p, "hello world", 11); 1166 assertEqualInt(ARCHIVE_EOF, 1167 archive_read_data_block(a, &p, &size, &offset)); 1168 assertEqualInt((int)size, 0); 1169 assertEqualInt((int)offset, 11); 1170 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1171 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1172 assertEqualInt(archive_entry_size(ae), 0); 1173 } 1174 if (archive_entry_filetype(ae) == AE_IFDIR) { 1175 /* Descend into the current object */ 1176 assertEqualIntA(a, ARCHIVE_OK, 1177 archive_read_disk_descend(a)); 1178 } 1179 } 1180 /* There is no entry. */ 1181 failure("There must be no entry"); 1182 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1183 1184 failure("Atime should be restored"); 1185 assertFileAtime("at", 886622, 0); 1186 failure("Atime should be restored"); 1187 assertFileAtime("at/f1", 886600, 0); 1188 failure("Atime should be restored"); 1189 assertFileAtime("at/f2", 886611, 0); 1190 failure("The atime of a empty file should not be changed"); 1191 assertFileAtime("at/fe", 886611, 0); 1192 1193 /* Close the disk object. */ 1194 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1195 1196 /* 1197 * Test3: Traversals with archive_read_disk_set_atime_restored() but 1198 * no data read as a listing. 1199 */ 1200 assertUtimes("at/f1", 886600, 0, 886600, 0); 1201 assertUtimes("at/f2", 886611, 0, 886611, 0); 1202 assertUtimes("at/fe", 886611, 0, 886611, 0); 1203 assertUtimes("at", 886622, 0, 886622, 0); 1204 file_count = 4; 1205 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); 1206 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1207 1208 failure("Directory traversals should work as well"); 1209 while (file_count--) { 1210 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1211 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1212 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1213 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { 1214 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1215 assertEqualInt(archive_entry_size(ae), 10); 1216 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { 1217 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1218 assertEqualInt(archive_entry_size(ae), 11); 1219 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1220 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1221 assertEqualInt(archive_entry_size(ae), 0); 1222 } 1223 if (archive_entry_filetype(ae) == AE_IFDIR) { 1224 /* Descend into the current object */ 1225 assertEqualIntA(a, ARCHIVE_OK, 1226 archive_read_disk_descend(a)); 1227 } 1228 } 1229 /* There is no entry. */ 1230 failure("There must be no entry"); 1231 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1232 1233 failure("Atime should be restored"); 1234 assertFileAtime("at", 886622, 0); 1235 failure("Atime should be restored"); 1236 assertFileAtime("at/f1", 886600, 0); 1237 failure("Atime should be restored"); 1238 assertFileAtime("at/f2", 886611, 0); 1239 failure("The atime of a empty file should not be changed"); 1240 assertFileAtime("at/fe", 886611, 0); 1241 1242 if (!canNodump()) { 1243 /* Destroy the disk object. */ 1244 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1245 archive_entry_free(ae); 1246 skipping("Can't test atime with nodump on this filesystem"); 1247 return; 1248 } 1249 1250 /* Close the disk object. */ 1251 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1252 1253 /* 1254 * Test4: Traversals with ARCHIVE_READDISK_RESTORE_ATIME and 1255 * ARCHIVE_READDISK_HONOR_NODUMP 1256 */ 1257 assertSetNodump("at/f1"); 1258 assertSetNodump("at/f2"); 1259 assertUtimes("at/f1", 886600, 0, 886600, 0); 1260 assertUtimes("at/f2", 886611, 0, 886611, 0); 1261 assertUtimes("at/fe", 886611, 0, 886611, 0); 1262 assertUtimes("at", 886622, 0, 886622, 0); 1263 file_count = 2; 1264 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, 1265 ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); 1266 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1267 1268 failure("Directory traversals should work as well"); 1269 while (file_count--) { 1270 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1271 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1272 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1273 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1274 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1275 assertEqualInt(archive_entry_size(ae), 0); 1276 } 1277 if (archive_entry_filetype(ae) == AE_IFDIR) { 1278 /* Descend into the current object */ 1279 assertEqualIntA(a, ARCHIVE_OK, 1280 archive_read_disk_descend(a)); 1281 } 1282 } 1283 /* There is no entry. */ 1284 failure("There must be no entry"); 1285 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1286 1287 failure("Atime should be restored"); 1288 assertFileAtime("at", 886622, 0); 1289 failure("Atime should be restored"); 1290 assertFileAtime("at/f1", 886600, 0); 1291 failure("Atime should be restored"); 1292 assertFileAtime("at/f2", 886611, 0); 1293 failure("The atime of a empty file should not be changed"); 1294 assertFileAtime("at/fe", 886611, 0); 1295 1296 /* Destroy the disk object. */ 1297 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1298 archive_entry_free(ae); 1299} 1300 1301static int 1302metadata_filter(struct archive *a, void *data, struct archive_entry *ae) 1303{ 1304 (void)data; /* UNUSED */ 1305 1306 failure("CTime should be set"); 1307 assertEqualInt(8, archive_entry_ctime_is_set(ae)); 1308 failure("MTime should be set"); 1309 assertEqualInt(16, archive_entry_mtime_is_set(ae)); 1310 1311 if (archive_entry_mtime(ae) < 886611) 1312 return (0); 1313 if (archive_read_disk_can_descend(a)) { 1314 /* Descend into the current object */ 1315 failure("archive_read_disk_can_descend should work" 1316 " in metadata filter"); 1317 assertEqualIntA(a, 1, archive_read_disk_can_descend(a)); 1318 failure("archive_read_disk_descend should work" 1319 " in metadata filter"); 1320 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); 1321 } 1322 return (1); 1323} 1324 1325static void 1326test_callbacks(void) 1327{ 1328 struct archive *a; 1329 struct archive *m; 1330 struct archive_entry *ae; 1331 const void *p; 1332 size_t size; 1333 int64_t offset; 1334 int file_count; 1335 1336 assertMakeDir("cb", 0755); 1337 assertMakeFile("cb/f1", 0644, "0123456789"); 1338 assertMakeFile("cb/f2", 0644, "hello world"); 1339 assertMakeFile("cb/fe", 0644, NULL); 1340 assertUtimes("cb/f1", 886600, 0, 886600, 0); 1341 assertUtimes("cb/f2", 886611, 0, 886611, 0); 1342 assertUtimes("cb/fe", 886611, 0, 886611, 0); 1343 assertUtimes("cb", 886622, 0, 886622, 0); 1344 1345 assert((ae = archive_entry_new()) != NULL); 1346 assert((a = archive_read_disk_new()) != NULL); 1347 if (a == NULL) { 1348 archive_entry_free(ae); 1349 return; 1350 } 1351 assert((m = archive_match_new()) != NULL); 1352 if (m == NULL) { 1353 archive_entry_free(ae); 1354 archive_read_free(a); 1355 archive_match_free(m); 1356 return; 1357 } 1358 1359 /* 1360 * Test1: Traversals with a name filter. 1361 */ 1362 file_count = 3; 1363 assertEqualIntA(m, ARCHIVE_OK, 1364 archive_match_exclude_pattern(m, "cb/f2")); 1365 assertEqualIntA(a, ARCHIVE_OK, 1366 archive_read_disk_set_matching(a, m, NULL, NULL)); 1367 failure("Directory traversals should work as well"); 1368 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); 1369 while (file_count--) { 1370 archive_entry_clear(ae); 1371 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1372 failure("File 'cb/f2' should be exclueded"); 1373 assert(strcmp(archive_entry_pathname(ae), "cb/f2") != 0); 1374 if (strcmp(archive_entry_pathname(ae), "cb") == 0) { 1375 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1376 } else if (strcmp(archive_entry_pathname(ae), "cb/f1") == 0) { 1377 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1378 assertEqualInt(archive_entry_size(ae), 10); 1379 assertEqualIntA(a, ARCHIVE_OK, 1380 archive_read_data_block(a, &p, &size, &offset)); 1381 assertEqualInt((int)size, 10); 1382 assertEqualInt((int)offset, 0); 1383 assertEqualMem(p, "0123456789", 10); 1384 assertEqualInt(ARCHIVE_EOF, 1385 archive_read_data_block(a, &p, &size, &offset)); 1386 assertEqualInt((int)size, 0); 1387 assertEqualInt((int)offset, 10); 1388 } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { 1389 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1390 assertEqualInt(archive_entry_size(ae), 0); 1391 } 1392 if (archive_read_disk_can_descend(a)) { 1393 /* Descend into the current object */ 1394 assertEqualIntA(a, ARCHIVE_OK, 1395 archive_read_disk_descend(a)); 1396 } 1397 } 1398 /* There is no entry. */ 1399 failure("There should be no entry"); 1400 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1401 1402 /* Close the disk object. */ 1403 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1404 1405 /* Reset name filter */ 1406 assertEqualIntA(a, ARCHIVE_OK, 1407 archive_read_disk_set_matching(a, NULL, NULL, NULL)); 1408 1409 /* 1410 * Test2: Traversals with a metadata filter. 1411 */ 1412 assertUtimes("cb/f1", 886600, 0, 886600, 0); 1413 assertUtimes("cb/f2", 886611, 0, 886611, 0); 1414 assertUtimes("cb/fe", 886611, 0, 886611, 0); 1415 assertUtimes("cb", 886622, 0, 886622, 0); 1416 file_count = 3; 1417 assertEqualIntA(a, ARCHIVE_OK, 1418 archive_read_disk_set_metadata_filter_callback(a, metadata_filter, 1419 NULL)); 1420 failure("Directory traversals should work as well"); 1421 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); 1422 1423 while (file_count--) { 1424 archive_entry_clear(ae); 1425 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1426 failure("File 'cb/f1' should be excluded"); 1427 assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0); 1428 if (strcmp(archive_entry_pathname(ae), "cb") == 0) { 1429 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1430 } else if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0) { 1431 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1432 assertEqualInt(archive_entry_size(ae), 11); 1433 assertEqualIntA(a, ARCHIVE_OK, 1434 archive_read_data_block(a, &p, &size, &offset)); 1435 assertEqualInt((int)size, 11); 1436 assertEqualInt((int)offset, 0); 1437 assertEqualMem(p, "hello world", 11); 1438 assertEqualInt(ARCHIVE_EOF, 1439 archive_read_data_block(a, &p, &size, &offset)); 1440 assertEqualInt((int)size, 0); 1441 assertEqualInt((int)offset, 11); 1442 } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { 1443 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1444 assertEqualInt(archive_entry_size(ae), 0); 1445 } 1446 } 1447 /* There is no entry. */ 1448 failure("There should be no entry"); 1449 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1450 1451 /* Destroy the disk object. */ 1452 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1453 assertEqualInt(ARCHIVE_OK, archive_match_free(m)); 1454 archive_entry_free(ae); 1455} 1456 1457static void 1458test_nodump(void) 1459{ 1460 struct archive *a; 1461 struct archive_entry *ae; 1462 const void *p; 1463 size_t size; 1464 int64_t offset; 1465 int file_count; 1466 1467 if (!canNodump()) { 1468 skipping("Can't test nodump on this filesystem"); 1469 return; 1470 } 1471 1472 assertMakeDir("nd", 0755); 1473 assertMakeFile("nd/f1", 0644, "0123456789"); 1474 assertMakeFile("nd/f2", 0644, "hello world"); 1475 assertMakeFile("nd/fe", 0644, NULL); 1476 assertSetNodump("nd/f2"); 1477 assertUtimes("nd/f1", 886600, 0, 886600, 0); 1478 assertUtimes("nd/f2", 886611, 0, 886611, 0); 1479 assertUtimes("nd/fe", 886611, 0, 886611, 0); 1480 assertUtimes("nd", 886622, 0, 886622, 0); 1481 1482 assert((ae = archive_entry_new()) != NULL); 1483 assert((a = archive_read_disk_new()) != NULL); 1484 1485 /* 1486 * Test1: Traversals without ARCHIVE_READDISK_HONOR_NODUMP 1487 */ 1488 failure("Directory traversals should work as well"); 1489 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); 1490 1491 file_count = 4; 1492 while (file_count--) { 1493 archive_entry_clear(ae); 1494 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1495 if (strcmp(archive_entry_pathname(ae), "nd") == 0) { 1496 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1497 } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { 1498 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1499 assertEqualInt(archive_entry_size(ae), 10); 1500 assertEqualIntA(a, ARCHIVE_OK, 1501 archive_read_data_block(a, &p, &size, &offset)); 1502 assertEqualInt((int)size, 10); 1503 assertEqualInt((int)offset, 0); 1504 assertEqualMem(p, "0123456789", 10); 1505 assertEqualInt(ARCHIVE_EOF, 1506 archive_read_data_block(a, &p, &size, &offset)); 1507 assertEqualInt((int)size, 0); 1508 assertEqualInt((int)offset, 10); 1509 } else if (strcmp(archive_entry_pathname(ae), "nd/f2") == 0) { 1510 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1511 assertEqualInt(archive_entry_size(ae), 11); 1512 assertEqualIntA(a, ARCHIVE_OK, 1513 archive_read_data_block(a, &p, &size, &offset)); 1514 assertEqualInt((int)size, 11); 1515 assertEqualInt((int)offset, 0); 1516 assertEqualMem(p, "hello world", 11); 1517 assertEqualInt(ARCHIVE_EOF, 1518 archive_read_data_block(a, &p, &size, &offset)); 1519 assertEqualInt((int)size, 0); 1520 assertEqualInt((int)offset, 11); 1521 } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { 1522 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1523 assertEqualInt(archive_entry_size(ae), 0); 1524 } 1525 if (archive_read_disk_can_descend(a)) { 1526 /* Descend into the current object */ 1527 assertEqualIntA(a, ARCHIVE_OK, 1528 archive_read_disk_descend(a)); 1529 } 1530 } 1531 /* There is no entry. */ 1532 failure("There should be no entry"); 1533 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1534 1535 /* Close the disk object. */ 1536 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1537 1538 /* 1539 * Test2: Traversals with ARCHIVE_READDISK_HONOR_NODUMP 1540 */ 1541 assertUtimes("nd/f1", 886600, 0, 886600, 0); 1542 assertUtimes("nd/f2", 886611, 0, 886611, 0); 1543 assertUtimes("nd/fe", 886611, 0, 886611, 0); 1544 assertUtimes("nd", 886622, 0, 886622, 0); 1545 1546 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, 1547 ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); 1548 failure("Directory traversals should work as well"); 1549 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); 1550 1551 file_count = 3; 1552 while (file_count--) { 1553 archive_entry_clear(ae); 1554 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1555 failure("File 'nd/f2' should be exclueded"); 1556 assert(strcmp(archive_entry_pathname(ae), "nd/f2") != 0); 1557 if (strcmp(archive_entry_pathname(ae), "nd") == 0) { 1558 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1559 } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { 1560 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1561 assertEqualInt(archive_entry_size(ae), 10); 1562 assertEqualIntA(a, ARCHIVE_OK, 1563 archive_read_data_block(a, &p, &size, &offset)); 1564 assertEqualInt((int)size, 10); 1565 assertEqualInt((int)offset, 0); 1566 assertEqualMem(p, "0123456789", 10); 1567 assertEqualInt(ARCHIVE_EOF, 1568 archive_read_data_block(a, &p, &size, &offset)); 1569 assertEqualInt((int)size, 0); 1570 assertEqualInt((int)offset, 10); 1571 } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { 1572 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1573 assertEqualInt(archive_entry_size(ae), 0); 1574 } 1575 if (archive_read_disk_can_descend(a)) { 1576 /* Descend into the current object */ 1577 assertEqualIntA(a, ARCHIVE_OK, 1578 archive_read_disk_descend(a)); 1579 } 1580 } 1581 /* There is no entry. */ 1582 failure("There should be no entry"); 1583 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1584 1585 failure("Atime should be restored"); 1586 assertFileAtime("nd/f2", 886611, 0); 1587 1588 /* Destroy the disk object. */ 1589 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1590 archive_entry_free(ae); 1591} 1592 1593static void 1594test_parent(void) 1595{ 1596 struct archive *a; 1597 struct archive_entry *ae; 1598 const void *p; 1599 size_t size; 1600 int64_t offset; 1601 int file_count; 1602 int match_count; 1603 int r; 1604 1605 assertMakeDir("lock", 0311); 1606 assertMakeDir("lock/dir1", 0755); 1607 assertMakeFile("lock/dir1/f1", 0644, "0123456789"); 1608 assertMakeDir("lock/lock2", 0311); 1609 assertMakeDir("lock/lock2/dir1", 0755); 1610 assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789"); 1611 1612 assert((ae = archive_entry_new()) != NULL); 1613 assert((a = archive_read_disk_new()) != NULL); 1614 1615 /* 1616 * Test1: Traverse lock/dir1 as . 1617 */ 1618 assertChdir("lock/dir1"); 1619 1620 failure("Directory traversals should work as well"); 1621 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); 1622 1623 file_count = 2; 1624 match_count = 0; 1625 while (file_count--) { 1626 archive_entry_clear(ae); 1627 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1628 if (strcmp(archive_entry_pathname(ae), ".") == 0) { 1629 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1630 ++match_count; 1631 } else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { 1632 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1633 assertEqualInt(archive_entry_size(ae), 10); 1634 assertEqualIntA(a, ARCHIVE_OK, 1635 archive_read_data_block(a, &p, &size, &offset)); 1636 assertEqualInt((int)size, 10); 1637 assertEqualInt((int)offset, 0); 1638 assertEqualMem(p, "0123456789", 10); 1639 assertEqualInt(ARCHIVE_EOF, 1640 archive_read_data_block(a, &p, &size, &offset)); 1641 assertEqualInt((int)size, 0); 1642 assertEqualInt((int)offset, 10); 1643 ++match_count; 1644 } 1645 if (archive_read_disk_can_descend(a)) { 1646 /* Descend into the current object */ 1647 assertEqualIntA(a, ARCHIVE_OK, 1648 archive_read_disk_descend(a)); 1649 } 1650 } 1651 failure("Did not match expected filenames"); 1652 assertEqualInt(match_count, 2); 1653 /* 1654 * There is no entry. This will however fail if the directory traverse 1655 * tries to ascend past the initial directory, since it lacks permission 1656 * to do so. 1657 */ 1658 failure("There should be no entry and no error"); 1659 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1660 1661 /* Close the disk object. */ 1662 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1663 1664 assertChdir("../.."); 1665 1666 /* 1667 * Test2: Traverse lock/dir1 directly 1668 */ 1669 failure("Directory traversals should work as well"); 1670 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1")); 1671 1672 file_count = 2; 1673 match_count = 0; 1674 while (file_count--) { 1675 archive_entry_clear(ae); 1676 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1677 if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) { 1678 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1679 ++match_count; 1680 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) { 1681 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1682 assertEqualInt(archive_entry_size(ae), 10); 1683 assertEqualIntA(a, ARCHIVE_OK, 1684 archive_read_data_block(a, &p, &size, &offset)); 1685 assertEqualInt((int)size, 10); 1686 assertEqualInt((int)offset, 0); 1687 assertEqualMem(p, "0123456789", 10); 1688 assertEqualInt(ARCHIVE_EOF, 1689 archive_read_data_block(a, &p, &size, &offset)); 1690 assertEqualInt((int)size, 0); 1691 assertEqualInt((int)offset, 10); 1692 ++match_count; 1693 } 1694 if (archive_read_disk_can_descend(a)) { 1695 /* Descend into the current object */ 1696 assertEqualIntA(a, ARCHIVE_OK, 1697 archive_read_disk_descend(a)); 1698 } 1699 } 1700 failure("Did not match expected filenames"); 1701 assertEqualInt(match_count, 2); 1702 /* 1703 * There is no entry. This will however fail if the directory traverse 1704 * tries to ascend past the initial directory, since it lacks permission 1705 * to do so. 1706 */ 1707 failure("There should be no entry and no error"); 1708 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1709 1710 /* Close the disk object. */ 1711 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1712 1713 /* 1714 * Test3: Traverse lock/dir1/. 1715 */ 1716 failure("Directory traversals should work as well"); 1717 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/.")); 1718 1719 file_count = 2; 1720 match_count = 0; 1721 while (file_count--) { 1722 archive_entry_clear(ae); 1723 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1724 if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) { 1725 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1726 ++match_count; 1727 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) { 1728 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1729 assertEqualInt(archive_entry_size(ae), 10); 1730 assertEqualIntA(a, ARCHIVE_OK, 1731 archive_read_data_block(a, &p, &size, &offset)); 1732 assertEqualInt((int)size, 10); 1733 assertEqualInt((int)offset, 0); 1734 assertEqualMem(p, "0123456789", 10); 1735 assertEqualInt(ARCHIVE_EOF, 1736 archive_read_data_block(a, &p, &size, &offset)); 1737 assertEqualInt((int)size, 0); 1738 assertEqualInt((int)offset, 10); 1739 ++match_count; 1740 } 1741 if (archive_read_disk_can_descend(a)) { 1742 /* Descend into the current object */ 1743 assertEqualIntA(a, ARCHIVE_OK, 1744 archive_read_disk_descend(a)); 1745 } 1746 } 1747 failure("Did not match expected filenames"); 1748 assertEqualInt(match_count, 2); 1749 /* 1750 * There is no entry. This will however fail if the directory traverse 1751 * tries to ascend past the initial directory, since it lacks permission 1752 * to do so. 1753 */ 1754 failure("There should be no entry and no error"); 1755 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1756 1757 /* Close the disk object. */ 1758 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1759 1760 /* 1761 * Test4: Traverse lock/lock2/dir1 from inside lock. 1762 * 1763 * This test is expected to fail on platforms with no O_EXEC or 1764 * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because 1765 * the current traversal code can't handle the case where it can't 1766 * obtain an open fd for the initial current directory. We need to 1767 * check that condition here, because if O_EXEC _does_ exist, we don't 1768 * want to overlook any failure. 1769 */ 1770 assertChdir("lock"); 1771 1772 failure("Directory traversals should work as well"); 1773 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1")); 1774 1775 archive_entry_clear(ae); 1776 r = archive_read_next_header2(a, ae); 1777 if (r == ARCHIVE_FAILED) { 1778#if defined(O_PATH) || defined(O_SEARCH) || \ 1779 (defined(__FreeBSD__) && defined(O_EXEC)) 1780 assertEqualIntA(a, ARCHIVE_OK, r); 1781#endif 1782 /* Close the disk object. */ 1783 archive_read_close(a); 1784 } else { 1785 file_count = 2; 1786 match_count = 0; 1787 while (file_count--) { 1788 if (file_count == 0) 1789 assertEqualIntA(a, ARCHIVE_OK, 1790 archive_read_next_header2(a, ae)); 1791 if (strcmp(archive_entry_pathname(ae), 1792 "lock2/dir1") == 0) { 1793 assertEqualInt(archive_entry_filetype(ae), 1794 AE_IFDIR); 1795 ++match_count; 1796 } else if (strcmp(archive_entry_pathname(ae), 1797 "lock2/dir1/f1") == 0) { 1798 assertEqualInt(archive_entry_filetype(ae), 1799 AE_IFREG); 1800 assertEqualInt(archive_entry_size(ae), 10); 1801 assertEqualIntA(a, ARCHIVE_OK, 1802 archive_read_data_block(a, &p, &size, 1803 &offset)); 1804 assertEqualInt((int)size, 10); 1805 assertEqualInt((int)offset, 0); 1806 assertEqualMem(p, "0123456789", 10); 1807 assertEqualInt(ARCHIVE_EOF, 1808 archive_read_data_block(a, &p, &size, 1809 &offset)); 1810 assertEqualInt((int)size, 0); 1811 assertEqualInt((int)offset, 10); 1812 ++match_count; 1813 } 1814 if (archive_read_disk_can_descend(a)) { 1815 /* Descend into the current object */ 1816 assertEqualIntA(a, ARCHIVE_OK, 1817 archive_read_disk_descend(a)); 1818 } 1819 } 1820 failure("Did not match expected filenames"); 1821 assertEqualInt(match_count, 2); 1822 /* 1823 * There is no entry. This will however fail if the directory 1824 * traverse tries to ascend past the initial directory, since 1825 * it lacks permission to do so. 1826 */ 1827 failure("There should be no entry and no error"); 1828 assertEqualIntA(a, ARCHIVE_EOF, 1829 archive_read_next_header2(a, ae)); 1830 1831 /* Close the disk object. */ 1832 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1833 } 1834 1835 assertChdir(".."); 1836 assertChmod("lock", 0755); 1837 assertChmod("lock/lock2", 0755); 1838 1839 /* Destroy the disk object. */ 1840 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1841 archive_entry_free(ae); 1842} 1843 1844DEFINE_TEST(test_read_disk_directory_traversals) 1845{ 1846 /* Basic test. */ 1847 test_basic(); 1848 /* Test hybrid mode; follow symlink initially, then not. */ 1849 test_symlink_hybrid(); 1850 /* Test logical mode; follow all symlinks. */ 1851 test_symlink_logical(); 1852 /* Test logical mode; prevent loop in symlinks. */ 1853 test_symlink_logical_loop(); 1854 /* Test to restore atime. */ 1855 test_restore_atime(); 1856 /* Test callbacks. */ 1857 test_callbacks(); 1858 /* Test nodump. */ 1859 test_nodump(); 1860 /* Test parent overshoot. */ 1861 test_parent(); 1862} 1863