[asterisk-commits] mnicholson: testsuite/asterisk/trunk r123 - in /asterisk/trunk/asttest: lua/ ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 24 14:17:54 CDT 2010
Author: mnicholson
Date: Wed Mar 24 14:17:51 2010
New Revision: 123
URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=123
Log:
Modify proclib.c to check if a file exists and is executable before executing it. Also added the proc.exists() function for this purpose.
Added:
asterisk/trunk/asttest/self-tests/proclib_exec/
asterisk/trunk/asttest/self-tests/proclib_exec/test.lua (with props)
Modified:
asterisk/trunk/asttest/lua/proclib.c
Modified: asterisk/trunk/asttest/lua/proclib.c
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/asttest/lua/proclib.c?view=diff&rev=123&r1=122&r2=123
==============================================================================
--- asterisk/trunk/asttest/lua/proclib.c (original)
+++ asterisk/trunk/asttest/lua/proclib.c Wed Mar 24 14:17:51 2010
@@ -34,6 +34,120 @@
#include <sys/time.h>
#include <time.h>
+
+/*!
+ * \brief Check if we can execute the given file.
+ * \warn This function only does a very basic check of executability. It is
+ * possible for this function to say a file is executable, but the file not
+ * actually be executable by the user under the current circumstances.
+ */
+static int is_executable(lua_State *L) {
+ struct stat st;
+ const char *path = luaL_checkstring(L, 1);
+
+ if (stat(path, &st)) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, strerror(errno));
+ return 2;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ lua_pushboolean(L, 0);
+ lua_pushliteral(L, "path is not a regular file");
+ return 2;
+ }
+
+ if (!((S_IXUSR | S_IXGRP | S_IXOTH) & st.st_mode)) {
+ lua_pushboolean(L, 0);
+ lua_pushliteral(L, "path is not executable");
+ return 2;
+ }
+
+ /* the file might be executable */
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*!
+ * \brief [lua_CFunction proc.exists] Check if the given file exists and is
+ * executable.
+ * \param L the lua state to use
+ */
+static int proc_exists(lua_State *L) {
+ char *env_path;
+ const char *path = luaL_checkstring(L, 1);
+ char *p;
+ char *c;
+
+ if (strlen(path) == 0) {
+ lua_pushboolean(L, 0);
+ lua_pushliteral(L, "invalid path provided (path was an empty string)");
+ return 2;
+ }
+
+ /* if path starts with '/' then directly stat the given path */
+ if (path[0] == '/') {
+ lua_pushcfunction(L, is_executable);
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 2);
+ return 2;
+ }
+
+ if (!(env_path = getenv("PATH"))) {
+ /* default env_path to the following as indicated in the
+ * exec(3) man page */
+ env_path = ":/bin:/usr/bin";
+ }
+
+ p = env_path;
+ for (p = env_path; (c = strchr(p, ':')); p = ++c) {
+ if (c - p <= 1) {
+ /* empty path component */
+ continue;
+ }
+
+ lua_pushcfunction(L, is_executable);
+
+ lua_pushlstring(L, p, c - p);
+ lua_pushliteral(L, "/");
+ lua_pushvalue(L, 1);
+ lua_concat(L, 3);
+
+ lua_call(L, 1, 2);
+
+ if (lua_toboolean(L, -2)) {
+ lua_pop(L, 1);
+ return 1;
+ }
+
+ lua_pop(L, 2);
+ }
+
+ /* check the last path component */
+ if (strlen(p) != 0) {
+ lua_pushcfunction(L, is_executable);
+
+ lua_pushstring(L, p);
+ lua_pushliteral(L, "/");
+ lua_pushvalue(L, 1);
+ lua_concat(L, 3);
+
+ lua_call(L, 1, 2);
+
+ if (lua_toboolean(L, -2)) {
+ lua_pop(L, 1);
+ return 1;
+ }
+
+ lua_pop(L, 2);
+ }
+
+ /* no executable paths were found */
+ lua_pushboolean(L, 0);
+ lua_pushliteral(L, "no executable found");
+ return 2;
+}
+
static FILE *create_iolib_file(lua_State *L, const char *name, int fd, const char *mode) {
FILE **file;
@@ -87,6 +201,15 @@
const char **argv = build_argv(L, name);
int stdin_pipe[2], stdout_pipe[2], stderr_pipe[2];
+ /* make sure the given path exists and is executable */
+ lua_pushcfunction(L, proc_exists);
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 2);
+
+ if (!lua_toboolean(L, -2)) {
+ goto e_return;
+ }
+
if (pipe(stdin_pipe)) {
lua_pushliteral(L, "error creating stdin pipe: ");
lua_pushstring(L, strerror(errno));
@@ -122,6 +245,7 @@
close(stderr_pipe[0]);
execvp(name, (char * const *) argv);
+ fprintf(stderr, "error spawning process: %s\n", strerror(errno));
exit(1);
} else if (pid == -1) {
lua_pushliteral(L, "error spawning process (fork error): ");
@@ -172,6 +296,7 @@
e_free_argv:
free(argv);
+e_return:
/* error string should already be on the stack */
return lua_error(L);
}
@@ -188,6 +313,15 @@
const char *name = luaL_checkstring(L, 1);
const char **argv = build_argv(L, name);
int fd;
+
+ /* make sure the given path exists and is executable */
+ lua_pushcfunction(L, proc_exists);
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 2);
+
+ if (!lua_toboolean(L, -2)) {
+ goto e_return;
+ }
/* start the process */
pid = fork();
@@ -227,6 +361,7 @@
e_free_argv:
free(argv);
+e_return:
/* error string should already be on the stack */
return lua_error(L);
}
@@ -449,6 +584,7 @@
}
static luaL_Reg proclib[] = {
+ {"exists", proc_exists},
{"exec", exec_proc},
{"exec_io", exec_proc_with_stdio},
{NULL, NULL},
Added: asterisk/trunk/asttest/self-tests/proclib_exec/test.lua
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/asttest/self-tests/proclib_exec/test.lua?view=auto&rev=123
==============================================================================
--- asterisk/trunk/asttest/self-tests/proclib_exec/test.lua (added)
+++ asterisk/trunk/asttest/self-tests/proclib_exec/test.lua Wed Mar 24 14:17:51 2010
@@ -1,0 +1,30 @@
+-- test proclib's ablity to detect missing and non-executable files
+
+
+-- this function expects the give path to exist
+function should_succeed(path)
+ local res, err = proc.exists(path)
+ if not res then
+ fail("error detecting '" .. path .. "': " .. err)
+ end
+end
+
+-- this function expects the given path to NOT exist
+function should_fail(path)
+ local res, err = proc.exists(path)
+ if res then
+ fail("falsely detected '" .. path .. "'")
+ end
+end
+
+should_succeed("echo")
+should_succeed("/bin/echo")
+should_succeed("/bin/sh")
+
+should_fail("this file won't exist, except for under extreme circumstances")
+should_fail("/same for this one")
+should_fail("")
+
+should_fail("/tmp")
+should_fail("/var/log/syslog")
+
Propchange: asterisk/trunk/asttest/self-tests/proclib_exec/test.lua
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: asterisk/trunk/asttest/self-tests/proclib_exec/test.lua
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: asterisk/trunk/asttest/self-tests/proclib_exec/test.lua
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list