diff options
Diffstat (limited to 'src/mod_configure.erl')
-rw-r--r-- | src/mod_configure.erl | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/mod_configure.erl b/src/mod_configure.erl new file mode 100644 index 000000000..b72f180b5 --- /dev/null +++ b/src/mod_configure.erl @@ -0,0 +1,207 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_configure.erl +%%% Author : Alexey Shchepin <alexey@sevcom.net> +%%% Purpose : +%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@sevcom.net> +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(mod_configure). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([start/0, + process_local_iq/3]). + +-include("ejabberd.hrl"). +-include("namespaces.hrl"). + + +start() -> + ejabberd_local:register_iq_handler(?NS_XDATA, + ?MODULE, process_local_iq). + + +process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> + case acl:match_rule(configure, From) of + deny -> + {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error", + [{"code", "405"}], + [{xmlcdata, "Not Allowed"}]}]}; + allow -> + Lang = xml:get_tag_attr_s("xml:lang", SubEl), + case Type of + set -> + case xml:get_tag_attr_s("type", SubEl) of + "cancel" -> + {iq, ID, result, XMLNS, + [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}; + "submit" -> + XData = jlib:parse_xdata_submit(SubEl), + case XData of + invalid -> + {iq, ID, error, XMLNS, + [SubEl, {xmlelement, "error", + [{"code", "400"}], + [{xmlcdata, "Bad Request"}]}]}; + _ -> + Node = + string:tokens( + xml:get_tag_attr_s("node", SubEl), + "/"), + case set_form(Node, Lang, XData) of + {result, Res} -> + {iq, ID, result, XMLNS, + [{xmlelement, "query", + [{"xmlns", XMLNS}], + Res + }]}; + {error, Code, Desc} -> + {iq, ID, error, XMLNS, + [SubEl, {xmlelement, "error", + [{"code", Code}], + [{xmlcdata, Desc}]}]} + end + end; + _ -> + {iq, ID, error, XMLNS, + [SubEl, {xmlelement, "error", + [{"code", "405"}], + [{xmlcdata, "Not Allowed"}]}]} + end; + get -> + Node = + string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), + case get_form(Node, Lang) of + {result, Res} -> + {iq, ID, result, XMLNS, + [{xmlelement, "query", [{"xmlns", XMLNS}], + Res + }]}; + {error, Code, Desc} -> + {iq, ID, error, XMLNS, + [SubEl, {xmlelement, "error", + [{"code", Code}], + [{xmlcdata, Desc}]}]} + end + end + end. + +-define(TLFIELD(Type, Label, Var), + {xmlelement, "field", [{"type", Type}, + {"label", translate:translate(Lang, Label)}, + {"var", Var}], []}). + +-define(TABLEFIELD(Table, Val), + {xmlelement, "field", [{"type", "list-single"}, + {"label", atom_to_list(Table)}, + {"var", atom_to_list(Table)}], + [{xmlelement, "value", [], [{xmlcdata, atom_to_list(Val)}]}, + {xmlelement, "option", [{"label", + translate:translate(Lang, "RAM copy")}], + [{xmlelement, "value", [], [{xmlcdata, "ram_copies"}]}]}, + {xmlelement, "option", [{"label", + translate:translate(Lang, + "RAM and disc copy")}], + [{xmlelement, "value", [], [{xmlcdata, "disc_copies"}]}]}, + {xmlelement, "option", [{"label", + translate:translate(Lang, "Disk copy")}], + [{xmlelement, "value", [], [{xmlcdata, "disc_only_copies"}]}]}, + {xmlelement, "option", [{"label", + translate:translate(Lang, "Remote copy")}], + [{xmlelement, "value", [], [{xmlcdata, "unknown"}]}]} + ]}). + + + +get_form(["running nodes", ENode, "DB"], Lang) -> + case search_running_node(ENode) of + false -> + {error, "404", "Not Found"}; + Node -> + case rpc:call(Node, mnesia, system_info, [tables]) of + {badrpc, Reason} -> + {error, "500", "Internal Server Error"}; + Tables -> + {result, [{xmlelement, "title", [], + [{xmlcdata, + translate:translate( + Lang, "DB Tables Configuration")}]}, + {xmlelement, "instructions", [], + [{xmlcdata, + translate:translate( + Lang, "Choose storage type of tables")}]} | + lists:map( + fun(Table) -> + case rpc:call(Node, + mnesia, + table_info, + [Table, storage_type]) of + {badrpc, _} -> + ?TABLEFIELD(Table, unknown); + Type -> + ?TABLEFIELD(Table, Type) + end + end, Tables) + ]} + end + end; + +get_form(_, Lang) -> + {error, "503", "Service Unavailable"}. + + + +set_form(["running nodes", ENode, "DB"], Lang, XData) -> + case search_running_node(ENode) of + false -> + {error, "404", "Not Found"}; + Node -> + lists:foreach( + fun({SVar, SVals}) -> + % We believe that this allowed only for good peoples + Table = list_to_atom(SVar), + Type = case SVals of + ["unknown"] -> unknown; + ["ram_copies"] -> ram_copies; + ["disc_copies"] -> disc_copies; + ["disc_only_copies"] -> disc_only_copies; + _ -> false + end, + if + Type == false -> + ok; + Type == unknown -> + mnesia:del_table_copy(Table, Node); + true -> + case mnesia:add_table_copy(Table, Node, Type) of + {aborted, _} -> + mnesia:change_table_copy_type( + Table, Node, Type); + _ -> + ok + end + end + end, XData), + {result, []} + end; + +set_form(_, Lang, XData) -> + {error, "503", "Service Unavailable"}. + + + +search_running_node(SNode) -> + search_running_node(SNode, mnesia:system_info(running_db_nodes)). + +search_running_node(_, []) -> + false; +search_running_node(SNode, [Node | Nodes]) -> + case atom_to_list(Node) of + SNode -> + Node; + _ -> + search_running_node(SNode, Nodes) + end. + + |