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