#include "stream/stringstream.h"
#include "os/path.h"
#include "moduleobservers.h"
+#include "filematch.h"
-#define VFS_MAXDIRS 8
+#define VFS_MAXDIRS 64
#if defined(WIN32)
#define PATH_MAX 260
static archives_t g_archives;
static char g_strDirs[VFS_MAXDIRS][PATH_MAX+1];
static int g_numDirs;
+static char g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX+1];
+static int g_numForbiddenDirs = 0;
static bool g_bUsePak = true;
ModuleObservers g_observers;
// reads all pak files from a dir
void InitDirectory(const char* directory, ArchiveModules& archiveModules)
{
- if (g_numDirs == (VFS_MAXDIRS-1))
+ int j;
+
+ g_numForbiddenDirs = 0;
+ StringTokeniser st(GlobalRadiant().getGameDescriptionKeyValue("forbidden_paths"), " ");
+ for(j = 0; j < VFS_MAXDIRS; ++j)
+ {
+ const char *t = st.getToken();
+ if(string_empty(t))
+ break;
+ strncpy(g_strForbiddenDirs[g_numForbiddenDirs], t, PATH_MAX);
+ g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = '\0';
+ ++g_numForbiddenDirs;
+ }
+
+ for(j = 0; j < g_numForbiddenDirs; ++j)
+ {
+ char* dbuf = g_strdup(directory);
+ if(*dbuf && dbuf[strlen(dbuf)-1] == '/')
+ dbuf[strlen(dbuf)-1] = 0;
+ const char *p = strrchr(dbuf, '/');
+ p = (p ? (p+1) : dbuf);
+ if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
+ {
+ g_free(dbuf);
+ break;
+ }
+ g_free(dbuf);
+ }
+ if(j < g_numForbiddenDirs)
+ {
+ printf("Directory %s matched by forbidden dirs, removed\n", directory);
+ return;
+ }
+
+ if (g_numDirs == VFS_MAXDIRS)
return;
strncpy(g_strDirs[g_numDirs], directory, PATH_MAX);
if(name == 0)
break;
+ for(j = 0; j < g_numForbiddenDirs; ++j)
+ {
+ const char *p = strrchr(name, '/');
+ p = (p ? (p+1) : name);
+ if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
+ break;
+ }
+ if(j < g_numForbiddenDirs)
+ continue;
+
const char *ext = strrchr (name, '.');
if(ext && !string_compare_nocase_upper(ext, ".pk3dir"))
{
- if (g_numDirs == (VFS_MAXDIRS-1))
+ if (g_numDirs == VFS_MAXDIRS)
continue;
snprintf(g_strDirs[g_numDirs], PATH_MAX, "%s%s/", path, name);
g_strDirs[g_numDirs][PATH_MAX] = '\0';
g_archives.clear();
g_numDirs = 0;
+ g_numForbiddenDirs = 0;
}
#define VFS_SEARCH_PAK 0x1
const char* FindPath(const char* absolute)
{
+ const char *best = "";
for(archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i)
{
- if(path_equal_n(absolute, (*i).name.c_str(), string_length((*i).name.c_str())))
- {
- return (*i).name.c_str();
- }
+ if(string_length((*i).name.c_str()) > string_length(best))
+ if(path_equal_n(absolute, (*i).name.c_str(), string_length((*i).name.c_str())))
+ best = (*i).name.c_str();
}
- return "";
+ return best;
}
g_observers.detach(observer);
}
- Archive* getArchive(const char* archiveName)
+ Archive* getArchive(const char* archiveName, bool pakonly)
{
for(archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i)
{
- if((*i).is_pakfile)
- {
- if(path_equal((*i).name.c_str(), archiveName))
- {
- return (*i).archive;
- }
- }
+ if(pakonly && !(*i).is_pakfile)
+ continue;
+
+ if(path_equal((*i).name.c_str(), archiveName))
+ return (*i).archive;
}
return 0;
}
- void forEachArchive(const ArchiveNameCallback& callback)
+ void forEachArchive(const ArchiveNameCallback& callback, bool pakonly, bool reverse)
{
+ if (reverse)
+ g_archives.reverse();
+
for(archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i)
{
- if((*i).is_pakfile)
- {
- callback((*i).name.c_str());
- }
+ if(pakonly && !(*i).is_pakfile)
+ continue;
+
+ callback((*i).name.c_str());
}
+
+ if (reverse)
+ g_archives.reverse();
}
};