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#if defined(PATH_MAX) && !defined(__GLIBC__) 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#if defined(PATH_MAX) && !defined(__GLIBC__) 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 const char *skip_test_restore_atime; 1051 1052 skip_test_restore_atime = getenv("SKIP_TEST_RESTORE_ATIME"); 1053 if (skip_test_restore_atime != NULL) { 1054 skipping("Skipping restore atime tests due to " 1055 "SKIP_TEST_RESTORE_ATIME environment variable"); 1056 return; 1057 } 1058 if (!atimeIsUpdated()) { 1059 skipping("Can't test restoring atime on this filesystem"); 1060 return; 1061 } 1062 1063 assertMakeDir("at", 0755); 1064 assertMakeFile("at/f1", 0644, "0123456789"); 1065 assertMakeFile("at/f2", 0644, "hello world"); 1066 assertMakeFile("at/fe", 0644, NULL); 1067 assertUtimes("at/f1", 886600, 0, 886600, 0); 1068 assertUtimes("at/f2", 886611, 0, 886611, 0); 1069 assertUtimes("at/fe", 886611, 0, 886611, 0); 1070 assertUtimes("at", 886622, 0, 886622, 0); 1071 file_count = 4; 1072 1073 assert((ae = archive_entry_new()) != NULL); 1074 assert((a = archive_read_disk_new()) != NULL); 1075 1076 /* 1077 * Test1: Traversals without archive_read_disk_set_atime_restored(). 1078 */ 1079 failure("Directory traversals should work as well"); 1080 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1081 while (file_count--) { 1082 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1083 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1084 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1085 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { 1086 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1087 assertEqualInt(archive_entry_size(ae), 10); 1088 assertEqualIntA(a, ARCHIVE_OK, 1089 archive_read_data_block(a, &p, &size, &offset)); 1090 assertEqualInt((int)size, 10); 1091 assertEqualInt((int)offset, 0); 1092 assertEqualMem(p, "0123456789", 10); 1093 assertEqualInt(ARCHIVE_EOF, 1094 archive_read_data_block(a, &p, &size, &offset)); 1095 assertEqualInt((int)size, 0); 1096 assertEqualInt((int)offset, 10); 1097 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { 1098 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1099 assertEqualInt(archive_entry_size(ae), 11); 1100 assertEqualIntA(a, ARCHIVE_OK, 1101 archive_read_data_block(a, &p, &size, &offset)); 1102 assertEqualInt((int)size, 11); 1103 assertEqualInt((int)offset, 0); 1104 assertEqualMem(p, "hello world", 11); 1105 assertEqualInt(ARCHIVE_EOF, 1106 archive_read_data_block(a, &p, &size, &offset)); 1107 assertEqualInt((int)size, 0); 1108 assertEqualInt((int)offset, 11); 1109 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1110 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1111 assertEqualInt(archive_entry_size(ae), 0); 1112 } 1113 if (archive_entry_filetype(ae) == AE_IFDIR) { 1114 /* Descend into the current object */ 1115 assertEqualIntA(a, ARCHIVE_OK, 1116 archive_read_disk_descend(a)); 1117 } 1118 } 1119 /* There is no entry. */ 1120 failure("There must be no entry"); 1121 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1122 1123 /* On FreeBSD (and likely other systems), atime on 1124 dirs does not change when it is read. */ 1125 /* failure("Atime should be restored"); */ 1126 /* assertFileAtimeRecent("at"); */ 1127 failure("Atime should be restored"); 1128 assertFileAtimeRecent("at/f1"); 1129 failure("Atime should be restored"); 1130 assertFileAtimeRecent("at/f2"); 1131 failure("The atime of a empty file should not be changed"); 1132 assertFileAtime("at/fe", 886611, 0); 1133 1134 /* Close the disk object. */ 1135 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1136 1137 /* 1138 * Test2: Traversals with archive_read_disk_set_atime_restored(). 1139 */ 1140 assertUtimes("at/f1", 886600, 0, 886600, 0); 1141 assertUtimes("at/f2", 886611, 0, 886611, 0); 1142 assertUtimes("at/fe", 886611, 0, 886611, 0); 1143 assertUtimes("at", 886622, 0, 886622, 0); 1144 file_count = 4; 1145 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); 1146 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1147 1148 failure("Directory traversals should work as well"); 1149 while (file_count--) { 1150 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1151 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1152 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1153 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { 1154 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1155 assertEqualInt(archive_entry_size(ae), 10); 1156 assertEqualIntA(a, ARCHIVE_OK, 1157 archive_read_data_block(a, &p, &size, &offset)); 1158 assertEqualInt((int)size, 10); 1159 assertEqualInt((int)offset, 0); 1160 assertEqualMem(p, "0123456789", 10); 1161 assertEqualInt(ARCHIVE_EOF, 1162 archive_read_data_block(a, &p, &size, &offset)); 1163 assertEqualInt((int)size, 0); 1164 assertEqualInt((int)offset, 10); 1165 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { 1166 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1167 assertEqualInt(archive_entry_size(ae), 11); 1168 assertEqualIntA(a, ARCHIVE_OK, 1169 archive_read_data_block(a, &p, &size, &offset)); 1170 assertEqualInt((int)size, 11); 1171 assertEqualInt((int)offset, 0); 1172 assertEqualMem(p, "hello world", 11); 1173 assertEqualInt(ARCHIVE_EOF, 1174 archive_read_data_block(a, &p, &size, &offset)); 1175 assertEqualInt((int)size, 0); 1176 assertEqualInt((int)offset, 11); 1177 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1178 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1179 assertEqualInt(archive_entry_size(ae), 0); 1180 } 1181 if (archive_entry_filetype(ae) == AE_IFDIR) { 1182 /* Descend into the current object */ 1183 assertEqualIntA(a, ARCHIVE_OK, 1184 archive_read_disk_descend(a)); 1185 } 1186 } 1187 /* There is no entry. */ 1188 failure("There must be no entry"); 1189 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1190 1191 failure("Atime should be restored"); 1192 assertFileAtime("at", 886622, 0); 1193 failure("Atime should be restored"); 1194 assertFileAtime("at/f1", 886600, 0); 1195 failure("Atime should be restored"); 1196 assertFileAtime("at/f2", 886611, 0); 1197 failure("The atime of a empty file should not be changed"); 1198 assertFileAtime("at/fe", 886611, 0); 1199 1200 /* Close the disk object. */ 1201 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1202 1203 /* 1204 * Test3: Traversals with archive_read_disk_set_atime_restored() but 1205 * no data read as a listing. 1206 */ 1207 assertUtimes("at/f1", 886600, 0, 886600, 0); 1208 assertUtimes("at/f2", 886611, 0, 886611, 0); 1209 assertUtimes("at/fe", 886611, 0, 886611, 0); 1210 assertUtimes("at", 886622, 0, 886622, 0); 1211 file_count = 4; 1212 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); 1213 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1214 1215 failure("Directory traversals should work as well"); 1216 while (file_count--) { 1217 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1218 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1219 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1220 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { 1221 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1222 assertEqualInt(archive_entry_size(ae), 10); 1223 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { 1224 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1225 assertEqualInt(archive_entry_size(ae), 11); 1226 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1227 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1228 assertEqualInt(archive_entry_size(ae), 0); 1229 } 1230 if (archive_entry_filetype(ae) == AE_IFDIR) { 1231 /* Descend into the current object */ 1232 assertEqualIntA(a, ARCHIVE_OK, 1233 archive_read_disk_descend(a)); 1234 } 1235 } 1236 /* There is no entry. */ 1237 failure("There must be no entry"); 1238 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1239 1240 failure("Atime should be restored"); 1241 assertFileAtime("at", 886622, 0); 1242 failure("Atime should be restored"); 1243 assertFileAtime("at/f1", 886600, 0); 1244 failure("Atime should be restored"); 1245 assertFileAtime("at/f2", 886611, 0); 1246 failure("The atime of a empty file should not be changed"); 1247 assertFileAtime("at/fe", 886611, 0); 1248 1249 if (!canNodump()) { 1250 /* Destroy the disk object. */ 1251 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1252 archive_entry_free(ae); 1253 skipping("Can't test atime with nodump on this filesystem"); 1254 return; 1255 } 1256 1257 /* Close the disk object. */ 1258 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1259 1260 /* 1261 * Test4: Traversals with ARCHIVE_READDISK_RESTORE_ATIME and 1262 * ARCHIVE_READDISK_HONOR_NODUMP 1263 */ 1264 assertSetNodump("at/f1"); 1265 assertSetNodump("at/f2"); 1266 assertUtimes("at/f1", 886600, 0, 886600, 0); 1267 assertUtimes("at/f2", 886611, 0, 886611, 0); 1268 assertUtimes("at/fe", 886611, 0, 886611, 0); 1269 assertUtimes("at", 886622, 0, 886622, 0); 1270 file_count = 2; 1271 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, 1272 ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); 1273 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); 1274 1275 failure("Directory traversals should work as well"); 1276 while (file_count--) { 1277 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1278 if (strcmp(archive_entry_pathname(ae), "at") == 0) { 1279 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1280 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { 1281 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1282 assertEqualInt(archive_entry_size(ae), 0); 1283 } 1284 if (archive_entry_filetype(ae) == AE_IFDIR) { 1285 /* Descend into the current object */ 1286 assertEqualIntA(a, ARCHIVE_OK, 1287 archive_read_disk_descend(a)); 1288 } 1289 } 1290 /* There is no entry. */ 1291 failure("There must be no entry"); 1292 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1293 1294 failure("Atime should be restored"); 1295 assertFileAtime("at", 886622, 0); 1296 failure("Atime should be restored"); 1297 assertFileAtime("at/f1", 886600, 0); 1298 failure("Atime should be restored"); 1299 assertFileAtime("at/f2", 886611, 0); 1300 failure("The atime of a empty file should not be changed"); 1301 assertFileAtime("at/fe", 886611, 0); 1302 1303 /* Destroy the disk object. */ 1304 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1305 archive_entry_free(ae); 1306} 1307 1308static int 1309metadata_filter(struct archive *a, void *data, struct archive_entry *ae) 1310{ 1311 (void)data; /* UNUSED */ 1312 1313 failure("CTime should be set"); 1314 assertEqualInt(8, archive_entry_ctime_is_set(ae)); 1315 failure("MTime should be set"); 1316 assertEqualInt(16, archive_entry_mtime_is_set(ae)); 1317 1318 if (archive_entry_mtime(ae) < 886611) 1319 return (0); 1320 if (archive_read_disk_can_descend(a)) { 1321 /* Descend into the current object */ 1322 failure("archive_read_disk_can_descend should work" 1323 " in metadata filter"); 1324 assertEqualIntA(a, 1, archive_read_disk_can_descend(a)); 1325 failure("archive_read_disk_descend should work" 1326 " in metadata filter"); 1327 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); 1328 } 1329 return (1); 1330} 1331 1332static void 1333test_callbacks(void) 1334{ 1335 struct archive *a; 1336 struct archive *m; 1337 struct archive_entry *ae; 1338 const void *p; 1339 size_t size; 1340 int64_t offset; 1341 int file_count; 1342 1343 assertMakeDir("cb", 0755); 1344 assertMakeFile("cb/f1", 0644, "0123456789"); 1345 assertMakeFile("cb/f2", 0644, "hello world"); 1346 assertMakeFile("cb/fe", 0644, NULL); 1347 assertUtimes("cb/f1", 886600, 0, 886600, 0); 1348 assertUtimes("cb/f2", 886611, 0, 886611, 0); 1349 assertUtimes("cb/fe", 886611, 0, 886611, 0); 1350 assertUtimes("cb", 886622, 0, 886622, 0); 1351 1352 assert((ae = archive_entry_new()) != NULL); 1353 assert((a = archive_read_disk_new()) != NULL); 1354 if (a == NULL) { 1355 archive_entry_free(ae); 1356 return; 1357 } 1358 assert((m = archive_match_new()) != NULL); 1359 if (m == NULL) { 1360 archive_entry_free(ae); 1361 archive_read_free(a); 1362 archive_match_free(m); 1363 return; 1364 } 1365 1366 /* 1367 * Test1: Traversals with a name filter. 1368 */ 1369 file_count = 3; 1370 assertEqualIntA(m, ARCHIVE_OK, 1371 archive_match_exclude_pattern(m, "cb/f2")); 1372 assertEqualIntA(a, ARCHIVE_OK, 1373 archive_read_disk_set_matching(a, m, NULL, NULL)); 1374 failure("Directory traversals should work as well"); 1375 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); 1376 while (file_count--) { 1377 archive_entry_clear(ae); 1378 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1379 failure("File 'cb/f2' should be exclueded"); 1380 assert(strcmp(archive_entry_pathname(ae), "cb/f2") != 0); 1381 if (strcmp(archive_entry_pathname(ae), "cb") == 0) { 1382 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1383 } else if (strcmp(archive_entry_pathname(ae), "cb/f1") == 0) { 1384 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1385 assertEqualInt(archive_entry_size(ae), 10); 1386 assertEqualIntA(a, ARCHIVE_OK, 1387 archive_read_data_block(a, &p, &size, &offset)); 1388 assertEqualInt((int)size, 10); 1389 assertEqualInt((int)offset, 0); 1390 assertEqualMem(p, "0123456789", 10); 1391 assertEqualInt(ARCHIVE_EOF, 1392 archive_read_data_block(a, &p, &size, &offset)); 1393 assertEqualInt((int)size, 0); 1394 assertEqualInt((int)offset, 10); 1395 } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { 1396 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1397 assertEqualInt(archive_entry_size(ae), 0); 1398 } 1399 if (archive_read_disk_can_descend(a)) { 1400 /* Descend into the current object */ 1401 assertEqualIntA(a, ARCHIVE_OK, 1402 archive_read_disk_descend(a)); 1403 } 1404 } 1405 /* There is no entry. */ 1406 failure("There should be no entry"); 1407 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1408 1409 /* Close the disk object. */ 1410 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1411 1412 /* Reset name filter */ 1413 assertEqualIntA(a, ARCHIVE_OK, 1414 archive_read_disk_set_matching(a, NULL, NULL, NULL)); 1415 1416 /* 1417 * Test2: Traversals with a metadata filter. 1418 */ 1419 assertUtimes("cb/f1", 886600, 0, 886600, 0); 1420 assertUtimes("cb/f2", 886611, 0, 886611, 0); 1421 assertUtimes("cb/fe", 886611, 0, 886611, 0); 1422 assertUtimes("cb", 886622, 0, 886622, 0); 1423 file_count = 3; 1424 assertEqualIntA(a, ARCHIVE_OK, 1425 archive_read_disk_set_metadata_filter_callback(a, metadata_filter, 1426 NULL)); 1427 failure("Directory traversals should work as well"); 1428 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); 1429 1430 while (file_count--) { 1431 archive_entry_clear(ae); 1432 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1433 failure("File 'cb/f1' should be excluded"); 1434 assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0); 1435 if (strcmp(archive_entry_pathname(ae), "cb") == 0) { 1436 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1437 } else if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0) { 1438 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1439 assertEqualInt(archive_entry_size(ae), 11); 1440 assertEqualIntA(a, ARCHIVE_OK, 1441 archive_read_data_block(a, &p, &size, &offset)); 1442 assertEqualInt((int)size, 11); 1443 assertEqualInt((int)offset, 0); 1444 assertEqualMem(p, "hello world", 11); 1445 assertEqualInt(ARCHIVE_EOF, 1446 archive_read_data_block(a, &p, &size, &offset)); 1447 assertEqualInt((int)size, 0); 1448 assertEqualInt((int)offset, 11); 1449 } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { 1450 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1451 assertEqualInt(archive_entry_size(ae), 0); 1452 } 1453 } 1454 /* There is no entry. */ 1455 failure("There should be no entry"); 1456 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1457 1458 /* Destroy the disk object. */ 1459 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1460 assertEqualInt(ARCHIVE_OK, archive_match_free(m)); 1461 archive_entry_free(ae); 1462} 1463 1464static void 1465test_nodump(void) 1466{ 1467 struct archive *a; 1468 struct archive_entry *ae; 1469 const void *p; 1470 size_t size; 1471 int64_t offset; 1472 int file_count; 1473 1474 if (!canNodump()) { 1475 skipping("Can't test nodump on this filesystem"); 1476 return; 1477 } 1478 1479 assertMakeDir("nd", 0755); 1480 assertMakeFile("nd/f1", 0644, "0123456789"); 1481 assertMakeFile("nd/f2", 0644, "hello world"); 1482 assertMakeFile("nd/fe", 0644, NULL); 1483 assertSetNodump("nd/f2"); 1484 assertUtimes("nd/f1", 886600, 0, 886600, 0); 1485 assertUtimes("nd/f2", 886611, 0, 886611, 0); 1486 assertUtimes("nd/fe", 886611, 0, 886611, 0); 1487 assertUtimes("nd", 886622, 0, 886622, 0); 1488 1489 assert((ae = archive_entry_new()) != NULL); 1490 assert((a = archive_read_disk_new()) != NULL); 1491 1492 /* 1493 * Test1: Traversals without ARCHIVE_READDISK_HONOR_NODUMP 1494 */ 1495 failure("Directory traversals should work as well"); 1496 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); 1497 1498 file_count = 4; 1499 while (file_count--) { 1500 archive_entry_clear(ae); 1501 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1502 if (strcmp(archive_entry_pathname(ae), "nd") == 0) { 1503 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1504 } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { 1505 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1506 assertEqualInt(archive_entry_size(ae), 10); 1507 assertEqualIntA(a, ARCHIVE_OK, 1508 archive_read_data_block(a, &p, &size, &offset)); 1509 assertEqualInt((int)size, 10); 1510 assertEqualInt((int)offset, 0); 1511 assertEqualMem(p, "0123456789", 10); 1512 assertEqualInt(ARCHIVE_EOF, 1513 archive_read_data_block(a, &p, &size, &offset)); 1514 assertEqualInt((int)size, 0); 1515 assertEqualInt((int)offset, 10); 1516 } else if (strcmp(archive_entry_pathname(ae), "nd/f2") == 0) { 1517 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1518 assertEqualInt(archive_entry_size(ae), 11); 1519 assertEqualIntA(a, ARCHIVE_OK, 1520 archive_read_data_block(a, &p, &size, &offset)); 1521 assertEqualInt((int)size, 11); 1522 assertEqualInt((int)offset, 0); 1523 assertEqualMem(p, "hello world", 11); 1524 assertEqualInt(ARCHIVE_EOF, 1525 archive_read_data_block(a, &p, &size, &offset)); 1526 assertEqualInt((int)size, 0); 1527 assertEqualInt((int)offset, 11); 1528 } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { 1529 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1530 assertEqualInt(archive_entry_size(ae), 0); 1531 } 1532 if (archive_read_disk_can_descend(a)) { 1533 /* Descend into the current object */ 1534 assertEqualIntA(a, ARCHIVE_OK, 1535 archive_read_disk_descend(a)); 1536 } 1537 } 1538 /* There is no entry. */ 1539 failure("There should be no entry"); 1540 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1541 1542 /* Close the disk object. */ 1543 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1544 1545 /* 1546 * Test2: Traversals with ARCHIVE_READDISK_HONOR_NODUMP 1547 */ 1548 assertUtimes("nd/f1", 886600, 0, 886600, 0); 1549 assertUtimes("nd/f2", 886611, 0, 886611, 0); 1550 assertUtimes("nd/fe", 886611, 0, 886611, 0); 1551 assertUtimes("nd", 886622, 0, 886622, 0); 1552 1553 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, 1554 ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); 1555 failure("Directory traversals should work as well"); 1556 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); 1557 1558 file_count = 3; 1559 while (file_count--) { 1560 archive_entry_clear(ae); 1561 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1562 failure("File 'nd/f2' should be exclueded"); 1563 assert(strcmp(archive_entry_pathname(ae), "nd/f2") != 0); 1564 if (strcmp(archive_entry_pathname(ae), "nd") == 0) { 1565 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1566 } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { 1567 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1568 assertEqualInt(archive_entry_size(ae), 10); 1569 assertEqualIntA(a, ARCHIVE_OK, 1570 archive_read_data_block(a, &p, &size, &offset)); 1571 assertEqualInt((int)size, 10); 1572 assertEqualInt((int)offset, 0); 1573 assertEqualMem(p, "0123456789", 10); 1574 assertEqualInt(ARCHIVE_EOF, 1575 archive_read_data_block(a, &p, &size, &offset)); 1576 assertEqualInt((int)size, 0); 1577 assertEqualInt((int)offset, 10); 1578 } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { 1579 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1580 assertEqualInt(archive_entry_size(ae), 0); 1581 } 1582 if (archive_read_disk_can_descend(a)) { 1583 /* Descend into the current object */ 1584 assertEqualIntA(a, ARCHIVE_OK, 1585 archive_read_disk_descend(a)); 1586 } 1587 } 1588 /* There is no entry. */ 1589 failure("There should be no entry"); 1590 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1591 1592 failure("Atime should be restored"); 1593 assertFileAtime("nd/f2", 886611, 0); 1594 1595 /* Destroy the disk object. */ 1596 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1597 archive_entry_free(ae); 1598} 1599 1600static void 1601test_parent(void) 1602{ 1603 struct archive *a; 1604 struct archive_entry *ae; 1605 const void *p; 1606 size_t size; 1607 int64_t offset; 1608 int file_count; 1609 int match_count; 1610 int r; 1611 1612 assertMakeDir("lock", 0311); 1613 assertMakeDir("lock/dir1", 0755); 1614 assertMakeFile("lock/dir1/f1", 0644, "0123456789"); 1615 assertMakeDir("lock/lock2", 0311); 1616 assertMakeDir("lock/lock2/dir1", 0755); 1617 assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789"); 1618 1619 assert((ae = archive_entry_new()) != NULL); 1620 assert((a = archive_read_disk_new()) != NULL); 1621 1622 /* 1623 * Test1: Traverse lock/dir1 as . 1624 */ 1625 assertChdir("lock/dir1"); 1626 1627 failure("Directory traversals should work as well"); 1628 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); 1629 1630 file_count = 2; 1631 match_count = 0; 1632 while (file_count--) { 1633 archive_entry_clear(ae); 1634 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1635 if (strcmp(archive_entry_pathname(ae), ".") == 0) { 1636 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1637 ++match_count; 1638 } else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { 1639 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1640 assertEqualInt(archive_entry_size(ae), 10); 1641 assertEqualIntA(a, ARCHIVE_OK, 1642 archive_read_data_block(a, &p, &size, &offset)); 1643 assertEqualInt((int)size, 10); 1644 assertEqualInt((int)offset, 0); 1645 assertEqualMem(p, "0123456789", 10); 1646 assertEqualInt(ARCHIVE_EOF, 1647 archive_read_data_block(a, &p, &size, &offset)); 1648 assertEqualInt((int)size, 0); 1649 assertEqualInt((int)offset, 10); 1650 ++match_count; 1651 } 1652 if (archive_read_disk_can_descend(a)) { 1653 /* Descend into the current object */ 1654 assertEqualIntA(a, ARCHIVE_OK, 1655 archive_read_disk_descend(a)); 1656 } 1657 } 1658 failure("Did not match expected filenames"); 1659 assertEqualInt(match_count, 2); 1660 /* 1661 * There is no entry. This will however fail if the directory traverse 1662 * tries to ascend past the initial directory, since it lacks permission 1663 * to do so. 1664 */ 1665 failure("There should be no entry and no error"); 1666 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1667 1668 /* Close the disk object. */ 1669 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1670 1671 assertChdir("../.."); 1672 1673 /* 1674 * Test2: Traverse lock/dir1 directly 1675 */ 1676 failure("Directory traversals should work as well"); 1677 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1")); 1678 1679 file_count = 2; 1680 match_count = 0; 1681 while (file_count--) { 1682 archive_entry_clear(ae); 1683 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1684 if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) { 1685 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1686 ++match_count; 1687 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) { 1688 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1689 assertEqualInt(archive_entry_size(ae), 10); 1690 assertEqualIntA(a, ARCHIVE_OK, 1691 archive_read_data_block(a, &p, &size, &offset)); 1692 assertEqualInt((int)size, 10); 1693 assertEqualInt((int)offset, 0); 1694 assertEqualMem(p, "0123456789", 10); 1695 assertEqualInt(ARCHIVE_EOF, 1696 archive_read_data_block(a, &p, &size, &offset)); 1697 assertEqualInt((int)size, 0); 1698 assertEqualInt((int)offset, 10); 1699 ++match_count; 1700 } 1701 if (archive_read_disk_can_descend(a)) { 1702 /* Descend into the current object */ 1703 assertEqualIntA(a, ARCHIVE_OK, 1704 archive_read_disk_descend(a)); 1705 } 1706 } 1707 failure("Did not match expected filenames"); 1708 assertEqualInt(match_count, 2); 1709 /* 1710 * There is no entry. This will however fail if the directory traverse 1711 * tries to ascend past the initial directory, since it lacks permission 1712 * to do so. 1713 */ 1714 failure("There should be no entry and no error"); 1715 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1716 1717 /* Close the disk object. */ 1718 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1719 1720 /* 1721 * Test3: Traverse lock/dir1/. 1722 */ 1723 failure("Directory traversals should work as well"); 1724 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/.")); 1725 1726 file_count = 2; 1727 match_count = 0; 1728 while (file_count--) { 1729 archive_entry_clear(ae); 1730 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1731 if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) { 1732 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1733 ++match_count; 1734 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) { 1735 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1736 assertEqualInt(archive_entry_size(ae), 10); 1737 assertEqualIntA(a, ARCHIVE_OK, 1738 archive_read_data_block(a, &p, &size, &offset)); 1739 assertEqualInt((int)size, 10); 1740 assertEqualInt((int)offset, 0); 1741 assertEqualMem(p, "0123456789", 10); 1742 assertEqualInt(ARCHIVE_EOF, 1743 archive_read_data_block(a, &p, &size, &offset)); 1744 assertEqualInt((int)size, 0); 1745 assertEqualInt((int)offset, 10); 1746 ++match_count; 1747 } 1748 if (archive_read_disk_can_descend(a)) { 1749 /* Descend into the current object */ 1750 assertEqualIntA(a, ARCHIVE_OK, 1751 archive_read_disk_descend(a)); 1752 } 1753 } 1754 failure("Did not match expected filenames"); 1755 assertEqualInt(match_count, 2); 1756 /* 1757 * There is no entry. This will however fail if the directory traverse 1758 * tries to ascend past the initial directory, since it lacks permission 1759 * to do so. 1760 */ 1761 failure("There should be no entry and no error"); 1762 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1763 1764 /* Close the disk object. */ 1765 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1766 1767 /* 1768 * Test4: Traverse lock/lock2/dir1 from inside lock. 1769 * 1770 * This test is expected to fail on platforms with no O_EXEC or 1771 * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because 1772 * the current traversal code can't handle the case where it can't 1773 * obtain an open fd for the initial current directory. We need to 1774 * check that condition here, because if O_EXEC _does_ exist, we don't 1775 * want to overlook any failure. 1776 */ 1777 assertChdir("lock"); 1778 1779 failure("Directory traversals should work as well"); 1780 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1")); 1781 1782 archive_entry_clear(ae); 1783 r = archive_read_next_header2(a, ae); 1784 if (r == ARCHIVE_FAILED) { 1785#if defined(O_PATH) || defined(O_SEARCH) || \ 1786 (defined(__FreeBSD__) && defined(O_EXEC)) 1787 assertEqualIntA(a, ARCHIVE_OK, r); 1788#endif 1789 /* Close the disk object. */ 1790 archive_read_close(a); 1791 } else { 1792 file_count = 2; 1793 match_count = 0; 1794 while (file_count--) { 1795 if (file_count == 0) 1796 assertEqualIntA(a, ARCHIVE_OK, 1797 archive_read_next_header2(a, ae)); 1798 if (strcmp(archive_entry_pathname(ae), 1799 "lock2/dir1") == 0) { 1800 assertEqualInt(archive_entry_filetype(ae), 1801 AE_IFDIR); 1802 ++match_count; 1803 } else if (strcmp(archive_entry_pathname(ae), 1804 "lock2/dir1/f1") == 0) { 1805 assertEqualInt(archive_entry_filetype(ae), 1806 AE_IFREG); 1807 assertEqualInt(archive_entry_size(ae), 10); 1808 assertEqualIntA(a, ARCHIVE_OK, 1809 archive_read_data_block(a, &p, &size, 1810 &offset)); 1811 assertEqualInt((int)size, 10); 1812 assertEqualInt((int)offset, 0); 1813 assertEqualMem(p, "0123456789", 10); 1814 assertEqualInt(ARCHIVE_EOF, 1815 archive_read_data_block(a, &p, &size, 1816 &offset)); 1817 assertEqualInt((int)size, 0); 1818 assertEqualInt((int)offset, 10); 1819 ++match_count; 1820 } 1821 if (archive_read_disk_can_descend(a)) { 1822 /* Descend into the current object */ 1823 assertEqualIntA(a, ARCHIVE_OK, 1824 archive_read_disk_descend(a)); 1825 } 1826 } 1827 failure("Did not match expected filenames"); 1828 assertEqualInt(match_count, 2); 1829 /* 1830 * There is no entry. This will however fail if the directory 1831 * traverse tries to ascend past the initial directory, since 1832 * it lacks permission to do so. 1833 */ 1834 failure("There should be no entry and no error"); 1835 assertEqualIntA(a, ARCHIVE_EOF, 1836 archive_read_next_header2(a, ae)); 1837 1838 /* Close the disk object. */ 1839 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1840 } 1841 1842 assertChdir(".."); 1843 assertChmod("lock", 0755); 1844 assertChmod("lock/lock2", 0755); 1845 1846 /* Destroy the disk object. */ 1847 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1848 archive_entry_free(ae); 1849} 1850 1851DEFINE_TEST(test_read_disk_directory_traversals) 1852{ 1853 /* Basic test. */ 1854 test_basic(); 1855 /* Test hybrid mode; follow symlink initially, then not. */ 1856 test_symlink_hybrid(); 1857 /* Test logical mode; follow all symlinks. */ 1858 test_symlink_logical(); 1859 /* Test logical mode; prevent loop in symlinks. */ 1860 test_symlink_logical_loop(); 1861 /* Test to restore atime. */ 1862 test_restore_atime(); 1863 /* Test callbacks. */ 1864 test_callbacks(); 1865 /* Test nodump. */ 1866 test_nodump(); 1867 /* Test parent overshoot. */ 1868 test_parent(); 1869} 1870