[svn-commits] mnicholson: testsuite/asterisk/trunk r123 - in /asterisk/trunk/asttest: lua/ ...

SVN commits to the Digium repositories svn-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 svn-commits mailing list