summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-22 12:26:53 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-22 12:26:53 +0000
commitabb8fd86e78c57461f6729faafec5ea35ccd18a9 (patch)
treec262a150967152852cb015ddcd12a08530aedf7f /crawl-ref/source
parent609ccd171cbe8473c0a03c47392a12e72de2baaa (diff)
downloadcrawl-ref-abb8fd86e78c57461f6729faafec5ea35ccd18a9.tar.gz
crawl-ref-abb8fd86e78c57461f6729faafec5ea35ccd18a9.zip
Pull c_macro out of the code and into clua/macro.lua.
User-script dofile and loadfile check for "clua" anywhere in the file name and refuse to load the file in that case; only core Crawl code can load Lua files from clua/*. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1622 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/clua.cc40
-rw-r--r--crawl-ref/source/clua.h6
-rw-r--r--crawl-ref/source/dat/clua/macro.lua39
-rw-r--r--crawl-ref/source/files.cc8
-rw-r--r--crawl-ref/source/files.h2
-rw-r--r--crawl-ref/source/makefile.mgw2
-rw-r--r--crawl-ref/source/makefile.unix12
7 files changed, 67 insertions, 42 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc
index 5953355df2..2f21d7db44 100644
--- a/crawl-ref/source/clua.cc
+++ b/crawl-ref/source/clua.cc
@@ -216,17 +216,19 @@ int CLua::execstring(const char *s, const char *context)
return err;
}
-bool CLua::is_path_safe(const char *s)
+bool CLua::is_path_safe(std::string s, bool trusted)
{
- return (!strstr(s, "..") && shell_safe(s));
+ lowercase(s);
+ return (s.find("..") == std::string::npos && shell_safe(s.c_str())
+ && (trusted || s.find("clua") == std::string::npos));
}
-int CLua::loadfile(lua_State *ls, const char *filename)
+int CLua::loadfile(lua_State *ls, const char *filename, bool trusted)
{
if (!ls)
return (-1);
- if (!is_path_safe(filename))
+ if (!is_path_safe(filename, trusted))
{
lua_pushstring(
ls,
@@ -238,7 +240,7 @@ int CLua::loadfile(lua_State *ls, const char *filename)
return (luaL_loadfile(ls, file.c_str()));
}
-int CLua::execfile(const char *filename)
+int CLua::execfile(const char *filename, bool trusted)
{
if (sourced_files.find(filename) != sourced_files.end())
return 0;
@@ -246,7 +248,7 @@ int CLua::execfile(const char *filename)
sourced_files.insert(filename);
lua_State *ls = state();
- int err = loadfile(ls, filename);
+ int err = loadfile(ls, filename, trusted);
lua_call_throttle strangler(this);
if (!err)
err = lua_pcall(ls, 0, 0, 0);
@@ -600,31 +602,7 @@ void CLua::load_chooks()
void CLua::load_cmacro()
{
- static const char *c_macro =
- "function c_macro(fn)"
- " if fn == nil then"
- " if c_macro_coroutine ~= nil then"
- " local coret, mret"
- " coret, mret = coroutine.resume(c_macro_coroutine)"
- " if not coret or not mret then"
- " c_macro_coroutine = nil"
- " c_macro_name = nil"
- " end"
- " if not coret and mret then"
- " error(mret)"
- " end"
- " return (coret and mret)"
- " end"
- " return false"
- " end"
- " if _G[fn] == nil or type(_G[fn]) ~= 'function' then"
- " return false"
- " end"
- " c_macro_name = fn"
- " c_macro_coroutine = coroutine.create(_G[fn]) "
- " return c_macro() "
- "end";
- execstring(c_macro, "base");
+ execfile("clua/macro.lua", true);
}
/////////////////////////////////////////////////////////////////////
diff --git a/crawl-ref/source/clua.h b/crawl-ref/source/clua.h
index 419d34c908..0ec9723544 100644
--- a/crawl-ref/source/clua.h
+++ b/crawl-ref/source/clua.h
@@ -64,7 +64,7 @@ public:
void getregistry(const char *name);
int execstring(const char *str, const char *context = "init.txt");
- int execfile(const char *filename);
+ int execfile(const char *filename, bool trusted = false);
bool callbooleanfn(bool defval, const char *fn, const char *params, ...);
bool callfn(const char *fn, int nargs, int nret = 1);
@@ -73,8 +73,8 @@ public:
bool runhook(const char *hook, const char *params, ...);
static int file_write(lua_State *ls);
- static int loadfile(lua_State *ls, const char *file);
- static bool is_path_safe(const char *file);
+ static int loadfile(lua_State *ls, const char *file, bool trusted = false);
+ static bool is_path_safe(std::string file, bool trusted = false);
public:
std::string error;
diff --git a/crawl-ref/source/dat/clua/macro.lua b/crawl-ref/source/dat/clua/macro.lua
new file mode 100644
index 0000000000..b624ed0292
--- /dev/null
+++ b/crawl-ref/source/dat/clua/macro.lua
@@ -0,0 +1,39 @@
+------------------------------------------------------------------
+-- macro.lua:
+-- Crawl macro framework for Lua.
+--
+-- Macros are called as Lua coroutines. If the macro yields false, the
+-- coroutine is discarded (assuming an error). If the macro yields
+-- true, Crawl will start a macro delay for the macro and call the
+-- coroutine again next turn. If the macro just returns, the coroutine
+-- is assumed to be done.
+--
+-- Why coroutines: Macros may need to perform actions that take
+-- multiple turns, which requires control to return to Crawl to
+-- perform world updates between actions. Coroutines are the simplest
+-- way to pass control back and forth without losing the macro's
+-- state.
+------------------------------------------------------------------
+function c_macro(fn)
+ if fn == nil then
+ if c_macro_coroutine ~= nil then
+ local coret, mret
+ coret, mret = coroutine.resume(c_macro_coroutine)
+ if not coret or not mret then
+ c_macro_coroutine = nil
+ c_macro_name = nil
+ end
+ if not coret and mret then
+ error(mret)
+ end
+ return (coret and mret)
+ end
+ return false
+ end
+ if _G[fn] == nil or type(_G[fn]) ~= 'function' then
+ return false
+ end
+ c_macro_name = fn
+ c_macro_coroutine = coroutine.create(_G[fn])
+ return c_macro()
+end \ No newline at end of file
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 68dc9424b2..114a3f23a2 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -285,10 +285,14 @@ static bool create_dirs(const std::string &dir)
return (true);
}
-std::string datafile_path(const std::string &basename,
+std::string datafile_path(std::string basename,
bool croak_on_fail,
bool test_base_path)
{
+#if FILE_SEPARATOR != '/'
+ basename = replace_all_of(basename, "/", std::string(1, FILE_SEPARATOR));
+#endif
+
if (test_base_path && file_exists(basename))
return (basename);
@@ -305,7 +309,7 @@ std::string datafile_path(const std::string &basename,
const std::string prefixes[] = {
std::string("dat") + FILE_SEPARATOR,
std::string("docs") + FILE_SEPARATOR,
- std::string("..")+FILE_SEPARATOR+std::string("docs")+FILE_SEPARATOR,
+ std::string("..") + FILE_SEPARATOR + "docs" + FILE_SEPARATOR,
std::string("..") + FILE_SEPARATOR,
std::string(".") + FILE_SEPARATOR,
"",
diff --git a/crawl-ref/source/files.h b/crawl-ref/source/files.h
index 112e8e620f..c32cc52561 100644
--- a/crawl-ref/source/files.h
+++ b/crawl-ref/source/files.h
@@ -26,7 +26,7 @@
// referenced in files - newgame - ouch:
extern FixedArray<bool, MAX_LEVELS, NUM_BRANCHES> tmp_file_pairs;
-std::string datafile_path(const std::string &basename,
+std::string datafile_path(std::string basename,
bool croak_on_fail = true,
bool test_base_path = false);
std::string get_parent_directory(const std::string &filename);
diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw
index d0056cd958..a9c3fbe381 100644
--- a/crawl-ref/source/makefile.mgw
+++ b/crawl-ref/source/makefile.mgw
@@ -125,8 +125,10 @@ ifneq ($(OPATH),$(INSTALLDIR))
$(COPY) $(APPNAME) ${INSTALLDIR}
endif
mkdir $(INSTALLDIR)\dat 2>nul || echo "" >nul
+ mkdir $(INSTALLDIR)\dat\clua 2>null || echo "">nul
copy /y dat\*.des $(INSTALLDIR)\dat
copy /y dat\*.txt $(INSTALLDIR)\dat
+ copy /y dat\clua\*.lua $(INSTALLDIR)\dat\clua
copy /y ..\init.txt $(INSTALLDIR)
clean:
diff --git a/crawl-ref/source/makefile.unix b/crawl-ref/source/makefile.unix
index 298e249f6a..9a6ed5998f 100644
--- a/crawl-ref/source/makefile.unix
+++ b/crawl-ref/source/makefile.unix
@@ -33,14 +33,14 @@ MCHMOD_SAVEDIR := 775
# The user:group to install the game as.
INSTALL_UGRP := games:games
-INSTALLDIR := /usr/games
+INSTALLDIR := /usr/games/crawl
# If you're installing Crawl for multiple users, you *must* set this to a
# valid path before building Crawl. This is not necessary if you are building
# Crawl for a single user.
-# SAVEDIR := /usr/games/crawl-saves/
-# DATADIR := /usr/games/crawl-data/
+# SAVEDIR := /usr/games/crawl/saves/
+# DATADIR := /usr/games/crawl/data/
LEX := flex
YACC := bison -y
@@ -210,15 +210,16 @@ endif
install: $(GAME)
[ -d $(INSTALLDIR) ] || mkdir -p $(INSTALLDIR)
- $(COPY) $(GAME) ${INSTALLDIR}
+ $(COPY) $(GAME) $(INSTALLDIR)
chown $(INSTALL_UGRP) $(INSTALLDIR)/$(GAME)
chmod ${MCHMOD} ${INSTALLDIR}/$(GAME)
ifeq ($(DATADIR),)
$(error DATADIR not set! Set DATADIR and run make clean install again)
endif
- mkdir -p $(DATADIR)/dat
+ mkdir -p $(DATADIR)/dat/clua
cp dat/*.des $(DATADIR)/dat
cp dat/*.txt $(DATADIR)/dat
+ cp dat/clua/*.lua $(DATADIR)/dat/clua
cp -r lua $(DATADIR)/dat
mkdir -p $(DATADIR)/docs
cp ../docs/*.txt $(DATADIR)/docs
@@ -228,6 +229,7 @@ ifneq ($(SAVEDIR),)
chown $(INSTALL_UGRP) $(SAVEDIR)
chmod $(MCHMOD_SAVEDIR) $(SAVEDIR)
endif
+ ln -s $(INSTALLDIR)/$(GAME) /usr/local/bin/
clean:
$(DELETE) *.o