1) file: clean up path conversion call sites (was using private routine)
2) all: change file_enum and cohorts to pass struct stat instead of just size 3) minor cleanup This was SVN commit r1465.
This commit is contained in:
parent
1d1a2ce3e4
commit
e15562b7ae
@ -197,7 +197,7 @@ int file_rel_chdir(const char* argv0, const char* const rel_path)
|
||||
msg = "realpath returned an invalid path?";
|
||||
goto fail;
|
||||
}
|
||||
CHECK_ERR(convert_path(fn+1, rel_path));
|
||||
CHECK_ERR(file_make_native_path(rel_path, fn+1));
|
||||
|
||||
if(chdir(n_path) < 0)
|
||||
goto fail;
|
||||
@ -231,18 +231,29 @@ fail:
|
||||
struct DirEnt
|
||||
{
|
||||
const std::string name;
|
||||
const off_t size;
|
||||
|
||||
DirEnt(const char* const _name, const off_t _size)
|
||||
: name(_name), size(_size) {}
|
||||
// store only required fields from struct stat to save space.
|
||||
// in order of decl in VC2003 sys/stat.h.
|
||||
mode_t st_mode;
|
||||
off_t st_size;
|
||||
time_t st_mtime;
|
||||
|
||||
DirEnt(const char* _name, mode_t _st_mode, off_t _st_size, time_t _st_mtime)
|
||||
: name(_name)
|
||||
{
|
||||
st_mode = _st_mode;
|
||||
st_size = _st_size;
|
||||
st_mtime = _st_mtime;
|
||||
}
|
||||
|
||||
// no copy ctor, since some members are const
|
||||
private:
|
||||
DirEnt& operator=(const DirEnt&);
|
||||
};
|
||||
|
||||
// pointer to DirEnt: faster sorting, but more allocs.
|
||||
typedef std::vector<const DirEnt*> DirEnts;
|
||||
typedef DirEnts::const_iterator DirEntIt;
|
||||
typedef DirEnts::const_iterator DirEntCIt;
|
||||
typedef DirEnts::reverse_iterator DirEntRIt;
|
||||
|
||||
static bool dirent_less(const DirEnt* const d1, const DirEnt* const d2)
|
||||
@ -250,7 +261,7 @@ static bool dirent_less(const DirEnt* const d1, const DirEnt* const d2)
|
||||
|
||||
|
||||
// call <cb> for each file and subdirectory in <dir> (alphabetical order),
|
||||
// passing <user> and the entry name (not full path!).
|
||||
// passing the entry name (not full path!), stat info, and <user>.
|
||||
//
|
||||
// first builds a list of entries (sorted) and remembers if an error occurred.
|
||||
// if <cb> returns non-zero, abort immediately and return that; otherwise,
|
||||
@ -297,8 +308,9 @@ int file_enum(const char* const dir, const FileCB cb, const uintptr_t user)
|
||||
const char* fn = os_ent->d_name;
|
||||
|
||||
strncpy(fn_start, fn, PATH_MAX-n_path_len-1);
|
||||
// stat needs the full path. this is easier than changing
|
||||
// directory every time, and should be fast enough.
|
||||
// need path for stat (we only have filename ATM).
|
||||
// this is easier than changing directory every time,
|
||||
// and should be fast enough.
|
||||
// BTW, direct strcpy is faster than path_append -
|
||||
// we save a strlen every iteration.
|
||||
|
||||
@ -313,34 +325,33 @@ int file_enum(const char* const dir, const FileCB cb, const uintptr_t user)
|
||||
continue;
|
||||
}
|
||||
|
||||
off_t size = s.st_size;
|
||||
|
||||
// dir
|
||||
if(S_ISDIR(s.st_mode))
|
||||
{
|
||||
// skip . and ..
|
||||
if(fn[0] == '.' && (fn[1] == '\0' || (fn[1] == '.' && fn[2] == '\0')))
|
||||
continue;
|
||||
|
||||
size = -1;
|
||||
}
|
||||
// skip if neither dir nor file
|
||||
else if(!S_ISREG(s.st_mode))
|
||||
continue;
|
||||
|
||||
const DirEnt* const ent = new DirEnt(fn, size);
|
||||
dirents.push_back(ent);
|
||||
dirents.push_back(new DirEnt(fn, s.st_mode, s.st_size, s.st_mtime));
|
||||
}
|
||||
closedir(os_dir);
|
||||
|
||||
std::sort(dirents.begin(), dirents.end(), dirent_less);
|
||||
|
||||
for(DirEntIt it = dirents.begin(); it != dirents.end(); ++it)
|
||||
struct stat s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
for(DirEntCIt it = dirents.begin(); it != dirents.end(); ++it)
|
||||
{
|
||||
const DirEnt* const ent = *it;
|
||||
const char* name_c = ent->name.c_str();
|
||||
const ssize_t size = ent->size;
|
||||
ret = cb(name_c, size, user);
|
||||
s.st_mode = ent->st_mode;
|
||||
s.st_size = ent->st_size;
|
||||
s.st_mtime = ent->st_mtime;
|
||||
ret = cb(name_c, &s, user);
|
||||
if(ret != 0)
|
||||
{
|
||||
cb_err = ret; // first error (since we now abort)
|
||||
@ -364,7 +375,7 @@ int file_stat(const char* const path, struct stat* const s)
|
||||
memset(s, 0, sizeof(struct stat));
|
||||
|
||||
char n_path[PATH_MAX+1];
|
||||
CHECK_ERR(convert_path(n_path, path));
|
||||
CHECK_ERR(file_make_native_path(path, n_path));
|
||||
|
||||
return stat(n_path, s);
|
||||
}
|
||||
@ -456,7 +467,7 @@ int file_open(const char* const p_fn, const uint flags, File* const f)
|
||||
memset(f, 0, sizeof(File));
|
||||
|
||||
char n_fn[PATH_MAX];
|
||||
CHECK_ERR(convert_path(n_fn, p_fn));
|
||||
CHECK_ERR(file_make_native_path(p_fn, n_fn));
|
||||
|
||||
if(!f)
|
||||
goto invalid_f;
|
||||
|
@ -20,6 +20,8 @@
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
#include "posix.h" // struct stat
|
||||
|
||||
|
||||
struct File
|
||||
{
|
||||
@ -95,12 +97,12 @@ extern int file_rel_chdir(const char* argv0, const char* rel_path);
|
||||
|
||||
|
||||
// called by file_enum for each entry in the directory.
|
||||
// name doesn't include path! it's a directory <==> size < 0.
|
||||
// name doesn't include path!
|
||||
// return non-zero to immediately abort; file_enum will return that value.
|
||||
typedef int(*FileCB)(const char* const name, const ssize_t size, const uintptr_t user);
|
||||
typedef int(*FileCB)(const char* const name, const struct stat* s, const uintptr_t user);
|
||||
|
||||
// call <cb> for each file and subdirectory in <dir> (alphabetical order),
|
||||
// passing <user> and the entry name (not full path!).
|
||||
// passing the entry name (not full path!), stat info, and <user>.
|
||||
//
|
||||
// first builds a list of entries (sorted) and remembers if an error occurred.
|
||||
// if <cb> returns non-zero, abort immediately and return that; otherwise,
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "zip.h"
|
||||
#include "res.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// provision for removing all ZLib code (all inflate calls will fail).
|
||||
@ -57,8 +59,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -190,14 +190,6 @@ static int z_verify_lfh(const void* const file, const off_t lfh_ofs, const off_t
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline uint is_leap_year(uint year)
|
||||
{
|
||||
if(year % 4 != 0)
|
||||
return 0;
|
||||
return (year % 100 != 0 || year % 400 == 0)? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static uint bits(uint num, uint lo_idx, uint hi_idx)
|
||||
{
|
||||
uint result = num;
|
||||
@ -211,39 +203,19 @@ static uint bits(uint num, uint lo_idx, uint hi_idx)
|
||||
|
||||
static time_t convert_dos_date(u16 fatdate, u16 fattime)
|
||||
{
|
||||
time_t result = 0;
|
||||
struct tm t;
|
||||
t.tm_sec = bits(fattime, 0,4) * 2; // [0,59]
|
||||
t.tm_min = bits(fattime, 5,10); // [0,59]
|
||||
t.tm_hour = bits(fattime, 11,15); // [0,23]
|
||||
t.tm_mday = bits(fatdate, 0,4); // [1,31]
|
||||
t.tm_mon = bits(fatdate, 5,8)-1; // [0,11]
|
||||
t.tm_year = bits(fatdate, 9,15) + 80; // since 1900
|
||||
t.tm_isdst = -1; // unknown - let libc determine
|
||||
|
||||
uint second = bits(fattime, 0,4) * 2;
|
||||
uint minute = bits(fattime, 5,10); // 0..59
|
||||
uint hour = bits(fattime, 11,15); // 0..23
|
||||
uint day = bits(fatdate, 0,4); // of month; 1..31
|
||||
uint month = bits(fatdate, 5,8); // 1..12
|
||||
uint year = bits(fatdate, 9,15) + 1980;
|
||||
|
||||
if(second >= 60 || minute >= 60 || hour >= 24 || !day || day > 31 || !month || month > 12)
|
||||
{
|
||||
debug_warn("convert_dos_date: not normalized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add days in previous years
|
||||
for(uint y = 1970; y < year; y++)
|
||||
{
|
||||
result += 365;
|
||||
if(is_leap_year(y))
|
||||
result++;
|
||||
}
|
||||
|
||||
// add days in previous months
|
||||
static uint days_in_month[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
days_in_month[1] = is_leap_year(year)? 29 : 28;
|
||||
for(uint m = 1; m < month; m++)
|
||||
result += days_in_month[m-1];
|
||||
|
||||
result += day-1; // total days since 1970
|
||||
result *= 86400; // now seconds
|
||||
result += hour*3600 + minute*60 + second; // total seconds since 1970
|
||||
return result;
|
||||
time_t ret = mktime(&t);
|
||||
if(ret == (time_t)-1)
|
||||
debug_warn("convert_dos_date: mktime failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -283,7 +255,6 @@ static int z_extract_cdfh(const u8* cdfh, const ssize_t bytes_left, const char*&
|
||||
const char* fn_ = (const char*)cdfh+CDFH_SIZE;
|
||||
// not 0-terminated!
|
||||
|
||||
|
||||
//
|
||||
// check if valid and data should actually be returned
|
||||
//
|
||||
@ -296,7 +267,7 @@ static int z_extract_cdfh(const u8* cdfh, const ssize_t bytes_left, const char*&
|
||||
}
|
||||
// .. this is a directory entry; we only want files.
|
||||
if(!csize_ && !ucsize_)
|
||||
return -1;
|
||||
return -1;
|
||||
#ifdef PARANOIA
|
||||
// .. CDFH's file ofs doesn't match that reported by LFH.
|
||||
// don't check this in normal builds - seeking between LFHs and
|
||||
@ -633,10 +604,17 @@ have_idx:
|
||||
// if it returns a nonzero value, abort and return that, otherwise 0.
|
||||
static int lookup_enum_files(LookupInfo* const li, FileCB cb, uintptr_t user)
|
||||
{
|
||||
struct stat s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
const ZEnt* ent = li->ents;
|
||||
for(i32 i = 0; i < li->num_files; i++, ent++)
|
||||
{
|
||||
int ret = cb(ent->fn, (ssize_t)ent->loc.ucsize, user);
|
||||
s.st_mode = S_IFREG;
|
||||
s.st_size = (off_t)ent->loc.ucsize;
|
||||
s.st_mtime = ent->loc.mtime;
|
||||
|
||||
int ret = cb(ent->fn, &s, user);
|
||||
if(ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ struct PathInfo
|
||||
|
||||
// if this file is an OpenAL DLL, add it to our list.
|
||||
// (match "*oal.dll" and "*OpenAL*", as with OpenAL router's search).
|
||||
static int check_if_oal_dll(const char* fn, const ssize_t size, const uintptr_t user)
|
||||
static int check_if_oal_dll(const char* fn, const struct stat* s, const uintptr_t user)
|
||||
{
|
||||
PathInfo* pi = (PathInfo*)user;
|
||||
strncpy(pi->end, fn, pi->remaining);
|
||||
|
Loading…
Reference in New Issue
Block a user