1248590Smm/*- 2248590Smm * Copyright (c) 2011 Tim Kientzle 3248590Smm * Copyright (c) 2011-2012 Andres Mejia 4248590Smm * All rights reserved. 5248590Smm * 6248590Smm * Redistribution and use in source and binary forms, with or without 7248590Smm * modification, are permitted provided that the following conditions 8248590Smm * are met: 9248590Smm * 1. Redistributions of source code must retain the above copyright 10248590Smm * notice, this list of conditions and the following disclaimer. 11248590Smm * 2. Redistributions in binary form must reproduce the above copyright 12248590Smm * notice, this list of conditions and the following disclaimer in the 13248590Smm * documentation and/or other materials provided with the distribution. 14248590Smm * 15248590Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16248590Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17248590Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18248590Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19248590Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20248590Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21248590Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22248590Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23248590Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24248590Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25248590Smm */ 26248590Smm 27248590Smm#include "test.h" 28248590Smm__FBSDID("$FreeBSD$"); 29248590Smm 30248590Smm#if defined(_WIN32) && !defined(__CYGWIN__) 31248590Smm#define open _open 32248590Smm#define close _close 33248590Smm#define read _read 34248590Smm#if !defined(__BORLANDC__) 35248590Smm#ifdef lseek 36248590Smm#undef lseek 37248590Smm#endif 38248590Smm#define lseek(f, o, w) _lseek(f, (long)(o), (int)(w)) 39248590Smm#endif 40248590Smm#endif 41248590Smm 42248590Smmstatic void 43248590Smmtest_splitted_file(void) 44248590Smm{ 45248590Smm char buff[64]; 46248590Smm static const char *reffiles[] = 47248590Smm { 48248590Smm "test_read_splitted_rar_aa", 49248590Smm "test_read_splitted_rar_ab", 50248590Smm "test_read_splitted_rar_ac", 51248590Smm "test_read_splitted_rar_ad", 52248590Smm NULL 53248590Smm }; 54248590Smm const char test_txt[] = "test text document\r\n"; 55248590Smm int size = sizeof(test_txt)-1; 56248590Smm struct archive_entry *ae; 57248590Smm struct archive *a; 58248590Smm 59248590Smm extract_reference_files(reffiles); 60248590Smm assert((a = archive_read_new()) != NULL); 61248590Smm assertA(0 == archive_read_support_filter_all(a)); 62248590Smm assertA(0 == archive_read_support_format_all(a)); 63248590Smm assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); 64248590Smm 65248590Smm /* First header. */ 66248590Smm assertA(0 == archive_read_next_header(a, &ae)); 67248590Smm assertEqualString("test.txt", archive_entry_pathname(ae)); 68248590Smm assertA((int)archive_entry_mtime(ae)); 69248590Smm assertA((int)archive_entry_ctime(ae)); 70248590Smm assertA((int)archive_entry_atime(ae)); 71248590Smm assertEqualInt(20, archive_entry_size(ae)); 72248590Smm assertEqualInt(33188, archive_entry_mode(ae)); 73248590Smm assertA(size == archive_read_data(a, buff, size)); 74248590Smm assertEqualMem(buff, test_txt, size); 75248590Smm 76248590Smm /* Second header. */ 77248590Smm assertA(0 == archive_read_next_header(a, &ae)); 78248590Smm assertEqualString("testlink", archive_entry_pathname(ae)); 79248590Smm assertA((int)archive_entry_mtime(ae)); 80248590Smm assertA((int)archive_entry_ctime(ae)); 81248590Smm assertA((int)archive_entry_atime(ae)); 82248590Smm assertEqualInt(0, archive_entry_size(ae)); 83248590Smm assertEqualInt(41471, archive_entry_mode(ae)); 84248590Smm assertEqualString("test.txt", archive_entry_symlink(ae)); 85248590Smm assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); 86248590Smm 87248590Smm /* Third header. */ 88248590Smm assertA(0 == archive_read_next_header(a, &ae)); 89248590Smm assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); 90248590Smm assertA((int)archive_entry_mtime(ae)); 91248590Smm assertA((int)archive_entry_ctime(ae)); 92248590Smm assertA((int)archive_entry_atime(ae)); 93248590Smm assertEqualInt(20, archive_entry_size(ae)); 94248590Smm assertEqualInt(33188, archive_entry_mode(ae)); 95248590Smm assertA(size == archive_read_data(a, buff, size)); 96248590Smm assertEqualMem(buff, test_txt, size); 97248590Smm 98248590Smm /* Fourth header. */ 99248590Smm assertA(0 == archive_read_next_header(a, &ae)); 100248590Smm assertEqualString("testdir", archive_entry_pathname(ae)); 101248590Smm assertA((int)archive_entry_mtime(ae)); 102248590Smm assertA((int)archive_entry_ctime(ae)); 103248590Smm assertA((int)archive_entry_atime(ae)); 104248590Smm assertEqualInt(0, archive_entry_size(ae)); 105248590Smm assertEqualInt(16877, archive_entry_mode(ae)); 106248590Smm 107248590Smm /* Fifth header. */ 108248590Smm assertA(0 == archive_read_next_header(a, &ae)); 109248590Smm assertEqualString("testemptydir", archive_entry_pathname(ae)); 110248590Smm assertA((int)archive_entry_mtime(ae)); 111248590Smm assertA((int)archive_entry_ctime(ae)); 112248590Smm assertA((int)archive_entry_atime(ae)); 113248590Smm assertEqualInt(0, archive_entry_size(ae)); 114248590Smm assertEqualInt(16877, archive_entry_mode(ae)); 115248590Smm 116248590Smm /* Test EOF */ 117248590Smm assertA(1 == archive_read_next_header(a, &ae)); 118248590Smm assertEqualInt(5, archive_file_count(a)); 119248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 120248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 121248590Smm} 122248590Smm 123248590Smmstatic void 124248590Smmtest_large_splitted_file(void) 125248590Smm{ 126248590Smm static const char *reffiles[] = 127248590Smm { 128248590Smm "test_read_large_splitted_rar_aa", 129248590Smm "test_read_large_splitted_rar_ab", 130248590Smm "test_read_large_splitted_rar_ac", 131248590Smm "test_read_large_splitted_rar_ad", 132248590Smm "test_read_large_splitted_rar_ae", 133248590Smm NULL 134248590Smm }; 135248590Smm const char test_txt[] = "gin-bottom: 0in\"><BR>\n</P>\n</BODY>\n</HTML>"; 136248590Smm int size = 241647978, offset = 0; 137248590Smm char buff[64]; 138248590Smm struct archive_entry *ae; 139248590Smm struct archive *a; 140248590Smm 141248590Smm extract_reference_files(reffiles); 142248590Smm assert((a = archive_read_new()) != NULL); 143248590Smm assertA(0 == archive_read_support_filter_all(a)); 144248590Smm assertA(0 == archive_read_support_format_all(a)); 145248590Smm assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); 146248590Smm 147248590Smm /* First header. */ 148248590Smm assertA(0 == archive_read_next_header(a, &ae)); 149248590Smm assertEqualString("ppmd_lzss_conversion_test.txt", 150248590Smm archive_entry_pathname(ae)); 151248590Smm assertA((int)archive_entry_mtime(ae)); 152248590Smm assertA((int)archive_entry_ctime(ae)); 153248590Smm assertA((int)archive_entry_atime(ae)); 154248590Smm assertEqualInt(size, archive_entry_size(ae)); 155248590Smm assertEqualInt(33188, archive_entry_mode(ae)); 156248590Smm while (offset + (int)sizeof(buff) < size) 157248590Smm { 158248590Smm assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); 159248590Smm offset += sizeof(buff); 160248590Smm } 161248590Smm assertA(size - offset == archive_read_data(a, buff, size - offset)); 162248590Smm assertEqualMem(buff, test_txt, size - offset); 163248590Smm 164248590Smm /* Test EOF */ 165248590Smm assertA(1 == archive_read_next_header(a, &ae)); 166248590Smm assertEqualInt(1, archive_file_count(a)); 167248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 168248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 169248590Smm} 170248590Smm 171248590Smm#define BLOCK_SIZE 10240 172248590Smmstruct mydata { 173248590Smm char *filename; 174248590Smm void *buffer; 175248590Smm int fd; 176248590Smm}; 177248590Smm 178248590Smmstatic int 179248590Smmfile_open(struct archive *a, void *data) 180248590Smm{ 181248590Smm struct mydata *mydata = (struct mydata *)data; 182248590Smm (void)a; 183248590Smm if (mydata->fd < 0) 184248590Smm { 185248590Smm mydata->fd = open(mydata->filename, O_RDONLY | O_BINARY); 186248590Smm if (mydata->fd >= 0) 187248590Smm { 188248590Smm if ((mydata->buffer = (void*)calloc(1, BLOCK_SIZE)) == NULL) 189248590Smm return (ARCHIVE_FAILED); 190248590Smm } 191248590Smm } 192248590Smm return (ARCHIVE_OK); 193248590Smm} 194248590Smmstatic ssize_t 195248590Smmfile_read(struct archive *a, void *data, const void **buff) 196248590Smm{ 197248590Smm struct mydata *mydata = (struct mydata *)data; 198248590Smm (void)a; 199248590Smm *buff = mydata->buffer; 200248590Smm return read(mydata->fd, mydata->buffer, BLOCK_SIZE); 201248590Smm} 202248590Smmstatic int64_t 203248590Smmfile_skip(struct archive *a, void *data, int64_t request) 204248590Smm{ 205248590Smm struct mydata *mydata = (struct mydata *)data; 206248590Smm int64_t result = lseek(mydata->fd, SEEK_CUR, request); 207248590Smm if (result >= 0) 208248590Smm return result; 209248590Smm archive_set_error(a, errno, "Error seeking in '%s'", mydata->filename); 210248590Smm return -1; 211248590Smm} 212248590Smmstatic int 213248590Smmfile_switch(struct archive *a, void *data1, void *data2) 214248590Smm{ 215248590Smm struct mydata *mydata1 = (struct mydata *)data1; 216248590Smm struct mydata *mydata2 = (struct mydata *)data2; 217248590Smm int r = (ARCHIVE_OK); 218248590Smm 219248590Smm (void)a; 220248590Smm if (mydata1 && mydata1->fd >= 0) 221248590Smm { 222248590Smm close(mydata1->fd); 223248590Smm free(mydata1->buffer); 224248590Smm mydata1->buffer = NULL; 225248590Smm mydata1->fd = -1; 226248590Smm } 227248590Smm if (mydata2) 228248590Smm { 229248590Smm r = file_open(a, mydata2); 230248590Smm } 231248590Smm return (r); 232248590Smm} 233248590Smmstatic int 234248590Smmfile_close(struct archive *a, void *data) 235248590Smm{ 236248590Smm struct mydata *mydata = (struct mydata *)data; 237248590Smm if (mydata == NULL) 238248590Smm return (ARCHIVE_FATAL); 239248590Smm file_switch(a, mydata, NULL); 240248590Smm free(mydata->filename); 241248590Smm free(mydata); 242248590Smm return (ARCHIVE_OK); 243248590Smm} 244248590Smmstatic int64_t 245248590Smmfile_seek(struct archive *a, void *data, int64_t request, int whence) 246248590Smm{ 247248590Smm struct mydata *mine = (struct mydata *)data; 248248590Smm int64_t r; 249248590Smm 250248590Smm (void)a; 251248590Smm r = lseek(mine->fd, request, whence); 252248590Smm if (r >= 0) 253248590Smm return r; 254248590Smm return (ARCHIVE_FATAL); 255248590Smm} 256248590Smm 257248590Smmstatic void 258248590Smmtest_customized_multiple_data_objects(void) 259248590Smm{ 260248590Smm char buff[64]; 261248590Smm static const char *reffiles[] = 262248590Smm { 263248590Smm "test_read_splitted_rar_aa", 264248590Smm "test_read_splitted_rar_ab", 265248590Smm "test_read_splitted_rar_ac", 266248590Smm "test_read_splitted_rar_ad", 267248590Smm NULL 268248590Smm }; 269248590Smm const char test_txt[] = "test text document\r\n"; 270248590Smm int size = sizeof(test_txt)-1; 271248590Smm struct archive_entry *ae; 272248590Smm struct archive *a; 273248590Smm struct mydata *mydata; 274248590Smm const char *filename = *reffiles; 275248590Smm int i; 276248590Smm 277248590Smm extract_reference_files(reffiles); 278248590Smm assert((a = archive_read_new()) != NULL); 279248590Smm assertA(0 == archive_read_support_filter_all(a)); 280248590Smm assertA(0 == archive_read_support_format_all(a)); 281248590Smm 282248590Smm for (i = 0; filename != NULL;) 283248590Smm { 284248590Smm assert((mydata = (struct mydata *)calloc(1, sizeof(*mydata))) != NULL); 285248590Smm if (mydata == NULL) { 286248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 287248590Smm return; 288248590Smm } 289248590Smm assert((mydata->filename = 290248590Smm (char *)calloc(1, strlen(filename) + 1)) != NULL); 291248590Smm if (mydata->filename == NULL) { 292248590Smm free(mydata); 293248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 294248590Smm return; 295248590Smm } 296248590Smm strcpy(mydata->filename, filename); 297248590Smm mydata->fd = -1; 298248590Smm filename = reffiles[++i]; 299248590Smm assertA(0 == archive_read_append_callback_data(a, mydata)); 300248590Smm } 301248590Smm assertA(0 == archive_read_set_open_callback(a, file_open)); 302248590Smm assertA(0 == archive_read_set_read_callback(a, file_read)); 303248590Smm assertA(0 == archive_read_set_skip_callback(a, file_skip)); 304248590Smm assertA(0 == archive_read_set_close_callback(a, file_close)); 305248590Smm assertA(0 == archive_read_set_switch_callback(a, file_switch)); 306248590Smm assertA(0 == archive_read_set_seek_callback(a, file_seek)); 307248590Smm assertA(0 == archive_read_open1(a)); 308248590Smm 309248590Smm /* First header. */ 310248590Smm assertA(0 == archive_read_next_header(a, &ae)); 311248590Smm assertEqualString("test.txt", archive_entry_pathname(ae)); 312248590Smm assertA((int)archive_entry_mtime(ae)); 313248590Smm assertA((int)archive_entry_ctime(ae)); 314248590Smm assertA((int)archive_entry_atime(ae)); 315248590Smm assertEqualInt(20, archive_entry_size(ae)); 316248590Smm assertEqualInt(33188, archive_entry_mode(ae)); 317248590Smm assertA(size == archive_read_data(a, buff, size)); 318248590Smm assertEqualMem(buff, test_txt, size); 319248590Smm 320248590Smm /* Second header. */ 321248590Smm assertA(0 == archive_read_next_header(a, &ae)); 322248590Smm assertEqualString("testlink", archive_entry_pathname(ae)); 323248590Smm assertA((int)archive_entry_mtime(ae)); 324248590Smm assertA((int)archive_entry_ctime(ae)); 325248590Smm assertA((int)archive_entry_atime(ae)); 326248590Smm assertEqualInt(0, archive_entry_size(ae)); 327248590Smm assertEqualInt(41471, archive_entry_mode(ae)); 328248590Smm assertEqualString("test.txt", archive_entry_symlink(ae)); 329248590Smm assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); 330248590Smm 331248590Smm /* Third header. */ 332248590Smm assertA(0 == archive_read_next_header(a, &ae)); 333248590Smm assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); 334248590Smm assertA((int)archive_entry_mtime(ae)); 335248590Smm assertA((int)archive_entry_ctime(ae)); 336248590Smm assertA((int)archive_entry_atime(ae)); 337248590Smm assertEqualInt(20, archive_entry_size(ae)); 338248590Smm assertEqualInt(33188, archive_entry_mode(ae)); 339248590Smm assertA(size == archive_read_data(a, buff, size)); 340248590Smm assertEqualMem(buff, test_txt, size); 341248590Smm 342248590Smm /* Fourth header. */ 343248590Smm assertA(0 == archive_read_next_header(a, &ae)); 344248590Smm assertEqualString("testdir", archive_entry_pathname(ae)); 345248590Smm assertA((int)archive_entry_mtime(ae)); 346248590Smm assertA((int)archive_entry_ctime(ae)); 347248590Smm assertA((int)archive_entry_atime(ae)); 348248590Smm assertEqualInt(0, archive_entry_size(ae)); 349248590Smm assertEqualInt(16877, archive_entry_mode(ae)); 350248590Smm 351248590Smm /* Fifth header. */ 352248590Smm assertA(0 == archive_read_next_header(a, &ae)); 353248590Smm assertEqualString("testemptydir", archive_entry_pathname(ae)); 354248590Smm assertA((int)archive_entry_mtime(ae)); 355248590Smm assertA((int)archive_entry_ctime(ae)); 356248590Smm assertA((int)archive_entry_atime(ae)); 357248590Smm assertEqualInt(0, archive_entry_size(ae)); 358248590Smm assertEqualInt(16877, archive_entry_mode(ae)); 359248590Smm 360248590Smm /* Test EOF */ 361248590Smm assertA(1 == archive_read_next_header(a, &ae)); 362248590Smm assertEqualInt(5, archive_file_count(a)); 363248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 364248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 365248590Smm} 366248590Smm 367248590SmmDEFINE_TEST(test_archive_read_multiple_data_objects) 368248590Smm{ 369248590Smm test_splitted_file(); 370248590Smm test_large_splitted_file(); 371248590Smm test_customized_multiple_data_objects(); 372248590Smm} 373