# # # patch "app_state.cc" # from [74425b52934112d6f23c222e36516a69aee2bb29] # to [5e18d4feea619cb2d2febff6cc245d135c6e0044] # # patch "app_state.hh" # from [c417b99837f0a2de58f1e8f9b059ab3d25f611c1] # to [db7e9d57a02d3bcabf0754ff9cf8cadc12bd47d4] # # patch "cmd_automate.cc" # from [dda99f14f877d817666d59e6e8fde7791f275751] # to [8731028f23529afed6eb9af6ae41541a82fed393] # # patch "lua_hooks.cc" # from [33536067d47c7ff32a84f75600765aef0ccb6e7c] # to [103dbfc1a4c5873528b0d9eb6209154dc6d569e5] # ============================================================ --- app_state.cc 74425b52934112d6f23c222e36516a69aee2bb29 +++ app_state.cc 5e18d4feea619cb2d2febff6cc245d135c6e0044 @@ -33,6 +33,7 @@ app_state::app_state() : db(system_path()), keys(*this), work(db, lua), branch_is_sticky(false), + mtn_automate_allowed(false), project(*this) { db.set_app(this); ============================================================ --- app_state.hh c417b99837f0a2de58f1e8f9b059ab3d25f611c1 +++ app_state.hh db7e9d57a02d3bcabf0754ff9cf8cadc12bd47d4 @@ -55,6 +55,7 @@ public: bool found_workspace; bool branch_is_sticky; + bool mtn_automate_allowed; // These are used to cache signers/verifiers (if the hook allows). // They can't be function-static variables in key.cc, since they ============================================================ --- cmd_automate.cc dda99f14f877d817666d59e6e8fde7791f275751 +++ cmd_automate.cc 8731028f23529afed6eb9af6ae41541a82fed393 @@ -416,7 +416,13 @@ LUAEXT(mtn_automate, ) app_state* app_p = get_app_state(L); I(app_p != NULL); I(app_p->lua.check_lua_state(L)); + E(app_p->mtn_automate_allowed, + F("It is illegal to call the mtn_automate() lua extension,\n" + "unless from a command function defined by register_command().")); + // don't allow recursive calls + app_p->mtn_automate_allowed = false; + // automate_ostream os(output, app_p->opts.automate_stdio_size); std::stringstream & os = output; @@ -475,6 +481,9 @@ LUAEXT(mtn_automate, ) os.flush(); + // allow further calls + app_p->mtn_automate_allowed = true; + lua_pushstring(L, output.str().c_str()); // XXX: what needs to happen here for memory management? Should I copy this and let lua free it? return 1; } ============================================================ --- lua_hooks.cc 33536067d47c7ff32a84f75600765aef0ccb6e7c +++ lua_hooks.cc 103dbfc1a4c5873528b0d9eb6209154dc6d569e5 @@ -1000,8 +1000,12 @@ void commands::cmd_lua::exec(app_state & for (args_vector::const_iterator it = args.begin(); it != args.end(); it++) ll.push_str((*it)()); + app.mtn_automate_allowed = true; + ll.call(args.size(),0); + app.mtn_automate_allowed = false; + E(ll.ok(), F("Call to user command %s (lua command: %s) failed.") % primary_name() % f_name); }