diff -u chmlib-0.37/src/chm_lib.c kchm-0.6.5/libchm++/chm_lib.c --- src/chm_lib.c 2005-10-26 14:17:50.000000000 +0200 +++ src/chm_lib.c 2005-03-15 17:25:28.000000000 +0100 @@ -48,19 +48,19 @@ * * ***************************************************************************/ +#include #include "chm_lib.h" #ifdef CHM_MT +#ifndef _REENTRANT #define _REENTRANT #endif +#endif #include "lzx.h" #include #include -#ifdef CHM_DEBUG -#include -#endif #if __sun || __sgi #include @@ -146,48 +146,17 @@ * many bits as they specify. */ -/* i386, 32-bit, Windows */ -#ifdef WIN32 -typedef unsigned char UChar; -typedef __int16 Int16; -typedef unsigned __int16 UInt16; -typedef __int32 Int32; -typedef unsigned __int32 UInt32; -typedef __int64 Int64; -typedef unsigned __int64 UInt64; - -/* I386, 32-bit, non-Windows */ -/* Sparc */ -/* MIPS */ -/* PPC */ -#elif __i386__ || __sun || __sgi || __ppc__ -typedef unsigned char UChar; -typedef short Int16; -typedef unsigned short UInt16; -typedef long Int32; -typedef unsigned long UInt32; -typedef long long Int64; -typedef unsigned long long UInt64; - -/* x86-64 */ -/* Note that these may be appropriate for other 64-bit machines. */ -#elif __x86_64__ -typedef unsigned char UChar; -typedef short Int16; -typedef unsigned short UInt16; -typedef int Int32; -typedef unsigned int UInt32; -typedef long Int64; -typedef unsigned long UInt64; - -#else - -/* yielding an error is preferable to yielding incorrect behavior */ -#error "Please define the sized types for your platform in chm_lib.c" -#endif +typedef __uint8_t UChar; +typedef __int16_t Int16; +typedef __uint16_t UInt16; +typedef __int32_t Int32; +typedef __uint32_t UInt32; +typedef __int64_t Int64; +typedef __uint64_t UInt64; /* GCC */ #ifdef __GNUC__ + #define memcmp __builtin_memcmp #define memcpy __builtin_memcpy #define strlen __builtin_strlen @@ -195,23 +164,23 @@ #elif defined(WIN32) static int ffs(unsigned int val) { - int bit=1, idx=1; - while (bit != 0 && (val & bit) == 0) - { - bit <<= 1; - ++idx; - } - if (bit == 0) - return 0; - else - return idx; + int bit=1, idx=1; + while (bit != 0 && (val & bit) == 0) + { + bit <<= 1; + ++idx; + } + if (bit == 0) + return 0; + else + return idx; } #endif /* utilities for unmarshalling data */ static int _unmarshal_char_array(unsigned char **pData, - unsigned int *pLenRemain, + unsigned long *pLenRemain, char *dest, int count) { @@ -224,7 +193,7 @@ } static int _unmarshal_uchar_array(unsigned char **pData, - unsigned int *pLenRemain, + unsigned long *pLenRemain, unsigned char *dest, int count) { @@ -236,32 +205,8 @@ return 1; } -static int _unmarshal_int16(unsigned char **pData, - unsigned int *pLenRemain, - Int16 *dest) -{ - if (2 > *pLenRemain) - return 0; - *dest = (*pData)[0] | (*pData)[1]<<8; - *pData += 2; - *pLenRemain -= 2; - return 1; -} - -static int _unmarshal_uint16(unsigned char **pData, - unsigned int *pLenRemain, - UInt16 *dest) -{ - if (2 > *pLenRemain) - return 0; - *dest = (*pData)[0] | (*pData)[1]<<8; - *pData += 2; - *pLenRemain -= 2; - return 1; -} - static int _unmarshal_int32(unsigned char **pData, - unsigned int *pLenRemain, + unsigned long *pLenRemain, Int32 *dest) { if (4 > *pLenRemain) @@ -273,7 +218,7 @@ } static int _unmarshal_uint32(unsigned char **pData, - unsigned int *pLenRemain, + unsigned long *pLenRemain, UInt32 *dest) { if (4 > *pLenRemain) @@ -285,7 +230,7 @@ } static int _unmarshal_int64(unsigned char **pData, - unsigned int *pLenRemain, + unsigned long *pLenRemain, Int64 *dest) { Int64 temp; @@ -305,7 +250,7 @@ } static int _unmarshal_uint64(unsigned char **pData, - unsigned int *pLenRemain, + unsigned long *pLenRemain, UInt64 *dest) { UInt64 temp; @@ -325,7 +270,7 @@ } static int _unmarshal_uuid(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, unsigned char *dest) { return _unmarshal_uchar_array(pData, pDataLen, dest, 16); @@ -368,7 +313,7 @@ }; /* __attribute__ ((aligned (1))); */ static int _unmarshal_itsf_header(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, struct chmItsfHeader *dest) { /* we only know how to deal with the 0x58 and 0x60 byte structures */ @@ -446,7 +391,7 @@ }; /* __attribute__ ((aligned (1))); */ static int _unmarshal_itsp_header(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, struct chmItspHeader *dest) { /* we only know how to deal with a 0x54 byte structures */ @@ -494,7 +439,7 @@ }; /* __attribute__ ((aligned (1))); */ static int _unmarshal_pmgl_header(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, struct chmPmglHeader *dest) { /* we only know how to deal with a 0x14 byte structures */ @@ -525,7 +470,7 @@ }; /* __attribute__ ((aligned (1))); */ static int _unmarshal_pmgi_header(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, struct chmPmgiHeader *dest) { /* we only know how to deal with a 0x8 byte structures */ @@ -553,11 +498,11 @@ UInt32 table_offset; UInt64 uncompressed_len; UInt64 compressed_len; - UInt64 block_len; + UInt64 block_len; }; /* __attribute__ ((aligned (1))); */ static int _unmarshal_lzxc_reset_table(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, struct chmLzxcResetTable *dest) { /* we only know how to deal with a 0x28 byte structures */ @@ -590,12 +535,12 @@ UInt32 version; /* 8 */ UInt32 resetInterval; /* c */ UInt32 windowSize; /* 10 */ - UInt32 windowsPerReset; /* 14 */ + UInt32 unknown_14; /* 14 */ UInt32 unknown_18; /* 18 */ }; static int _unmarshal_lzxc_control_data(unsigned char **pData, - unsigned int *pDataLen, + unsigned long *pDataLen, struct chmLzxcControlData *dest) { /* we want at least 0x18 bytes */ @@ -608,7 +553,7 @@ _unmarshal_uint32 (pData, pDataLen, &dest->version); _unmarshal_uint32 (pData, pDataLen, &dest->resetInterval); _unmarshal_uint32 (pData, pDataLen, &dest->windowSize); - _unmarshal_uint32 (pData, pDataLen, &dest->windowsPerReset); + _unmarshal_uint32 (pData, pDataLen, &dest->unknown_14); if (*pDataLen >= _CHM_LZXC_V2_LEN) _unmarshal_uint32 (pData, pDataLen, &dest->unknown_18); @@ -619,6 +564,7 @@ { dest->resetInterval *= 0x8000; dest->windowSize *= 0x8000; + dest->unknown_14 *= 0x8000; } if (dest->windowSize == 0 || dest->resetInterval == 0) return 0; @@ -658,11 +604,11 @@ #endif UInt64 dir_offset; - UInt64 dir_len; + UInt64 dir_len; UInt64 data_offset; Int32 index_root; Int32 index_head; - UInt32 block_len; + UInt32 block_len; UInt64 span; struct chmUnitInfo rt_unit; @@ -670,7 +616,6 @@ struct chmLzxcResetTable reset_table; /* LZX control data */ - int compression_enabled; UInt32 window_size; UInt32 reset_interval; UInt32 reset_blkcount; @@ -681,7 +626,7 @@ /* cache for decompressed blocks */ UChar **cache_blocks; - UInt64 *cache_block_indices; + Int64 *cache_block_indices; Int32 cache_num_blocks; }; @@ -695,7 +640,11 @@ UInt64 os, Int64 len) { - Int64 readLen=0, oldOs=0; + Int64 readLen=0; +#ifndef CHM_USE_PREAD + Int64 oldOs = 0; +#endif + if (h->fd == CHM_NULL_FD) return readLen; @@ -708,8 +657,8 @@ DWORD actualLen=0; /* awkward Win32 Seek/Tell */ - offsetLo = (unsigned int)(os & 0xffffffffL); - offsetHi = (unsigned int)((os >> 32) & 0xffffffffL); + offsetLo = (unsigned long)(os & 0xffffffffL); + offsetHi = (unsigned long)((os >> 32) & 0xffffffffL); origOffsetLo = SetFilePointer(h->fd, 0, &origOffsetHi, FILE_CURRENT); offsetLo = SetFilePointer(h->fd, offsetLo, &offsetHi, FILE_BEGIN); @@ -731,7 +680,7 @@ #ifdef CHM_USE_IO64 readLen = pread64(h->fd, buf, (long)len, os); #else - readLen = pread(h->fd, buf, (long)len, (unsigned int)os); + readLen = pread(h->fd, buf, (long)len, (unsigned long)os); #endif #else #ifdef CHM_USE_IO64 @@ -760,7 +709,7 @@ #endif { unsigned char sbuffer[256]; - unsigned int sremain; + unsigned long sremain; unsigned char *sbufpos; struct chmFile *newHandle=NULL; struct chmItsfHeader itsfHeader; @@ -781,12 +730,12 @@ #ifdef WIN32 #ifdef PPC_BSTR if ((newHandle->fd=CreateFile(filename, - GENERIC_READ, + GENERIC_READ, FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL)) == CHM_NULL_FD) + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == CHM_NULL_FD) { free(newHandle); return NULL; @@ -864,21 +813,29 @@ if (newHandle->index_root == -1) newHandle->index_root = newHandle->index_head; - /* By default, compression is enabled. */ - newHandle->compression_enabled = 1; - -/* Jed, Sun Jun 27: 'span' doesn't seem to be used anywhere?! */ -#if 0 - /* fetch span */ + /* prefetch most commonly needed unit infos */ if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, _CHMU_SPANINFO, &uiSpan) || - uiSpan.space == CHM_COMPRESSED) + uiSpan.space == CHM_COMPRESSED || + CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_RESET_TABLE, + &newHandle->rt_unit) || + newHandle->rt_unit.space == CHM_COMPRESSED || + CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_CONTENT, + &newHandle->cn_unit) || + newHandle->cn_unit.space == CHM_COMPRESSED || + CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_LZXC_CONTROLDATA, + &uiLzxc) || + uiLzxc.space == CHM_COMPRESSED) { chm_close(newHandle); return NULL; } + /* try to read span */ /* N.B.: we've already checked that uiSpan is in the uncompressed section, * so this should not require attempting to decompress, which may * rely on having a valid "span" @@ -892,73 +849,34 @@ chm_close(newHandle); return NULL; } -#endif - - /* prefetch most commonly needed unit infos */ - if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, - _CHMU_RESET_TABLE, - &newHandle->rt_unit) || - newHandle->rt_unit.space == CHM_COMPRESSED || - CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, - _CHMU_CONTENT, - &newHandle->cn_unit) || - newHandle->cn_unit.space == CHM_COMPRESSED || - CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, - _CHMU_LZXC_CONTROLDATA, - &uiLzxc) || - uiLzxc.space == CHM_COMPRESSED) - { - newHandle->compression_enabled = 0; - } /* read reset table info */ - if (newHandle->compression_enabled) + sremain = _CHM_LZXC_RESETTABLE_V1_LEN; + sbufpos = sbuffer; + if (chm_retrieve_object(newHandle, &newHandle->rt_unit, sbuffer, + 0, sremain) != sremain || + !_unmarshal_lzxc_reset_table(&sbufpos, &sremain, + &newHandle->reset_table)) { - sremain = _CHM_LZXC_RESETTABLE_V1_LEN; - sbufpos = sbuffer; - if (chm_retrieve_object(newHandle, &newHandle->rt_unit, sbuffer, - 0, sremain) != sremain || - !_unmarshal_lzxc_reset_table(&sbufpos, &sremain, - &newHandle->reset_table)) - { - newHandle->compression_enabled = 0; - } + chm_close(newHandle); + return NULL; } /* read control data */ - if (newHandle->compression_enabled) + sremain = (unsigned long)uiLzxc.length; + sbufpos = sbuffer; + if (chm_retrieve_object(newHandle, &uiLzxc, sbuffer, + 0, sremain) != sremain || + !_unmarshal_lzxc_control_data(&sbufpos, &sremain, + &ctlData)) { - sremain = (unsigned int)uiLzxc.length; - if (uiLzxc.length > sizeof(sbuffer)) - { - chm_close(newHandle); - return NULL; - } - - sbufpos = sbuffer; - if (chm_retrieve_object(newHandle, &uiLzxc, sbuffer, - 0, sremain) != sremain || - !_unmarshal_lzxc_control_data(&sbufpos, &sremain, - &ctlData)) - { - newHandle->compression_enabled = 0; - } - - newHandle->window_size = ctlData.windowSize; - newHandle->reset_interval = ctlData.resetInterval; - -/* Jed, Mon Jun 28: Experimentally, it appears that the reset block count */ -/* must be multiplied by this formerly unknown ctrl data field in */ -/* order to decompress some files. */ -#if 0 - newHandle->reset_blkcount = newHandle->reset_interval / - (newHandle->window_size / 2); -#else - newHandle->reset_blkcount = newHandle->reset_interval / - (newHandle->window_size / 2) * - ctlData.windowsPerReset; -#endif + chm_close(newHandle); + return NULL; } + newHandle->window_size = ctlData.windowSize; + newHandle->reset_interval = ctlData.resetInterval; + newHandle->reset_blkcount = newHandle->reset_interval / + (newHandle->window_size / 2); /* initialize cache */ chm_set_param(newHandle, CHM_PARAM_MAX_BLOCKS_CACHED, @@ -1123,12 +1041,14 @@ { /* XXX: implement UTF-8 support, including a real mapping onto * ISO-8859-1? probably there is a library to do this? As is - * immediately apparent from the below code, I'm presently not doing - * any special handling for files in which none of the strings contain - * UTF-8 multi-byte characters. + * immediately apparent from the below code, I'm only handling files + * in which none of the strings contain UTF-8 multi-byte characters. */ while (count != 0) { + if (*(*pEntry) > 0x7f) + return 0; + *path++ = (char)(*(*pEntry)++); --count; } @@ -1167,7 +1087,7 @@ * that is provided for us. */ struct chmPmglHeader header; - unsigned int hremain; + unsigned long hremain; UChar *end; UChar *cur; UChar *temp; @@ -1187,8 +1107,6 @@ /* grab the name */ temp = cur; strLen = _chm_parse_cword(&cur); - if (strLen > CHM_MAX_PATHLEN) - return NULL; if (! _chm_parse_UTF8(&cur, strLen, buffer)) return NULL; @@ -1211,7 +1129,7 @@ * that is provided for us */ struct chmPmgiHeader header; - unsigned int hremain; + unsigned long hremain; int page=-1; UChar *end; UChar *cur; @@ -1230,8 +1148,6 @@ { /* grab the name */ strLen = _chm_parse_cword(&cur); - if (strLen > CHM_MAX_PATHLEN) - return -1; if (! _chm_parse_UTF8(&cur, strLen, buffer)) return -1; @@ -1280,10 +1196,10 @@ if (_chm_fetch_bytes(h, page_buf, (UInt64)h->dir_offset + (UInt64)curPage*h->block_len, h->block_len) != h->block_len) - { - FREEBUF(page_buf); + { + FREEBUF(page_buf); return CHM_RESOLVE_FAILURE; - } + } /* now, if it is a leaf node: */ if (memcmp(page_buf, _chm_pmgl_marker, 4) == 0) @@ -1332,7 +1248,7 @@ Int64 *len) { UChar buffer[8], *dummy; - unsigned int remain; + unsigned long remain; /* for all but the last block, use the reset table */ if (block < h->reset_table.block_count-1) @@ -1409,69 +1325,40 @@ UInt32 blockAlign = (UInt32)(block % h->reset_blkcount); /* reset intvl. aln. */ UInt32 i; /* local loop index */ - /* let the caching system pull its weight! */ - if (block - blockAlign <= h->lzx_last_block && - block >= h->lzx_last_block) - blockAlign = (block - h->lzx_last_block); - /* check if we need previous blocks */ if (blockAlign != 0) { /* fetch all required previous blocks since last reset */ - for (i = blockAlign; i > 0; i--) + for (i = h->reset_blkcount - blockAlign; i > 0; i--) { - UInt32 curBlockIdx = block - i; /* check if we most recently decompressed the previous block */ - if (h->lzx_last_block != curBlockIdx) + if ( (h->lzx_last_block < 0) || (UInt64)h->lzx_last_block != block-i ) { - if ((curBlockIdx % h->reset_blkcount) == 0) - { -#ifdef CHM_DEBUG - fprintf(stderr, "***RESET (1)***\n"); -#endif - LZXreset(h->lzx_state); - } - - indexSlot = (int)((curBlockIdx) % h->cache_num_blocks); - h->cache_block_indices[indexSlot] = curBlockIdx; + indexSlot = (int)((block-i) % h->cache_num_blocks); + h->cache_block_indices[indexSlot] = block-i; if (! h->cache_blocks[indexSlot]) h->cache_blocks[indexSlot] = (UChar *)malloc( - (unsigned int)(h->reset_table.block_len)); + (unsigned int)(h->reset_table.block_len)); lbuffer = h->cache_blocks[indexSlot]; /* decompress the previous block */ -#ifdef CHM_DEBUG - fprintf(stderr, "Decompressing block #%4d (EXTRA)\n", curBlockIdx); -#endif - if (!_chm_get_cmpblock_bounds(h, curBlockIdx, &cmpStart, &cmpLen) || - cmpLen < 0 || - cmpLen > h->reset_table.block_len + 6144 || - _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen || + LZXreset(h->lzx_state); + if (!_chm_get_cmpblock_bounds(h, block-i, &cmpStart, &cmpLen) || + _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen || LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen, (int)h->reset_table.block_len) != DECR_OK) { -#ifdef CHM_DEBUG - fprintf(stderr, " (DECOMPRESS FAILED!)\n"); -#endif FREEBUF(cbuffer); return (Int64)0; } - - h->lzx_last_block = (int)curBlockIdx; } + + h->lzx_last_block = (int)(block - i); } } else - { - if ((block % h->reset_blkcount) == 0) - { -#ifdef CHM_DEBUG - fprintf(stderr, "***RESET (2)***\n"); -#endif - LZXreset(h->lzx_state); - } - } + LZXreset(h->lzx_state); /* allocate slot in cache */ indexSlot = (int)(block % h->cache_num_blocks); @@ -1483,17 +1370,11 @@ *ubuffer = lbuffer; /* decompress the block we actually want */ -#ifdef CHM_DEBUG - fprintf(stderr, "Decompressing block #%4d (REAL )\n", block); -#endif if (! _chm_get_cmpblock_bounds(h, block, &cmpStart, &cmpLen) || _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen || LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen, (int)h->reset_table.block_len) != DECR_OK) { -#ifdef CHM_DEBUG - fprintf(stderr, " (DECOMPRESS FAILED!)\n"); -#endif FREEBUF(cbuffer); return (Int64)0; } @@ -1517,8 +1398,8 @@ UInt64 gotLen; UChar *ubuffer; - if (len <= 0) - return (Int64)0; + if (len <= 0) + return (Int64)0; /* figure out what we need to read */ nBlock = start / h->reset_table.block_len; @@ -1571,7 +1452,7 @@ return (Int64)0; /* starting address must be in correct range */ - if (addr < 0 || addr >= ui->length) + if (addr >= ui->length) return (Int64)0; /* clip length */ @@ -1592,11 +1473,6 @@ else /* ui->space == CHM_COMPRESSED */ { Int64 swath=0, total=0; - - /* if compression is not enabled for this file... */ - if (! h->compression_enabled) - return total; - do { /* swill another mouthful */ @@ -1640,13 +1516,12 @@ struct chmPmglHeader header; UChar *end; UChar *cur; - unsigned int lenRemain; + unsigned long lenRemain; UInt64 ui_path_len; /* the current ui */ struct chmUnitInfo ui; - int type_bits = (what & 0x7); - int filter_bits = (what & 0xF8); + int flag; /* starting page */ curPage = h->index_head; @@ -1678,8 +1553,6 @@ /* loop over this page */ while (cur < end) { - ui.flags = 0; - if (! _chm_parse_PMGL_entry(&cur, &ui)) { FREEBUF(page_buf); @@ -1690,12 +1563,12 @@ ui_path_len = strlen(ui.path)-1; /* check for DIRS */ - if (ui.path[ui_path_len] == '/') - ui.flags |= CHM_ENUMERATE_DIRS; + if (ui.path[ui_path_len] == '/' && !(what & CHM_ENUMERATE_DIRS)) + continue; /* check for FILES */ - if (ui.path[ui_path_len] != '/') - ui.flags |= CHM_ENUMERATE_FILES; + if (ui.path[ui_path_len] != '/' && !(what & CHM_ENUMERATE_FILES)) + continue; /* check for NORMAL vs. META */ if (ui.path[0] == '/') @@ -1703,17 +1576,13 @@ /* check for NORMAL vs. SPECIAL */ if (ui.path[1] == '#' || ui.path[1] == '$') - ui.flags |= CHM_ENUMERATE_SPECIAL; + flag = CHM_ENUMERATE_SPECIAL; else - ui.flags |= CHM_ENUMERATE_NORMAL; + flag = CHM_ENUMERATE_NORMAL; } else - ui.flags |= CHM_ENUMERATE_META; - - if (! (type_bits & ui.flags)) - continue; - - if (filter_bits && ! (filter_bits & ui.flags)) + flag = CHM_ENUMERATE_META; + if (! (what & flag)) continue; /* call the enumerator */ @@ -1769,21 +1638,20 @@ struct chmPmglHeader header; UChar *end; UChar *cur; - unsigned int lenRemain; + unsigned long lenRemain; /* set to 1 once we've started */ int it_has_begun=0; /* the current ui */ struct chmUnitInfo ui; - int type_bits = (what & 0x7); - int filter_bits = (what & 0xF8); + int flag; UInt64 ui_path_len; /* the length of the prefix */ char prefixRectified[CHM_MAX_PATHLEN+1]; int prefixLen; - char lastPath[CHM_MAX_PATHLEN+1]; + char lastPath[CHM_MAX_PATHLEN]; int lastPathLen; /* starting page */ @@ -1791,7 +1659,6 @@ /* initialize pathname state */ strncpy(prefixRectified, prefix, CHM_MAX_PATHLEN); - prefixRectified[CHM_MAX_PATHLEN] = '\0'; prefixLen = strlen(prefixRectified); if (prefixLen != 0) { @@ -1832,8 +1699,6 @@ /* loop over this page */ while (cur < end) { - ui.flags = 0; - if (! _chm_parse_PMGL_entry(&cur, &ui)) { FREEBUF(page_buf); @@ -1868,20 +1733,19 @@ if (strncasecmp(ui.path, lastPath, lastPathLen) == 0) continue; } - strncpy(lastPath, ui.path, CHM_MAX_PATHLEN); - lastPath[CHM_MAX_PATHLEN] = '\0'; + strcpy(lastPath, ui.path); lastPathLen = strlen(lastPath); /* get the length of the path */ ui_path_len = strlen(ui.path)-1; /* check for DIRS */ - if (ui.path[ui_path_len] == '/') - ui.flags |= CHM_ENUMERATE_DIRS; + if (ui.path[ui_path_len] == '/' && !(what & CHM_ENUMERATE_DIRS)) + continue; /* check for FILES */ - if (ui.path[ui_path_len] != '/') - ui.flags |= CHM_ENUMERATE_FILES; + if (ui.path[ui_path_len] != '/' && !(what & CHM_ENUMERATE_FILES)) + continue; /* check for NORMAL vs. META */ if (ui.path[0] == '/') @@ -1889,17 +1753,13 @@ /* check for NORMAL vs. SPECIAL */ if (ui.path[1] == '#' || ui.path[1] == '$') - ui.flags |= CHM_ENUMERATE_SPECIAL; + flag = CHM_ENUMERATE_SPECIAL; else - ui.flags |= CHM_ENUMERATE_NORMAL; + flag = CHM_ENUMERATE_NORMAL; } else - ui.flags |= CHM_ENUMERATE_META; - - if (! (type_bits & ui.flags)) - continue; - - if (filter_bits && ! (filter_bits & ui.flags)) + flag = CHM_ENUMERATE_META; + if (! (what & flag)) continue; /* call the enumerator */