1167465Smp/*- 259243Sobrien * Copyright (c) 2010-2012 Michihiro NAKAJIMA 359243Sobrien * All rights reserved. 459243Sobrien * 559243Sobrien * Redistribution and use in source and binary forms, with or without 659243Sobrien * modification, are permitted provided that the following conditions 759243Sobrien * are met: 859243Sobrien * 1. Redistributions of source code must retain the above copyright 959243Sobrien * notice, this list of conditions and the following disclaimer. 1059243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1159243Sobrien * notice, this list of conditions and the following disclaimer in the 1259243Sobrien * documentation and/or other materials provided with the distribution. 1359243Sobrien * 1459243Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 1559243Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1659243Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1759243Sobrien * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 1859243Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19100616Smp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2059243Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2159243Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2259243Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2359243Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2459243Sobrien */ 2559243Sobrien#include "test.h" 2659243Sobrien 2759243Sobrien#include <limits.h> 2859243Sobrien#if defined(_WIN32) && !defined(__CYGWIN__) 2959243Sobrien# if !defined(__BORLANDC__) 3059243Sobrien# define getcwd _getcwd 3159243Sobrien# endif 3259243Sobrien#endif 3359243Sobrien 3459243Sobrien/* 3559243Sobrien * Test if the current filesystem is mounted with noatime option. 3659243Sobrien */ 37167465Smpstatic int 3859243SobrienatimeIsUpdated(void) 3959243Sobrien{ 4059243Sobrien const char *fn = "fs_noatime"; 4159243Sobrien struct stat st; 4259243Sobrien#if defined(_WIN32) && !defined(CYGWIN) 4359243Sobrien char *buff = NULL; 44167465Smp char *ptr; 4559243Sobrien int r; 46145479Smp 4759243Sobrien r = systemf("fsutil behavior query disableLastAccess > query_atime"); 48167465Smp if (r == 0) { 49167465Smp buff = slurpfile(NULL, "query_atime"); 5059243Sobrien if (buff != NULL) { 5159243Sobrien ptr = buff; 52167465Smp while(*ptr != '\0' && !isdigit(*ptr)) { 5359243Sobrien ptr++; 54100616Smp } 55100616Smp if (*ptr == '0') { 5659243Sobrien free(buff); 57167465Smp return(1); 5859243Sobrien } else if (*ptr == '1' || *ptr == '2') { 59145479Smp free(buff); 60100616Smp return(0); 61100616Smp } 62100616Smp free(buff); 63100616Smp } 64100616Smp } 65100616Smp#endif 66167465Smp if (!assertMakeFile(fn, 0666, "a")) 67100616Smp return (0); 68100616Smp if (!assertUtimes(fn, 1, 0, 1, 0)) 69100616Smp return (0); 70167465Smp /* Test the file contents in order to update its atime. */ 71167465Smp if (!assertTextFileContents("a", fn)) 7259243Sobrien return (0); 7359243Sobrien if (stat(fn, &st) != 0) 7459243Sobrien return (0); 7559243Sobrien /* Is atime updated? */ 7659243Sobrien if (st.st_atime > 1) 7759243Sobrien return (1); 7859243Sobrien return (0); 79167465Smp} 8059243Sobrien 8159243Sobrienstatic void 8259243Sobrientest_basic(void) 8359243Sobrien{ 8459243Sobrien struct archive *a; 8559243Sobrien struct archive_entry *ae; 8659243Sobrien const void *p; 8759243Sobrien char *initial_cwd, *cwd; 8859243Sobrien size_t size; 8959243Sobrien int64_t offset; 9059243Sobrien int file_count; 9159243Sobrien#if defined(_WIN32) && !defined(__CYGWIN__) 9259243Sobrien wchar_t *wcwd, *wp, *fullpath; 9359243Sobrien#endif 9459243Sobrien 9559243Sobrien assertMakeDir("dir1", 0755); 9659243Sobrien assertMakeFile("dir1/file1", 0644, "0123456789"); 9759243Sobrien assertMakeFile("dir1/file2", 0644, "hello world"); 98145479Smp assertMakeDir("dir1/sub1", 0755); 9959243Sobrien assertMakeFile("dir1/sub1/file1", 0644, "0123456789"); 100145479Smp assertMakeDir("dir1/sub2", 0755); 10159243Sobrien assertMakeFile("dir1/sub2/file1", 0644, "0123456789"); 10259243Sobrien assertMakeFile("dir1/sub2/file2", 0644, "0123456789"); 10359243Sobrien assertMakeDir("dir1/sub2/sub1", 0755); 10459243Sobrien assertMakeDir("dir1/sub2/sub2", 0755); 10559243Sobrien assertMakeDir("dir1/sub2/sub3", 0755); 10659243Sobrien assertMakeFile("dir1/sub2/sub3/file", 0644, "xyz"); 10759243Sobrien file_count = 12; 10859243Sobrien 10959243Sobrien assert((ae = archive_entry_new()) != NULL); 110145479Smp assert((a = archive_read_disk_new()) != NULL); 111145479Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); 112145479Smp 11359243Sobrien while (file_count--) { 11459243Sobrien assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 11559243Sobrien if (strcmp(archive_entry_pathname(ae), "dir1") == 0) { 11659243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 11759243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 11859243Sobrien } else if (strcmp(archive_entry_pathname(ae), 11959243Sobrien "dir1/file1") == 0) { 12059243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 12159243Sobrien assertEqualInt(archive_entry_size(ae), 10); 12259243Sobrien assertEqualIntA(a, ARCHIVE_OK, 123100616Smp archive_read_data_block(a, &p, &size, &offset)); 12459243Sobrien assertEqualInt((int)size, 10); 125100616Smp assertEqualInt((int)offset, 0); 126100616Smp assertEqualMem(p, "0123456789", 10); 127100616Smp assertEqualInt(ARCHIVE_EOF, 128100616Smp archive_read_data_block(a, &p, &size, &offset)); 12959243Sobrien assertEqualInt((int)size, 0); 130167465Smp assertEqualInt((int)offset, 10); 131167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 132167465Smp } else if (strcmp(archive_entry_pathname(ae), 133167465Smp "dir1/file2") == 0) { 13459243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 13559243Sobrien assertEqualInt(archive_entry_size(ae), 11); 136145479Smp assertEqualIntA(a, ARCHIVE_OK, 13759243Sobrien archive_read_data_block(a, &p, &size, &offset)); 138145479Smp assertEqualInt((int)size, 11); 13959243Sobrien assertEqualInt((int)offset, 0); 14059243Sobrien assertEqualMem(p, "hello world", 11); 14159243Sobrien assertEqualInt(ARCHIVE_EOF, 14259243Sobrien archive_read_data_block(a, &p, &size, &offset)); 143100616Smp assertEqualInt((int)size, 0); 144100616Smp assertEqualInt((int)offset, 11); 145167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 146167465Smp } else if (strcmp(archive_entry_pathname(ae), 147167465Smp "dir1/sub1") == 0) { 148167465Smp assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 149100616Smp assertEqualInt(1, archive_read_disk_can_descend(a)); 150100616Smp } else if (strcmp(archive_entry_pathname(ae), 151145479Smp "dir1/sub1/file1") == 0) { 152100616Smp assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 153100616Smp assertEqualInt(archive_entry_size(ae), 10); 15459243Sobrien assertEqualIntA(a, ARCHIVE_OK, 155100616Smp archive_read_data_block(a, &p, &size, &offset)); 156145479Smp assertEqualInt((int)size, 10); 157100616Smp assertEqualInt((int)offset, 0); 158100616Smp assertEqualMem(p, "0123456789", 10); 159100616Smp assertEqualInt(ARCHIVE_EOF, 160100616Smp archive_read_data_block(a, &p, &size, &offset)); 161100616Smp assertEqualInt((int)size, 0); 162100616Smp assertEqualInt((int)offset, 10); 16359243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 16459243Sobrien } else if (strcmp(archive_entry_pathname(ae), 16559243Sobrien "dir1/sub2") == 0) { 16659243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 16759243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 16859243Sobrien } else if (strcmp(archive_entry_pathname(ae), 16959243Sobrien "dir1/sub2/file1") == 0) { 17059243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 17159243Sobrien assertEqualInt(archive_entry_size(ae), 10); 17259243Sobrien assertEqualIntA(a, ARCHIVE_OK, 17359243Sobrien archive_read_data_block(a, &p, &size, &offset)); 17459243Sobrien assertEqualInt((int)size, 10); 175167465Smp assertEqualInt((int)offset, 0); 17659243Sobrien assertEqualMem(p, "0123456789", 10); 177167465Smp assertEqualInt(ARCHIVE_EOF, 17859243Sobrien archive_read_data_block(a, &p, &size, &offset)); 17959243Sobrien assertEqualInt((int)size, 0); 180167465Smp assertEqualInt((int)offset, 10); 18159243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 18259243Sobrien } else if (strcmp(archive_entry_pathname(ae), 183131962Smp "dir1/sub2/file2") == 0) { 184131962Smp assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 185131962Smp assertEqualInt(archive_entry_size(ae), 10); 186131962Smp assertEqualIntA(a, ARCHIVE_OK, 187131962Smp archive_read_data_block(a, &p, &size, &offset)); 18859243Sobrien assertEqualInt((int)size, 10); 18959243Sobrien assertEqualInt((int)offset, 0); 19059243Sobrien assertEqualMem(p, "0123456789", 10); 191100616Smp assertEqualInt(ARCHIVE_EOF, 192100616Smp archive_read_data_block(a, &p, &size, &offset)); 193167465Smp assertEqualInt((int)size, 0); 194167465Smp assertEqualInt((int)offset, 10); 195167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 196167465Smp } else if (strcmp(archive_entry_pathname(ae), 197100616Smp "dir1/sub2/sub1") == 0) { 198100616Smp assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 199145479Smp assertEqualInt(1, archive_read_disk_can_descend(a)); 200100616Smp } else if (strcmp(archive_entry_pathname(ae), 201100616Smp "dir1/sub2/sub2") == 0) { 20259243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 203100616Smp assertEqualInt(1, archive_read_disk_can_descend(a)); 204145479Smp } else if (strcmp(archive_entry_pathname(ae), 205100616Smp "dir1/sub2/sub3") == 0) { 206100616Smp assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 207100616Smp assertEqualInt(1, archive_read_disk_can_descend(a)); 208100616Smp } else if (strcmp(archive_entry_pathname(ae), 209100616Smp "dir1/sub2/sub3/file") == 0) { 21059243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 21159243Sobrien assertEqualInt(archive_entry_size(ae), 3); 21259243Sobrien assertEqualIntA(a, ARCHIVE_OK, 21359243Sobrien archive_read_data_block(a, &p, &size, &offset)); 21459243Sobrien assertEqualInt((int)size, 3); 21559243Sobrien assertEqualInt((int)offset, 0); 21659243Sobrien assertEqualMem(p, "xyz", 3); 21759243Sobrien assertEqualInt(ARCHIVE_EOF, 21859243Sobrien archive_read_data_block(a, &p, &size, &offset)); 21959243Sobrien assertEqualInt((int)size, 0); 22059243Sobrien assertEqualInt((int)offset, 3); 22159243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 22259243Sobrien } 22359243Sobrien if (archive_entry_filetype(ae) == AE_IFDIR) { 22459243Sobrien /* Descend into the current object */ 22559243Sobrien assertEqualIntA(a, ARCHIVE_OK, 22659243Sobrien archive_read_disk_descend(a)); 22759243Sobrien } 22859243Sobrien } 22959243Sobrien /* There is no entry. */ 23059243Sobrien assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 23159243Sobrien 23259243Sobrien /* Close the disk object. */ 23359243Sobrien assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 23459243Sobrien 23559243Sobrien /* 23659243Sobrien * Test that call archive_read_disk_open_w, wchar_t version. 23759243Sobrien */ 238167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, L"dir1")); 23959243Sobrien 240167465Smp file_count = 12; 24159243Sobrien while (file_count--) { 24259243Sobrien assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 243167465Smp if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) { 24459243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 24559243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 24659243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 24759243Sobrien L"dir1/file1") == 0) { 24859243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 249167465Smp assertEqualInt(archive_entry_size(ae), 10); 25059243Sobrien assertEqualIntA(a, ARCHIVE_OK, 25159243Sobrien archive_read_data_block(a, &p, &size, &offset)); 25259243Sobrien assertEqualInt((int)size, 10); 25359243Sobrien assertEqualInt((int)offset, 0); 25483098Smp assertEqualMem(p, "0123456789", 10); 25559243Sobrien assertEqualInt(ARCHIVE_EOF, 25659243Sobrien archive_read_data_block(a, &p, &size, &offset)); 25759243Sobrien assertEqualInt((int)size, 0); 25859243Sobrien assertEqualInt((int)offset, 10); 25959243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 26059243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 26159243Sobrien L"dir1/file2") == 0) { 26259243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 26359243Sobrien assertEqualInt(archive_entry_size(ae), 11); 26459243Sobrien assertEqualIntA(a, ARCHIVE_OK, 265145479Smp archive_read_data_block(a, &p, &size, &offset)); 266145479Smp assertEqualInt((int)size, 11); 267145479Smp assertEqualInt((int)offset, 0); 26859243Sobrien assertEqualMem(p, "hello world", 11); 269167465Smp assertEqualInt(ARCHIVE_EOF, 270145479Smp archive_read_data_block(a, &p, &size, &offset)); 271145479Smp assertEqualInt((int)size, 0); 272167465Smp assertEqualInt((int)offset, 11); 273167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 27459243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 27559243Sobrien L"dir1/sub1") == 0) { 27659243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 27759243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 278167465Smp } else if (wcscmp(archive_entry_pathname_w(ae), 27959243Sobrien L"dir1/sub1/file1") == 0) { 28083098Smp assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 28159243Sobrien assertEqualInt(archive_entry_size(ae), 10); 28259243Sobrien assertEqualIntA(a, ARCHIVE_OK, 28359243Sobrien archive_read_data_block(a, &p, &size, &offset)); 28459243Sobrien assertEqualInt((int)size, 10); 28559243Sobrien assertEqualInt((int)offset, 0); 28659243Sobrien assertEqualMem(p, "0123456789", 10); 287145479Smp assertEqualInt(ARCHIVE_EOF, 288167465Smp archive_read_data_block(a, &p, &size, &offset)); 28959243Sobrien assertEqualInt((int)size, 0); 29059243Sobrien assertEqualInt((int)offset, 10); 291167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 29259243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 29359243Sobrien L"dir1/sub2") == 0) { 294167465Smp assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 295167465Smp assertEqualInt(1, archive_read_disk_can_descend(a)); 29659243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 29759243Sobrien L"dir1/sub2/file1") == 0) { 29859243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 29959243Sobrien assertEqualInt(archive_entry_size(ae), 10); 300167465Smp assertEqualIntA(a, ARCHIVE_OK, 30159243Sobrien archive_read_data_block(a, &p, &size, &offset)); 30259243Sobrien assertEqualInt((int)size, 10); 30359243Sobrien assertEqualInt((int)offset, 0); 30459243Sobrien assertEqualMem(p, "0123456789", 10); 30559243Sobrien assertEqualInt(ARCHIVE_EOF, 30659243Sobrien archive_read_data_block(a, &p, &size, &offset)); 30759243Sobrien assertEqualInt((int)size, 0); 308167465Smp assertEqualInt((int)offset, 10); 30959243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 31059243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 31159243Sobrien L"dir1/sub2/file2") == 0) { 31259243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 31359243Sobrien assertEqualInt(archive_entry_size(ae), 10); 314167465Smp assertEqualIntA(a, ARCHIVE_OK, 315167465Smp archive_read_data_block(a, &p, &size, &offset)); 31659243Sobrien assertEqualInt((int)size, 10); 31759243Sobrien assertEqualInt((int)offset, 0); 31859243Sobrien assertEqualMem(p, "0123456789", 10); 31959243Sobrien assertEqualInt(ARCHIVE_EOF, 32059243Sobrien archive_read_data_block(a, &p, &size, &offset)); 32159243Sobrien assertEqualInt((int)size, 0); 32259243Sobrien assertEqualInt((int)offset, 10); 32359243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 32459243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 325167465Smp L"dir1/sub2/sub1") == 0) { 32659243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 32759243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 32859243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 32959243Sobrien L"dir1/sub2/sub2") == 0) { 33059243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 33159243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 33259243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 33359243Sobrien L"dir1/sub2/sub3") == 0) { 33459243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 33559243Sobrien assertEqualInt(1, archive_read_disk_can_descend(a)); 33659243Sobrien } else if (wcscmp(archive_entry_pathname_w(ae), 33759243Sobrien L"dir1/sub2/sub3/file") == 0) { 33859243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 33959243Sobrien assertEqualInt(archive_entry_size(ae), 3); 34059243Sobrien assertEqualIntA(a, ARCHIVE_OK, 34159243Sobrien archive_read_data_block(a, &p, &size, &offset)); 34259243Sobrien assertEqualInt((int)size, 3); 34359243Sobrien assertEqualInt((int)offset, 0); 34459243Sobrien assertEqualMem(p, "xyz", 3); 34559243Sobrien assertEqualInt(ARCHIVE_EOF, 34659243Sobrien archive_read_data_block(a, &p, &size, &offset)); 34759243Sobrien assertEqualInt((int)size, 0); 34859243Sobrien assertEqualInt((int)offset, 3); 34959243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 35059243Sobrien } 35159243Sobrien if (archive_entry_filetype(ae) == AE_IFDIR) { 35259243Sobrien /* Descend into the current object */ 35359243Sobrien assertEqualIntA(a, ARCHIVE_OK, 35459243Sobrien archive_read_disk_descend(a)); 35559243Sobrien } 35659243Sobrien } 35759243Sobrien /* There is no entry. */ 35859243Sobrien assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 35959243Sobrien 36059243Sobrien /* Close the disk object. */ 36159243Sobrien assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 36259243Sobrien 36359243Sobrien /* 36459243Sobrien * Test that call archive_read_disk_open with a regular file. 36559243Sobrien */ 366167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/file1")); 36759243Sobrien 36859243Sobrien /* dir1/file1 */ 36959243Sobrien assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 37059243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 37159243Sobrien assertEqualString(archive_entry_pathname(ae), "dir1/file1"); 37259243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 37359243Sobrien assertEqualInt(archive_entry_size(ae), 10); 37459243Sobrien assertEqualIntA(a, ARCHIVE_OK, 375167465Smp archive_read_data_block(a, &p, &size, &offset)); 37659243Sobrien assertEqualInt((int)size, 10); 37759243Sobrien assertEqualInt((int)offset, 0); 37859243Sobrien assertEqualMem(p, "0123456789", 10); 37959243Sobrien 38059243Sobrien /* There is no entry. */ 38159243Sobrien assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 38259243Sobrien 38359243Sobrien /* Close the disk object. */ 38459243Sobrien assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 38559243Sobrien 386167465Smp 387167465Smp#if defined(_WIN32) && !defined(__CYGWIN__) 388167465Smp /* 389167465Smp * Test for wildcard '*' or '?' 390167465Smp */ 39159243Sobrien assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/*1")); 392167465Smp 393167465Smp /* dir1/file1 */ 394167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 395167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 39659243Sobrien assertEqualString(archive_entry_pathname(ae), "dir1/file1"); 397167465Smp assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 398167465Smp assertEqualInt(archive_entry_size(ae), 10); 399167465Smp assertEqualIntA(a, ARCHIVE_OK, 400167465Smp archive_read_data_block(a, &p, &size, &offset)); 401167465Smp assertEqualInt((int)size, 10); 402167465Smp assertEqualInt((int)offset, 0); 403167465Smp assertEqualMem(p, "0123456789", 10); 404167465Smp 405167465Smp /* dir1/sub1 */ 406167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 407167465Smp assertEqualInt(1, archive_read_disk_can_descend(a)); 408167465Smp assertEqualString(archive_entry_pathname(ae), "dir1/sub1"); 409167465Smp assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 410167465Smp 411167465Smp /* Descend into the current object */ 412167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); 413167465Smp 414167465Smp /* dir1/sub1/file1 */ 415167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 416167465Smp assertEqualInt(0, archive_read_disk_can_descend(a)); 417167465Smp assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1"); 418167465Smp assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 419167465Smp assertEqualInt(archive_entry_size(ae), 10); 420167465Smp assertEqualIntA(a, ARCHIVE_OK, 421167465Smp archive_read_data_block(a, &p, &size, &offset)); 422167465Smp assertEqualInt((int)size, 10); 423167465Smp assertEqualInt((int)offset, 0); 42459243Sobrien assertEqualMem(p, "0123456789", 10); 42559243Sobrien 42659243Sobrien /* There is no entry. */ 42759243Sobrien assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 42859243Sobrien 42959243Sobrien /* Close the disk object. */ 43059243Sobrien assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 43159243Sobrien 43259243Sobrien /* 43359243Sobrien * Test for a full-path beginning with "//?/" 43459243Sobrien */ 43559243Sobrien wcwd = _wgetcwd(NULL, 0); 43659243Sobrien fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); 43759243Sobrien wcscpy(fullpath, L"//?/"); 43859243Sobrien wcscat(fullpath, wcwd); 43959243Sobrien wcscat(fullpath, L"/dir1/file1"); 44059243Sobrien free(wcwd); 44159243Sobrien assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); 44259243Sobrien while ((wcwd = wcschr(fullpath, L'\\')) != NULL) 44359243Sobrien *wcwd = L'/'; 44459243Sobrien 44559243Sobrien /* dir1/file1 */ 446167465Smp assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 44759243Sobrien assertEqualInt(0, archive_read_disk_can_descend(a)); 44859243Sobrien assertEqualWString(archive_entry_pathname_w(ae), fullpath); 44959243Sobrien assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 45059243Sobrien assertEqualInt(archive_entry_size(ae), 10); 45159243Sobrien assertEqualIntA(a, ARCHIVE_OK, 45259243Sobrien 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 574static void 575test_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 731static void 732test_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 961static void 962test_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 1040static void 1041test_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 1307static int 1308metadata_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 1331static void 1332test_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 1463static void 1464test_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 1599static void 1600test_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) && !defined(__NetBSD__)) || \ 1611 (defined(__FreeBSD__) && defined(O_EXEC)) 1612#define IGNORE_TRAVERSALS_TEST4 1613 const char *ignore_traversals_test4; 1614 1615 ignore_traversals_test4 = getenv("IGNORE_TRAVERSALS_TEST4"); 1616#endif 1617 1618 assertMakeDir("lock", 0311); 1619 assertMakeDir("lock/dir1", 0755); 1620 assertMakeFile("lock/dir1/f1", 0644, "0123456789"); 1621 assertMakeDir("lock/lock2", 0311); 1622 assertMakeDir("lock/lock2/dir1", 0755); 1623 assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789"); 1624 1625 assert((ae = archive_entry_new()) != NULL); 1626 assert((a = archive_read_disk_new()) != NULL); 1627 1628 /* 1629 * Test1: Traverse lock/dir1 as . 1630 */ 1631 assertChdir("lock/dir1"); 1632 1633 failure("Directory traversals should work as well"); 1634 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); 1635 1636 file_count = 2; 1637 match_count = 0; 1638 while (file_count--) { 1639 archive_entry_clear(ae); 1640 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1641 if (strcmp(archive_entry_pathname(ae), ".") == 0) { 1642 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1643 ++match_count; 1644 } else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { 1645 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1646 assertEqualInt(archive_entry_size(ae), 10); 1647 assertEqualIntA(a, ARCHIVE_OK, 1648 archive_read_data_block(a, &p, &size, &offset)); 1649 assertEqualInt((int)size, 10); 1650 assertEqualInt((int)offset, 0); 1651 assertEqualMem(p, "0123456789", 10); 1652 assertEqualInt(ARCHIVE_EOF, 1653 archive_read_data_block(a, &p, &size, &offset)); 1654 assertEqualInt((int)size, 0); 1655 assertEqualInt((int)offset, 10); 1656 ++match_count; 1657 } 1658 if (archive_read_disk_can_descend(a)) { 1659 /* Descend into the current object */ 1660 assertEqualIntA(a, ARCHIVE_OK, 1661 archive_read_disk_descend(a)); 1662 } 1663 } 1664 failure("Did not match expected filenames"); 1665 assertEqualInt(match_count, 2); 1666 /* 1667 * There is no entry. This will however fail if the directory traverse 1668 * tries to ascend past the initial directory, since it lacks permission 1669 * to do so. 1670 */ 1671 failure("There should be no entry and no error"); 1672 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1673 1674 /* Close the disk object. */ 1675 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1676 1677 assertChdir("../.."); 1678 1679 /* 1680 * Test2: Traverse lock/dir1 directly 1681 */ 1682 failure("Directory traversals should work as well"); 1683 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1")); 1684 1685 file_count = 2; 1686 match_count = 0; 1687 while (file_count--) { 1688 archive_entry_clear(ae); 1689 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1690 if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) { 1691 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1692 ++match_count; 1693 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) { 1694 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1695 assertEqualInt(archive_entry_size(ae), 10); 1696 assertEqualIntA(a, ARCHIVE_OK, 1697 archive_read_data_block(a, &p, &size, &offset)); 1698 assertEqualInt((int)size, 10); 1699 assertEqualInt((int)offset, 0); 1700 assertEqualMem(p, "0123456789", 10); 1701 assertEqualInt(ARCHIVE_EOF, 1702 archive_read_data_block(a, &p, &size, &offset)); 1703 assertEqualInt((int)size, 0); 1704 assertEqualInt((int)offset, 10); 1705 ++match_count; 1706 } 1707 if (archive_read_disk_can_descend(a)) { 1708 /* Descend into the current object */ 1709 assertEqualIntA(a, ARCHIVE_OK, 1710 archive_read_disk_descend(a)); 1711 } 1712 } 1713 failure("Did not match expected filenames"); 1714 assertEqualInt(match_count, 2); 1715 /* 1716 * There is no entry. This will however fail if the directory traverse 1717 * tries to ascend past the initial directory, since it lacks permission 1718 * to do so. 1719 */ 1720 failure("There should be no entry and no error"); 1721 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1722 1723 /* Close the disk object. */ 1724 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1725 1726 /* 1727 * Test3: Traverse lock/dir1/. 1728 */ 1729 failure("Directory traversals should work as well"); 1730 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/.")); 1731 1732 file_count = 2; 1733 match_count = 0; 1734 while (file_count--) { 1735 archive_entry_clear(ae); 1736 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); 1737 if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) { 1738 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); 1739 ++match_count; 1740 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) { 1741 assertEqualInt(archive_entry_filetype(ae), AE_IFREG); 1742 assertEqualInt(archive_entry_size(ae), 10); 1743 assertEqualIntA(a, ARCHIVE_OK, 1744 archive_read_data_block(a, &p, &size, &offset)); 1745 assertEqualInt((int)size, 10); 1746 assertEqualInt((int)offset, 0); 1747 assertEqualMem(p, "0123456789", 10); 1748 assertEqualInt(ARCHIVE_EOF, 1749 archive_read_data_block(a, &p, &size, &offset)); 1750 assertEqualInt((int)size, 0); 1751 assertEqualInt((int)offset, 10); 1752 ++match_count; 1753 } 1754 if (archive_read_disk_can_descend(a)) { 1755 /* Descend into the current object */ 1756 assertEqualIntA(a, ARCHIVE_OK, 1757 archive_read_disk_descend(a)); 1758 } 1759 } 1760 failure("Did not match expected filenames"); 1761 assertEqualInt(match_count, 2); 1762 /* 1763 * There is no entry. This will however fail if the directory traverse 1764 * tries to ascend past the initial directory, since it lacks permission 1765 * to do so. 1766 */ 1767 failure("There should be no entry and no error"); 1768 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); 1769 1770 /* Close the disk object. */ 1771 assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 1772 1773 /* 1774 * Test4: Traverse lock/lock2/dir1 from inside lock. 1775 * 1776 * This test is expected to fail on platforms with no O_EXEC or 1777 * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because 1778 * the current traversal code can't handle the case where it can't 1779 * obtain an open fd for the initial current directory. We need to 1780 * check that condition here, because if O_EXEC _does_ exist, we don't 1781 * want to overlook any failure. 1782 */ 1783 assertChdir("lock"); 1784 1785 failure("Directory traversals should work as well"); 1786 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1")); 1787 1788 archive_entry_clear(ae); 1789 r = archive_read_next_header2(a, ae); 1790 if (r == ARCHIVE_FAILED) { 1791#ifdef IGNORE_TRAVERSALS_TEST4 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 1857DEFINE_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