# # patch "ChangeLog" # from [b3653eee6d64b7ad553d0adf496bb1049be866bc] # to [f6196f883085475828333c6cb25d2291f528920e] # # patch "lua.cc" # from [75f11ea114ded43701adba2c0e768c2731797f37] # to [967b4c4db84bd37752ed438eb7b424a6fd9dccc6] # # patch "std_hooks.lua" # from [17a3c92c480f7062b106394109058ebf0ff9f081] # to [8f062ef9dfe49877d8399a7e5389fd9872f96505] # ======================================================================== --- ChangeLog b3653eee6d64b7ad553d0adf496bb1049be866bc +++ ChangeLog f6196f883085475828333c6cb25d2291f528920e @@ -1,3 +1,9 @@ +2005-11-08 Timothy Brownawell + + Make a basic_io parser available to Lua. + * lua.cc: new function, monotone_parse_basicio_for_lua + * std_hooks.lua: use it in get_netsync_read_permitted + 2005-11-05 Timothy Brownawell Make sure that all new revisions added to the db deltify as much as ======================================================================== --- lua.cc 75f11ea114ded43701adba2c0e768c2731797f37 +++ lua.cc 967b4c4db84bd37752ed438eb7b424a6fd9dccc6 @@ -36,6 +36,7 @@ #include "transforms.hh" #include "paths.hh" #include "globish.hh" +#include "basic_io.hh" // defined in {std,test}_hooks.lua, converted #include "test_hooks.h" @@ -678,6 +679,68 @@ lua_pushnil(L); return 1; } + + static int + monotone_parse_basicio_for_lua(lua_State *L) + { + vector > > res; + const char *str = lua_tostring(L, -1); + std::istringstream iss(str); + basic_io::input_source in(iss, "monotone_parse_basicio_for_lua"); + basic_io::tokenizer tok(in); + try + { + string got; + basic_io::token_type tt; + do + { + tt = tok.get_token(got); + switch (tt) + { + case basic_io::TOK_SYMBOL: + res.push_back(make_pair(got, vector())); + break; + case basic_io::TOK_STRING: + case basic_io::TOK_HEX: + E(!res.empty(), boost::format("bad input to parse_basicio")); + res.back().second.push_back(got); + break; + default: + break; + } + } + while (tt != basic_io::TOK_NONE); + } + catch (informative_failure & e) + {// there was a syntax error in our string + lua_pushnil(L); + return 0; + } + lua_newtable(L); + int n = 1; + for (vector > >::const_iterator i = res.begin(); + i != res.end(); ++i) + { + lua_pushnumber(L, n++); + lua_newtable(L); + lua_pushstring(L, "name"); + lua_pushstring(L, i->first.c_str()); + lua_settable(L, -3); + lua_pushstring(L, "values"); + lua_newtable(L); + int m = 1; + for (vector::const_iterator j = i->second.begin(); + j != i->second.end(); ++j) + { + lua_pushnumber(L, m++); + lua_pushstring(L, j->c_str()); + lua_settable(L, -3); + } + lua_settable(L, -3); + lua_settable(L, -3); + } + return 1; + } } @@ -709,6 +772,7 @@ lua_register(st, "includedir", monotone_includedir_for_lua); lua_register(st, "gettext", monotone_gettext_for_lua); lua_register(st, "get_confdir", monotone_get_confdir_for_lua); + lua_register(st, "parse_basicio", monotone_parse_basicio_for_lua); // add regex functions: lua_newtable(st); ======================================================================== --- std_hooks.lua 17a3c92c480f7062b106394109058ebf0ff9f081 +++ std_hooks.lua 8f062ef9dfe49877d8399a7e5389fd9872f96505 @@ -796,36 +796,43 @@ end end --- can't handle args with quotes in them, or lines with multiple args -function read_basicio_line(file) - local _, a, b - while _ == nil do - local line = file:read() - if line == nil then return nil end - _, _, a, b = string.find(line, "%s*([^%s]*)%s*\"([^\"]*)\"") - end - return a, b -end - function get_netsync_read_permitted(branch, ident) local permfile = io.open(get_confdir() .. "/read-permissions", "r") if (permfile == nil) then return false end + local dat = permfile:read("*a") + local res = parse_basicio(dat) + if res == nil then + io.stderr:write("file read-permissions cannot be parsed\n") + return false + end local matches = false local cont = false - while true do - local name, param = read_basicio_line(permfile) - if name == nil then return false end - if name == "pattern" then + for i, item in pairs(res) + do + -- legal names: pattern, allow, deny, continue + if item.name == "pattern" then if matches and not cont then return false end - matches = globish_match(param, branch) - end - if matches then - if name == "continue" then - if param ~= "false" then cont = true end + matches = false + for j, val in pairs(item.values) do + if globish_match(val, branch) then matches = true end end - if name == "allow" and param == "*" then return true end - if name == "allow" and globish_match(param, ident) then return true end - if name == "deny" and globish_match(param, ident) then return false end + elseif item.name == "allow" then if matches then + for j, val in pairs(item.values) do + if val == "*" then return true end + if globish_match(val, ident) then return true end + end + end elseif item.name == "deny" then if matches then + for j, val in pairs(item.values) do + if globish_match(val, ident) then return false end + end + end elseif item.name == "continue" then if matches then + cont = true + for j, val in pairs(item.values) do + if val == "false" or val == "no" then cont = false end + end + end elseif item.name ~= "comment" then + io.stderr:write("unknown symbol in read-permissions: " .. item.name .. "\n") + return false end end return false