aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/common_test/src/ct.erl21
-rwxr-xr-xlib/common_test/src/ct_config.erl579
-rwxr-xr-xlib/common_test/src/ct_config_plain.erl6
-rw-r--r--lib/common_test/src/ct_framework.erl10
-rw-r--r--lib/common_test/src/ct_run.erl2
-rw-r--r--lib/common_test/src/ct_snmp.erl12
-rw-r--r--lib/common_test/src/ct_util.erl534
7 files changed, 638 insertions, 526 deletions
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index 8ae041e5b4..3cc6154592 100644
--- a/lib/common_test/src/ct.erl
+++ b/lib/common_test/src/ct.erl
@@ -135,7 +135,8 @@ run(TestDirs) ->
%%% @spec run_test(Opts) -> Result
%%% Opts = [OptTuples]
%%% OptTuples = {config,CfgFiles} | {dir,TestDirs} | {suite,Suites} |
-%%% {testcase,Cases} | {group,Groups} | {spec,TestSpecs} |
+%%% {userconfig, Callback, CfgFiles} |
+%%% {testcase,Cases} | {group,Groups} | {spec,TestSpecs} |
%%% {allow_user_terms,Bool} | {logdir,LogDir} |
%%% {silent_connections,Conns} | {cover,CoverSpecFile} |
%%% {step,StepOpts} | {event_handler,EventHandlers} | {include,InclDirs} |
@@ -269,7 +270,7 @@ stop_interactive() ->
%%% @see get_config/2
%%% @see get_config/3
require(Required) ->
- ct_util:require(Required).
+ ct_config:require(Required).
%%%-----------------------------------------------------------------
%%% @spec require(Name,Required) -> ok | {error,Reason}
@@ -304,19 +305,19 @@ require(Required) ->
%%% @see get_config/2
%%% @see get_config/3
require(Name,Required) ->
- ct_util:require(Name,Required).
+ ct_config:require(Name,Required).
%%%-----------------------------------------------------------------
%%% @spec get_config(Required) -> Value
%%% @equiv get_config(Required,undefined,[])
get_config(Required) ->
- ct_util:get_config(Required,undefined,[]).
+ ct_config:get_config(Required,undefined,[]).
%%%-----------------------------------------------------------------
%%% @spec get_config(Required,Default) -> Value
%%% @equiv get_config(Required,Default,[])
get_config(Required,Default) ->
- ct_util:get_config(Required,Default,[]).
+ ct_config:get_config(Required,Default,[]).
%%%-----------------------------------------------------------------
%%% @spec get_config(Required,Default,Opts) -> ValueOrElement
@@ -375,7 +376,7 @@ get_config(Required,Default) ->
%%% @see require/1
%%% @see require/2
get_config(Required,Default,Opts) ->
- ct_util:get_config(Required,Default,Opts).
+ ct_config:get_config(Required,Default,Opts).
%%%-----------------------------------------------------------------
%%% @spec log(Format) -> ok
@@ -734,7 +735,7 @@ abort_current_testcase(Reason) ->
%%% <p>See the <code>crypto</code> application for details on DES3
%%% encryption/decryption.</p>
encrypt_config_file(SrcFileName, EncryptFileName) ->
- ct_util:encrypt_config_file(SrcFileName, EncryptFileName).
+ ct_config:encrypt_config_file(SrcFileName, EncryptFileName).
%%%-----------------------------------------------------------------
%%% @spec encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) ->
@@ -754,7 +755,7 @@ encrypt_config_file(SrcFileName, EncryptFileName) ->
%%% <p>See the <code>crypto</code> application for details on DES3
%%% encryption/decryption.</p>
encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) ->
- ct_util:encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile).
+ ct_config:encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile).
%%%-----------------------------------------------------------------
%%% @spec decrypt_config_file(EncryptFileName, TargetFileName) ->
@@ -770,7 +771,7 @@ encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) ->
%%% <code>.ct_config.crypt</code> in the current directory, or the
%%% home directory of the user (it is searched for in that order).</p>
decrypt_config_file(EncryptFileName, TargetFileName) ->
- ct_util:decrypt_config_file(EncryptFileName, TargetFileName).
+ ct_config:decrypt_config_file(EncryptFileName, TargetFileName).
%%%-----------------------------------------------------------------
%%% @spec decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) ->
@@ -785,5 +786,5 @@ decrypt_config_file(EncryptFileName, TargetFileName) ->
%%% file contents is saved in the target file. The key must have the
%%% the same value as that used for encryption.</p>
decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) ->
- ct_util:decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile).
+ ct_config:decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile).
diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl
index f344813128..9a1f23201f 100755
--- a/lib/common_test/src/ct_config.erl
+++ b/lib/common_test/src/ct_config.erl
@@ -24,16 +24,169 @@
%%----------------------------------------------------------------------
-module(ct_config).
+% start of the config server
+-export([start/0, start/1, start/2, stop/0]).
+
+% manipulating with config files
-export([read_config_files/1,
- set_config/1, set_config/2, set_config/3,
- delete_config/1,
get_config_file_list/1]).
--include("ct_event.hrl").
+% require
+-export([require/1, require/2]).
+
+% get config data
+-export([get_config/1, get_config/2, get_config/3,
+ get_all_config/0]).
+
+% set config data
+-export([set_config/1, set_config/2, set_config/3,
+ set_default_config/2, set_default_config/3]).
+
+% delete config data
+-export([delete_config/1, delete_default_config/1]).
+
+% update and reload config
+-export([%reload_config/1,
+ update_config/2]).
+
+% ?
+-export([release_allocated/0]).
+
+-export([encrypt_config_file/2, encrypt_config_file/3,
+ decrypt_config_file/2, decrypt_config_file/3,
+ get_crypt_key_from_file/0, get_crypt_key_from_file/1]).
+
+% references
+-export([get_ref_from_name/1, get_name_from_ref/1, get_key_from_name/1]).
+
-include("ct_util.hrl").
+-include("ct_event.hrl").
+
+-define(cryptfile, ".ct_config.crypt").
+% TODO: add handler field here
-record(ct_conf,{key,value,ref,name='_UNDEF',default=false}).
-%% default = {true,suite} | {true,testcase} | false
+
+%%%-----------------------------------------------------------------
+%%% @spec start(Mode) -> Pid | exit(Error)
+%%% Mode = normal | interactive
+%%% Pid = pid()
+%%%
+%%% @doc Start start the ct_config_server process
+%%% (tool-internal use only).
+%%%
+%%% <p>This function is called from ct_run.erl. It starts and initiates
+%%% the <code>ct_config_server</code></p>
+%%%
+%%% <p>Returns the process identity of the
+%%% <code>ct_config_server</code>.</p>
+%%%
+%%% @see ct
+start() ->
+ start(normal,".").
+
+start(LogDir) when is_list(LogDir) ->
+ start(normal,LogDir);
+start(Mode) ->
+ start(Mode,".").
+
+start(Mode,LogDir) ->
+ case whereis(ct_config_server) of
+ undefined ->
+ Me = self(),
+ Pid = spawn_link(fun() -> do_start(Me) end),
+ receive
+ {Pid,started} -> Pid;
+ {Pid,Error} -> exit(Error)
+ end;
+ Pid ->
+ case ct_util:get_mode() of
+ interactive when Mode==interactive ->
+ Pid;
+ interactive ->
+ {error,interactive_mode};
+ _OtherMode ->
+ Pid
+ end
+ end.
+
+do_start(Parent) ->
+ process_flag(trap_exit,true),
+ register(ct_config_server,self()),
+ ct_util:create_table(?attr_table,bag,#ct_conf.key),
+ {ok,StartDir} = file:get_cwd(),
+ Opts = case ct_util:read_opts() of
+ {ok,Opts1} ->
+ Opts1;
+ Error ->
+ Parent ! {self(),Error},
+ exit(Error)
+ end,
+ case read_config_files(Opts) of
+ ok ->
+ Parent ! {self(),started},
+ loop(StartDir);
+ ReadError ->
+ Parent ! {self(),ReadError},
+ exit(ReadError)
+ end.
+
+%%%-----------------------------------------------------------------
+%%% @spec stop() -> ok
+%%%
+%%% @doc Stop the ct_config_server and close all existing connections
+%%% (tool-internal use only).
+%%%
+%%% @see ct
+stop() ->
+ case whereis(ct_config_server) of
+ undefined -> ok;
+ _ -> call({stop})
+ end.
+
+call(Msg) ->
+ MRef = erlang:monitor(process, whereis(ct_config_server)),
+ Ref = make_ref(),
+ ct_config_server ! {Msg,{self(),Ref}},
+ receive
+ {Ref, Result} ->
+ erlang:demonitor(MRef),
+ Result;
+ {'DOWN',MRef,process,_,Reason} ->
+ {error,{ct_util_server_down,Reason}}
+ end.
+
+return({To,Ref},Result) ->
+ To ! {Ref, Result}.
+
+
+loop(StartDir) ->
+ receive
+ {{require,Name,Tag,SubTags},From} ->
+ Result = do_require(Name,Tag,SubTags),
+ return(From,Result),
+ loop(StartDir);
+ {{set_default_config,{Config,Scope}},From} ->
+ ct_config:set_config(Config,{true,Scope}),
+ return(From,ok),
+ loop(StartDir);
+ {{set_default_config,{Name,Config,Scope}},From} ->
+ ct_config:set_config(Name,Config,{true,Scope}),
+ return(From,ok),
+ loop(StartDir);
+ {{delete_default_config,Scope},From} ->
+ ct_config:delete_config({true,Scope}),
+ return(From,ok),
+ loop(StartDir);
+ {{update_config,{Name,NewConfig}},From} ->
+ update_conf(Name,NewConfig),
+ return(From,ok),
+ loop(StartDir);
+ {{stop},From} ->
+ ets:delete(?attr_table),
+ file:set_cwd(StartDir),
+ return(From,ok)
+ end.
read_config_files(Opts) ->
AddCallback = fun(CallBack, Files)->
@@ -74,6 +227,180 @@ set_config(Name,Config,Default) ->
name=Name,default=Default}) ||
{Key,Val} <- Config].
+get_config(KeyOrName,Default,Opts) when is_atom(KeyOrName) ->
+ case lookup_config(KeyOrName) of
+ [] ->
+ Default;
+ [{_Ref,Val}|_] = Vals ->
+ case {lists:member(all,Opts),lists:member(element,Opts)} of
+ {true,true} ->
+ [{KeyOrName,V} || {_R,V} <- lists:sort(Vals)];
+ {true,false} ->
+ [V || {_R,V} <- lists:sort(Vals)];
+ {false,true} ->
+ {KeyOrName,Val};
+ {false,false} ->
+ Val
+ end
+ end;
+
+get_config({KeyOrName,SubKey},Default,Opts) ->
+ case lookup_config(KeyOrName) of
+ [] ->
+ Default;
+ Vals ->
+ Vals1 = case [Val || {_Ref,Val} <- lists:sort(Vals)] of
+ Result=[L|_] when is_list(L) ->
+ case L of
+ [{_,_}|_] ->
+ Result;
+ _ ->
+ []
+ end;
+ _ ->
+ []
+ end,
+ case get_subconfig([SubKey],Vals1,[],Opts) of
+ {ok,[{_,SubVal}|_]=SubVals} ->
+ case {lists:member(all,Opts),lists:member(element,Opts)} of
+ {true,true} ->
+ [{{KeyOrName,SubKey},Val} || {_,Val} <- SubVals];
+ {true,false} ->
+ [Val || {_SubKey,Val} <- SubVals];
+ {false,true} ->
+ {{KeyOrName,SubKey},SubVal};
+ {false,false} ->
+ SubVal
+ end;
+ _ ->
+ Default
+ end
+ end.
+
+
+%%%-----------------------------------------------------------------
+%%% @spec
+%%%
+%%% @doc
+update_conf(Name, NewConfig) ->
+ Old = ets:select(?attr_table,[{#ct_conf{name=Name,_='_'},[],['$_']}]),
+ lists:foreach(fun(OldElem) ->
+ NewElem = OldElem#ct_conf{value=NewConfig},
+ ets:delete_object(?attr_table, OldElem),
+ ets:insert(?attr_table, NewElem)
+ end, Old),
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% @spec release_allocated() -> ok
+%%%
+%%% @doc Release all allocated resources, but don't take down any
+%%% connections.
+release_allocated() ->
+ Allocated = ets:select(?attr_table,[{#ct_conf{name='$1',_='_'},
+ [{'=/=','$1','_UNDEF'}],
+ ['$_']}]),
+ release_allocated(Allocated).
+release_allocated([H|T]) ->
+ ets:delete_object(?attr_table,H),
+ ets:insert(?attr_table,H#ct_conf{name='_UNDEF'}),
+ release_allocated(T);
+release_allocated([]) ->
+ ok.
+
+allocate(Name,Key,SubKeys) ->
+ case ets:match_object(?attr_table,#ct_conf{key=Key,name='_UNDEF',_='_'}) of
+ [] ->
+ {error,{not_available,Key}};
+ Available ->
+ case allocate_subconfig(Name,SubKeys,Available,false) of
+ ok ->
+ ok;
+ Error ->
+ Error
+ end
+ end.
+
+allocate_subconfig(Name,SubKeys,[C=#ct_conf{value=Value}|Rest],Found) ->
+ case do_get_config(SubKeys,Value,[]) of
+ {ok,_SubMapped} ->
+ ets:insert(?attr_table,C#ct_conf{name=Name}),
+ allocate_subconfig(Name,SubKeys,Rest,true);
+ _Error ->
+ allocate_subconfig(Name,SubKeys,Rest,Found)
+ end;
+allocate_subconfig(_Name,_SubKeys,[],true) ->
+ ok;
+allocate_subconfig(_Name,SubKeys,[],false) ->
+ {error,{not_available,SubKeys}}.
+
+%%%-----------------------------------------------------------------
+%%% @hidden
+%%% @equiv ct:get_config/1
+get_config(KeyOrName) ->
+ ct_config:get_config(KeyOrName,undefined,[]).
+
+%%%-----------------------------------------------------------------
+%%% @hidden
+%%% @equiv ct:get_config/2
+get_config(KeyOrName,Default) ->
+ ct_config:get_config(KeyOrName,Default,[]).
+
+get_subconfig(SubKeys,Values) ->
+ get_subconfig(SubKeys,Values,[],[]).
+
+get_subconfig(SubKeys,[Value|Rest],Mapped,Opts) ->
+ case do_get_config(SubKeys,Value,[]) of
+ {ok,SubMapped} ->
+ case lists:member(all,Opts) of
+ true ->
+ get_subconfig(SubKeys,Rest,Mapped++SubMapped,Opts);
+ false ->
+ {ok,SubMapped}
+ end;
+ _Error ->
+ get_subconfig(SubKeys,Rest,Mapped,Opts)
+ end;
+get_subconfig(SubKeys,[],[],_) ->
+ {error,{not_available,SubKeys}};
+get_subconfig(_SubKeys,[],Mapped,_) ->
+ {ok,Mapped}.
+
+do_get_config([Key|Required],Available,Mapped) ->
+ case lists:keysearch(Key,1,Available) of
+ {value,{Key,Value}} ->
+ NewAvailable = lists:keydelete(Key,1,Available),
+ NewMapped = [{Key,Value}|Mapped],
+ do_get_config(Required,NewAvailable,NewMapped);
+ false ->
+ {error,{not_available,Key}}
+ end;
+do_get_config([],_Available,Mapped) ->
+ {ok,lists:reverse(Mapped)}.
+
+get_all_config() ->
+ ets:select(?attr_table,[{#ct_conf{name='$1',key='$2',value='$3',
+ default='$4',_='_'},
+ [],
+ [{{'$1','$2','$3','$4'}}]}]).
+
+lookup_config(KeyOrName) ->
+ case lookup_name(KeyOrName) of
+ [] ->
+ lookup_key(KeyOrName);
+ Values ->
+ Values
+ end.
+
+lookup_name(Name) ->
+ ets:select(?attr_table,[{#ct_conf{ref='$1',value='$2',name=Name,_='_'},
+ [],
+ [{{'$1','$2'}}]}]).
+lookup_key(Key) ->
+ ets:select(?attr_table,[{#ct_conf{key=Key,ref='$1',value='$2',name='_UNDEF',_='_'},
+ [],
+ [{{'$1','$2'}}]}]).
+
delete_config(Default) ->
ets:match_delete(?attr_table,#ct_conf{default=Default,_='_'}),
ok.
@@ -115,3 +442,247 @@ get_config_file_list(Opts)->
end ++
process_user_configs(Opts, []),
CfgFiles.
+
+%%%-----------------------------------------------------------------
+%%% @hidden
+%%% @equiv ct:require/1
+require(Key) when is_atom(Key) ->
+ require({Key,[]});
+require({Key,SubKeys}) when is_atom(Key) ->
+ allocate('_UNDEF',Key,to_list(SubKeys));
+require(Key) ->
+ {error,{invalid,Key}}.
+
+
+%%%-----------------------------------------------------------------
+%%% @hidden
+%%% @equiv ct:require/2
+require(Name,Key) when is_atom(Key) ->
+ require(Name,{Key,[]});
+require(Name,{Key,SubKeys}) when is_atom(Name), is_atom(Key) ->
+ call({require,Name,Key,to_list(SubKeys)});
+require(Name,Keys) ->
+ {error,{invalid,{Name,Keys}}}.
+
+to_list(X) when is_list(X) -> X;
+to_list(X) -> [X].
+
+do_require(Name,Key,SubKeys) when is_list(SubKeys) ->
+ case get_key_from_name(Name) of
+ {error,_} ->
+ allocate(Name,Key,SubKeys);
+ {ok,Key} ->
+ %% already allocated - check that it has all required subkeys
+ Vals = [Val || {_Ref,Val} <- lookup_name(Name)],
+ case get_subconfig(SubKeys,Vals) of
+ {ok,_SubMapped} ->
+ ok;
+ Error ->
+ Error
+ end;
+ {ok,OtherKey} ->
+ {error,{name_in_use,Name,OtherKey}}
+ end.
+
+%%%-----------------------------------------------------------------
+%%% @spec
+%%%
+%%% @doc
+encrypt_config_file(SrcFileName, EncryptFileName) ->
+ case get_crypt_key_from_file() of
+ {error,_} = E ->
+ E;
+ Key ->
+ encrypt_config_file(SrcFileName, EncryptFileName, {key,Key})
+ end.
+
+
+get_ref_from_name(Name) ->
+ case ets:select(?attr_table,[{#ct_conf{name=Name,ref='$1',_='_'},
+ [],
+ ['$1']}]) of
+ [Ref] ->
+ {ok,Ref};
+ _ ->
+ {error,{no_such_name,Name}}
+ end.
+
+get_name_from_ref(Ref) ->
+ case ets:select(?attr_table,[{#ct_conf{name='$1',ref=Ref,_='_'},
+ [],
+ ['$1']}]) of
+ [Name] ->
+ {ok,Name};
+ _ ->
+ {error,{no_such_ref,Ref}}
+ end.
+
+get_key_from_name(Name) ->
+ case ets:select(?attr_table,[{#ct_conf{name=Name,key='$1',_='_'},
+ [],
+ ['$1']}]) of
+ [Key|_] ->
+ {ok,Key};
+ _ ->
+ {error,{no_such_name,Name}}
+ end.
+
+%%%-----------------------------------------------------------------
+%%% @spec
+%%%
+%%% @doc
+encrypt_config_file(SrcFileName, EncryptFileName, {file,KeyFile}) ->
+ case get_crypt_key_from_file(KeyFile) of
+ {error,_} = E ->
+ E;
+ Key ->
+ encrypt_config_file(SrcFileName, EncryptFileName, {key,Key})
+ end;
+
+encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) ->
+ crypto:start(),
+ {K1,K2,K3,IVec} = make_crypto_key(Key),
+ case file:read_file(SrcFileName) of
+ {ok,Bin0} ->
+ Bin1 = term_to_binary({SrcFileName,Bin0}),
+ Bin2 = case byte_size(Bin1) rem 8 of
+ 0 -> Bin1;
+ N -> list_to_binary([Bin1,random_bytes(8-N)])
+ end,
+ EncBin = crypto:des3_cbc_encrypt(K1, K2, K3, IVec, Bin2),
+ case file:write_file(EncryptFileName, EncBin) of
+ ok ->
+ io:format("~s --(encrypt)--> ~s~n",
+ [SrcFileName,EncryptFileName]),
+ ok;
+ {error,Reason} ->
+ {error,{Reason,EncryptFileName}}
+ end;
+ {error,Reason} ->
+ {error,{Reason,SrcFileName}}
+ end.
+
+%%%-----------------------------------------------------------------
+%%% @spec
+%%%
+%%% @doc
+decrypt_config_file(EncryptFileName, TargetFileName) ->
+ case get_crypt_key_from_file() of
+ {error,_} = E ->
+ E;
+ Key ->
+ decrypt_config_file(EncryptFileName, TargetFileName, {key,Key})
+ end.
+
+
+set_default_config(NewConfig, Scope) ->
+ call({set_default_config, {NewConfig, Scope}}).
+
+set_default_config(Name, NewConfig, Scope) ->
+ call({set_default_config, {Name, NewConfig, Scope}}).
+
+delete_default_config(Scope) ->
+ call({delete_default_config, Scope}).
+
+update_config(Name, Config) ->
+ call({update_config, {Name, Config}}).
+
+%%%-----------------------------------------------------------------
+%%% @spec
+%%%
+%%% @doc
+decrypt_config_file(EncryptFileName, TargetFileName, {file,KeyFile}) ->
+ case get_crypt_key_from_file(KeyFile) of
+ {error,_} = E ->
+ E;
+ Key ->
+ decrypt_config_file(EncryptFileName, TargetFileName, {key,Key})
+ end;
+
+decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) ->
+ crypto:start(),
+ {K1,K2,K3,IVec} = make_crypto_key(Key),
+ case file:read_file(EncryptFileName) of
+ {ok,Bin} ->
+ DecBin = crypto:des3_cbc_decrypt(K1, K2, K3, IVec, Bin),
+ case catch binary_to_term(DecBin) of
+ {'EXIT',_} ->
+ {error,bad_file};
+ {_SrcFile,SrcBin} ->
+ case TargetFileName of
+ undefined ->
+ {ok,SrcBin};
+ _ ->
+ case file:write_file(TargetFileName, SrcBin) of
+ ok ->
+ io:format("~s --(decrypt)--> ~s~n",
+ [EncryptFileName,TargetFileName]),
+ ok;
+ {error,Reason} ->
+ {error,{Reason,TargetFileName}}
+ end
+ end
+ end;
+ {error,Reason} ->
+ {error,{Reason,EncryptFileName}}
+ end.
+
+
+get_crypt_key_from_file(File) ->
+ case file:read_file(File) of
+ {ok,Bin} ->
+ case catch string:tokens(binary_to_list(Bin), [$\n,$\r]) of
+ [Key] ->
+ Key;
+ _ ->
+ {error,{bad_crypt_file,File}}
+ end;
+ {error,Reason} ->
+ {error,{Reason,File}}
+ end.
+
+get_crypt_key_from_file() ->
+ CwdFile = filename:join(".",?cryptfile),
+ {Result,FullName} =
+ case file:read_file(CwdFile) of
+ {ok,Bin} ->
+ {Bin,CwdFile};
+ _ ->
+ case init:get_argument(home) of
+ {ok,[[Home]]} ->
+ HomeFile = filename:join(Home,?cryptfile),
+ case file:read_file(HomeFile) of
+ {ok,Bin} ->
+ {Bin,HomeFile};
+ _ ->
+ {{error,no_crypt_file},noent}
+ end;
+ _ ->
+ {{error,no_crypt_file},noent}
+ end
+ end,
+ case FullName of
+ noent ->
+ Result;
+ _ ->
+ case catch string:tokens(binary_to_list(Result), [$\n,$\r]) of
+ [Key] ->
+ io:format("~nCrypt key file: ~s~n", [FullName]),
+ Key;
+ _ ->
+ {error,{bad_crypt_file,FullName}}
+ end
+ end.
+
+make_crypto_key(String) ->
+ <<K1:8/binary,K2:8/binary>> = First = erlang:md5(String),
+ <<K3:8/binary,IVec:8/binary>> = erlang:md5([First|lists:reverse(String)]),
+ {K1,K2,K3,IVec}.
+
+random_bytes(N) ->
+ {A,B,C} = now(),
+ random:seed(A, B, C),
+ random_bytes_1(N, []).
+
+random_bytes_1(0, Acc) -> Acc;
+random_bytes_1(N, Acc) -> random_bytes_1(N-1, [random:uniform(255)|Acc]).
diff --git a/lib/common_test/src/ct_config_plain.erl b/lib/common_test/src/ct_config_plain.erl
index a5947cafef..be0433aa9f 100755
--- a/lib/common_test/src/ct_config_plain.erl
+++ b/lib/common_test/src/ct_config_plain.erl
@@ -38,10 +38,10 @@ read_config_file(ConfigFile) ->
{key,K} ->
K;
{file,F} ->
- ct_util:get_crypt_key_from_file(F)
+ ct_config:get_crypt_key_from_file(F)
end;
_ ->
- ct_util:get_crypt_key_from_file()
+ ct_config:get_crypt_key_from_file()
end,
case Key of
{error,no_crypt_file} ->
@@ -49,7 +49,7 @@ read_config_file(ConfigFile) ->
{error,CryptError} ->
{error, decrypt_file_error, CryptError};
_ when is_list(Key) ->
- case ct_util:decrypt_config_file(ConfigFile, undefined, {key,Key}) of
+ case ct_config:decrypt_config_file(ConfigFile, undefined, {key,Key}) of
{ok,CfgBin} ->
case read_config_terms(CfgBin) of
{error,ReadFail} ->
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index ed8b564921..89bbc2448f 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -113,9 +113,9 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) ->
ok;
true ->
%% delete all default values used in previous suite
- ct_util:delete_default_config(suite),
+ ct_config:delete_default_config(suite),
%% release all name -> key bindings (once per suite)
- ct_util:release_allocated()
+ ct_config:release_allocated()
end,
TestCaseInfo =
case catch apply(Mod,Func,[]) of
@@ -125,7 +125,7 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) ->
%% clear all config data default values set by previous
%% testcase info function (these should only survive the
%% testcase, not the whole suite)
- ct_util:delete_default_config(testcase),
+ ct_config:delete_default_config(testcase),
case add_defaults(Mod,Func,TestCaseInfo,DoInit) of
Error = {suite0_failed,_} ->
ct_logs:init_tc(),
@@ -381,10 +381,10 @@ try_set_default(Name,Key,Info,Where) ->
{_,[]} ->
no_default;
{'_UNDEF',_} ->
- [ct_util:set_default_config([CfgVal],Where) || CfgVal <- CfgElems],
+ [ct_config:set_default_config([CfgVal],Where) || CfgVal <- CfgElems],
ok;
_ ->
- [ct_util:set_default_config(Name,[CfgVal],Where) || CfgVal <- CfgElems],
+ [ct_config:set_default_config(Name,[CfgVal],Where) || CfgVal <- CfgElems],
ok
end.
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index b86dd8fe2f..04bc047f43 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -222,7 +222,7 @@ script_start1(Parent, Args) ->
end,
Config = ConfigFiles ++ UserConfigs,
case Config of
- false ->
+ [] ->
case install([{config,[]},
{event_handler,EvHandlers}],
LogDir) of
diff --git a/lib/common_test/src/ct_snmp.erl b/lib/common_test/src/ct_snmp.erl
index 7ff88ad7d3..b515c578c7 100644
--- a/lib/common_test/src/ct_snmp.erl
+++ b/lib/common_test/src/ct_snmp.erl
@@ -332,7 +332,7 @@ set_info(Config) ->
register_users(MgrAgentConfName, Users) ->
{snmp, SnmpVals} = ct:get_config(MgrAgentConfName),
NewSnmpVals = lists:keyreplace(users, 1, SnmpVals, {users, Users}),
- ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
+ ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
setup_users(Users).
%%% @spec register_agents(MgrAgentConfName, ManagedAgents) -> ok | {error, Reason}
@@ -347,7 +347,7 @@ register_agents(MgrAgentConfName, ManagedAgents) ->
{snmp, SnmpVals} = ct:get_config(MgrAgentConfName),
NewSnmpVals = lists:keyreplace(managed_agents, 1, SnmpVals,
{managed_agents, ManagedAgents}),
- ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
+ ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
setup_managed_agents(ManagedAgents).
%%% @spec register_usm_users(MgrAgentConfName, UsmUsers) -> ok | {error, Reason}
@@ -361,7 +361,7 @@ register_agents(MgrAgentConfName, ManagedAgents) ->
register_usm_users(MgrAgentConfName, UsmUsers) ->
{snmp, SnmpVals} = ct:get_config(MgrAgentConfName),
NewSnmpVals = lists:keyreplace(users, 1, SnmpVals, {usm_users, UsmUsers}),
- ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
+ ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID),
setup_usm_users(UsmUsers, EngineID).
@@ -376,7 +376,7 @@ unregister_users(MgrAgentConfName) ->
ct:get_config({MgrAgentConfName, users})),
{snmp, SnmpVals} = ct:get_config(MgrAgentConfName),
NewSnmpVals = lists:keyreplace(users, 1, SnmpVals, {users, []}),
- ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
+ ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
takedown_users(Users).
%%% @spec unregister_agents(MgrAgentConfName) -> ok | {error, Reason}
@@ -393,7 +393,7 @@ unregister_agents(MgrAgentConfName) ->
{snmp, SnmpVals} = ct:get_config(MgrAgentConfName),
NewSnmpVals = lists:keyreplace(managed_agents, 1, SnmpVals,
{managed_agents, []}),
- ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
+ ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
takedown_managed_agents(ManagedAgents).
@@ -409,7 +409,7 @@ update_usm_users(MgrAgentConfName, UsmUsers) ->
{snmp, SnmpVals} = ct:get_config(MgrAgentConfName),
NewSnmpVals = lists:keyreplace(usm_users, 1, SnmpVals,
{usm_users, UsmUsers}),
- ct_util:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
+ ct_config:update_config(MgrAgentConfName, {snmp, NewSnmpVals}),
EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID),
do_update_usm_users(UsmUsers, EngineID).
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 814bd97840..df124e1ca8 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -30,10 +30,7 @@
-export([register_connection/4,unregister_connection/1,
does_connection_exist/3,get_key_from_name/1]).
--export([require/1, require/2, get_config/1, get_config/2, get_config/3,
- set_default_config/2, set_default_config/3, delete_default_config/1,
- get_all_config/0, update_config/2,
- release_allocated/0, close_connections/0]).
+-export([close_connections/0]).
-export([save_suite_data/3, save_suite_data/2, read_suite_data/1,
delete_suite_data/0, delete_suite_data/1, match_delete_suite_data/1,
@@ -46,6 +43,8 @@
silence_all_connections/0, silence_connections/1, is_silenced/1,
reset_silent_connections/0]).
+-export([get_mode/0, create_table/3, read_opts/0]).
+
-export([set_cwd/1, reset_cwd/0]).
-export([parse_table/1]).
@@ -56,9 +55,6 @@
-export([is_test_dir/1, get_testdir/2]).
--export([encrypt_config_file/2, encrypt_config_file/3,
- decrypt_config_file/2, decrypt_config_file/3]).
-
-export([kill_attached/2, get_attached/1, ct_make_ref/0]).
-export([warn_duplicates/1]).
@@ -66,13 +62,8 @@
-include("ct_event.hrl").
-include("ct_util.hrl").
--record(ct_conf,{key,value,ref,name='_UNDEF',default=false}).
-%% default = {true,suite} | {true,testcase} | false
-
-record(suite_data, {key,name,value}).
--define(cryptfile, ".ct_config.crypt").
-
%%%-----------------------------------------------------------------
%%% @spec start(Mode) -> Pid | exit(Error)
%%% Mode = normal | interactive
@@ -119,7 +110,6 @@ start(Mode,LogDir) ->
do_start(Parent,Mode,LogDir) ->
process_flag(trap_exit,true),
register(ct_util_server,self()),
- create_table(?attr_table,bag,#ct_conf.key),
create_table(?conn_table,#conn.handle),
create_table(?board_table,2),
create_table(?suite_table,#suite_data.key),
@@ -148,38 +138,34 @@ do_start(Parent,Mode,LogDir) ->
ct_event:add_handler([{vts,VtsPid}])
end
end,
- case ct_config:read_config_files(Opts) of
- ok ->
- %% add user handlers
- case lists:keysearch(event_handler,1,Opts) of
- {value,{_,Handlers}} ->
- Add = fun({H,Args}) ->
- case catch gen_event:add_handler(?CT_EVMGR_REF,H,Args) of
- ok -> ok;
- {'EXIT',Why} -> exit(Why);
- Other -> exit({event_handler,Other})
- end
- end,
- case catch lists:foreach(Add,Handlers) of
- {'EXIT',Reason} ->
- Parent ! {self(),Reason};
- _ ->
- ok
- end;
- false ->
+ %% start ct_config server
+ CTCSResult = ct_config:start(Mode, LogDir),
+ %% add user event handlers
+ case lists:keysearch(event_handler,1,Opts) of
+ {value,{_,Handlers}} ->
+ Add = fun({H,Args}) ->
+ case catch gen_event:add_handler(?CT_EVMGR_REF,H,Args) of
+ ok -> ok;
+ {'EXIT',Why} -> exit(Why);
+ Other -> exit({event_handler,Other})
+ end
+ end,
+ case catch lists:foreach(Add,Handlers) of
+ {'EXIT',Reason} ->
+ Parent ! {self(),Reason};
+ _ ->
ok
- end,
- {StartTime,TestLogDir} = ct_logs:init(Mode),
- ct_event:notify(#event{name=test_start,
- node=node(),
- data={StartTime,
- lists:flatten(TestLogDir)}}),
- Parent ! {self(),started},
- loop(Mode,[],StartDir);
- ReadError ->
- Parent ! {self(),ReadError},
- exit(ReadError)
- end.
+ end;
+ false ->
+ ok
+ end,
+ {StartTime,TestLogDir} = ct_logs:init(Mode),
+ ct_event:notify(#event{name=test_start,
+ node=node(),
+ data={StartTime,
+ lists:flatten(TestLogDir)}}),
+ Parent ! {self(),started},
+ loop(Mode,[],StartDir).
create_table(TableName,KeyPos) ->
create_table(TableName,set,KeyPos).
@@ -197,18 +183,6 @@ read_opts() ->
{error,{bad_installation,Error}}
end.
-set_default_config(NewConfig, Scope) ->
- call({set_default_config, {NewConfig, Scope}}).
-
-set_default_config(Name, NewConfig, Scope) ->
- call({set_default_config, {Name, NewConfig, Scope}}).
-
-delete_default_config(Scope) ->
- call({delete_default_config, Scope}).
-
-update_config(Name, Config) ->
- call({update_config, {Name, Config}}).
-
save_suite_data(Key, Value) ->
call({save_suite_data, {Key, undefined, Value}}).
@@ -254,26 +228,6 @@ loop(Mode,TestData,StartDir) ->
ct_logs:make_last_run_index(),
return(From,ok),
loop(Mode,TestData,StartDir);
- {{require,Name,Tag,SubTags},From} ->
- Result = do_require(Name,Tag,SubTags),
- return(From,Result),
- loop(Mode,TestData,StartDir);
- {{set_default_config,{Config,Scope}},From} ->
- ct_config:set_config(Config,{true,Scope}),
- return(From,ok),
- loop(Mode,TestData,StartDir);
- {{set_default_config,{Name,Config,Scope}},From} ->
- ct_config:set_config(Name,Config,{true,Scope}),
- return(From,ok),
- loop(Mode,TestData,StartDir);
- {{delete_default_config,Scope},From} ->
- ct_config:delete_config({true,Scope}),
- return(From,ok),
- loop(Mode,TestData,StartDir);
- {{update_config,{Name,NewConfig}},From} ->
- update_conf(Name,NewConfig),
- return(From,ok),
- loop(Mode,TestData,StartDir);
{{save_suite_data,{Key,Name,Value}},From} ->
ets:insert(?suite_table, #suite_data{key=Key,
name=Name,
@@ -346,7 +300,6 @@ loop(Mode,TestData,StartDir) ->
ct_event:sync_notify(#event{name=test_done,
node=node(),
data=Time}),
- ets:delete(?attr_table),
close_connections(ets:tab2list(?conn_table)),
ets:delete(?conn_table),
ets:delete(?board_table),
@@ -354,6 +307,7 @@ loop(Mode,TestData,StartDir) ->
ct_logs:close(How),
file:set_cwd(StartDir),
ct_event:stop(),
+ ct_config:stop(),
return(From,ok);
{get_mode,From} ->
return(From,Mode),
@@ -375,6 +329,8 @@ close_connections([#conn{handle=Handle,callback=CB}|Conns]) ->
close_connections([]) ->
ok.
+get_key_from_name(Name)->
+ ct_config:get_key_from_name(Name).
%%%-----------------------------------------------------------------
%%% @spec register_connection(TargetName,Address,Callback,Handle) ->
@@ -392,7 +348,7 @@ close_connections([]) ->
%%% test is finished by calling <code>Callback:close/1</code>.</p>
register_connection(TargetName,Address,Callback,Handle) ->
TargetRef =
- case get_ref_from_name(TargetName) of
+ case ct_config:get_ref_from_name(TargetName) of
{ok,Ref} ->
Ref;
_ ->
@@ -430,7 +386,7 @@ unregister_connection(Handle) ->
%%%
%%% @doc Check if a connection already exists.
does_connection_exist(TargetName,Address,Callback) ->
- case get_ref_from_name(TargetName) of
+ case ct_config:get_ref_from_name(TargetName) of
{ok,TargetRef} ->
case ets:select(?conn_table,[{#conn{handle='$1',
targetref=TargetRef,
@@ -460,7 +416,7 @@ does_connection_exist(TargetName,Address,Callback) ->
%%% @doc Return all connections for the <code>Callback</code> on the
%%% given target (<code>TargetName</code>).
get_connections(TargetName,Callback) ->
- case get_ref_from_name(TargetName) of
+ case ct_config:get_ref_from_name(TargetName) of
{ok,Ref} ->
{ok,ets:select(?conn_table,[{#conn{handle='$1',
address='$2',
@@ -480,236 +436,11 @@ get_target_name(ConnPid) ->
[],
['$1']}]) of
[TargetRef] ->
- get_name_from_ref(TargetRef);
+ ct_config:get_name_from_ref(TargetRef);
[] ->
{error,{unknown_connection,ConnPid}}
end.
-
-%%%-----------------------------------------------------------------
-%%% @hidden
-%%% @equiv ct:require/1
-require(Key) when is_atom(Key) ->
- require({Key,[]});
-require({Key,SubKeys}) when is_atom(Key) ->
- allocate('_UNDEF',Key,to_list(SubKeys));
-require(Key) ->
- {error,{invalid,Key}}.
-
-
-%%%-----------------------------------------------------------------
-%%% @hidden
-%%% @equiv ct:require/2
-require(Name,Key) when is_atom(Key) ->
- require(Name,{Key,[]});
-require(Name,{Key,SubKeys}) when is_atom(Name), is_atom(Key) ->
- call({require,Name,Key,to_list(SubKeys)});
-require(Name,Keys) ->
- {error,{invalid,{Name,Keys}}}.
-
-to_list(X) when is_list(X) -> X;
-to_list(X) -> [X].
-
-do_require(Name,Key,SubKeys) when is_list(SubKeys) ->
- case get_key_from_name(Name) of
- {error,_} ->
- allocate(Name,Key,SubKeys);
- {ok,Key} ->
- %% already allocated - check that it has all required subkeys
- Vals = [Val || {_Ref,Val} <- lookup_name(Name)],
- case get_subconfig(SubKeys,Vals) of
- {ok,_SubMapped} ->
- ok;
- Error ->
- Error
- end;
- {ok,OtherKey} ->
- {error,{name_in_use,Name,OtherKey}}
- end.
-
-allocate(Name,Key,SubKeys) ->
- case ets:match_object(?attr_table,#ct_conf{key=Key,name='_UNDEF',_='_'}) of
- [] ->
- {error,{not_available,Key}};
- Available ->
- case allocate_subconfig(Name,SubKeys,Available,false) of
- ok ->
- ok;
- Error ->
- Error
- end
- end.
-
-allocate_subconfig(Name,SubKeys,[C=#ct_conf{value=Value}|Rest],Found) ->
- case do_get_config(SubKeys,Value,[]) of
- {ok,_SubMapped} ->
- ets:insert(?attr_table,C#ct_conf{name=Name}),
- allocate_subconfig(Name,SubKeys,Rest,true);
- _Error ->
- allocate_subconfig(Name,SubKeys,Rest,Found)
- end;
-allocate_subconfig(_Name,_SubKeys,[],true) ->
- ok;
-allocate_subconfig(_Name,SubKeys,[],false) ->
- {error,{not_available,SubKeys}}.
-
-
-
-
-%%%-----------------------------------------------------------------
-%%% @hidden
-%%% @equiv ct:get_config/1
-get_config(KeyOrName) ->
- get_config(KeyOrName,undefined,[]).
-
-%%%-----------------------------------------------------------------
-%%% @hidden
-%%% @equiv ct:get_config/2
-get_config(KeyOrName,Default) ->
- get_config(KeyOrName,Default,[]).
-
-%%%-----------------------------------------------------------------
-%%% @hidden
-%%% @equiv ct:get_config/3
-get_config(KeyOrName,Default,Opts) when is_atom(KeyOrName) ->
- case lookup_config(KeyOrName) of
- [] ->
- Default;
- [{_Ref,Val}|_] = Vals ->
- case {lists:member(all,Opts),lists:member(element,Opts)} of
- {true,true} ->
- [{KeyOrName,V} || {_R,V} <- lists:sort(Vals)];
- {true,false} ->
- [V || {_R,V} <- lists:sort(Vals)];
- {false,true} ->
- {KeyOrName,Val};
- {false,false} ->
- Val
- end
- end;
-
-get_config({KeyOrName,SubKey},Default,Opts) ->
- case lookup_config(KeyOrName) of
- [] ->
- Default;
- Vals ->
- Vals1 = case [Val || {_Ref,Val} <- lists:sort(Vals)] of
- Result=[L|_] when is_list(L) ->
- case L of
- [{_,_}|_] ->
- Result;
- _ ->
- []
- end;
- _ ->
- []
- end,
- case get_subconfig([SubKey],Vals1,[],Opts) of
- {ok,[{_,SubVal}|_]=SubVals} ->
- case {lists:member(all,Opts),lists:member(element,Opts)} of
- {true,true} ->
- [{{KeyOrName,SubKey},Val} || {_,Val} <- SubVals];
- {true,false} ->
- [Val || {_SubKey,Val} <- SubVals];
- {false,true} ->
- {{KeyOrName,SubKey},SubVal};
- {false,false} ->
- SubVal
- end;
- _ ->
- Default
- end
- end.
-
-
-get_subconfig(SubKeys,Values) ->
- get_subconfig(SubKeys,Values,[],[]).
-
-get_subconfig(SubKeys,[Value|Rest],Mapped,Opts) ->
- case do_get_config(SubKeys,Value,[]) of
- {ok,SubMapped} ->
- case lists:member(all,Opts) of
- true ->
- get_subconfig(SubKeys,Rest,Mapped++SubMapped,Opts);
- false ->
- {ok,SubMapped}
- end;
- _Error ->
- get_subconfig(SubKeys,Rest,Mapped,Opts)
- end;
-get_subconfig(SubKeys,[],[],_) ->
- {error,{not_available,SubKeys}};
-get_subconfig(_SubKeys,[],Mapped,_) ->
- {ok,Mapped}.
-
-do_get_config([Key|Required],Available,Mapped) ->
- case lists:keysearch(Key,1,Available) of
- {value,{Key,Value}} ->
- NewAvailable = lists:keydelete(Key,1,Available),
- NewMapped = [{Key,Value}|Mapped],
- do_get_config(Required,NewAvailable,NewMapped);
- false ->
- {error,{not_available,Key}}
- end;
-do_get_config([],_Available,Mapped) ->
- {ok,lists:reverse(Mapped)}.
-
-get_all_config() ->
- ets:select(?attr_table,[{#ct_conf{name='$1',key='$2',value='$3',
- default='$4',_='_'},
- [],
- [{{'$1','$2','$3','$4'}}]}]).
-
-lookup_config(KeyOrName) ->
- case lookup_name(KeyOrName) of
- [] ->
- lookup_key(KeyOrName);
- Values ->
- Values
- end.
-
-lookup_name(Name) ->
- ets:select(?attr_table,[{#ct_conf{ref='$1',value='$2',name=Name,_='_'},
- [],
- [{{'$1','$2'}}]}]).
-lookup_key(Key) ->
- ets:select(?attr_table,[{#ct_conf{key=Key,ref='$1',value='$2',name='_UNDEF',_='_'},
- [],
- [{{'$1','$2'}}]}]).
-
-
-
-
-%%%-----------------------------------------------------------------
-%%% @spec release_allocated() -> ok
-%%%
-%%% @doc Release all allocated resources, but don't take down any
-%%% connections.
-release_allocated() ->
- Allocated = ets:select(?attr_table,[{#ct_conf{name='$1',_='_'},
- [{'=/=','$1','_UNDEF'}],
- ['$_']}]),
- release_allocated(Allocated).
-release_allocated([H|T]) ->
- ets:delete_object(?attr_table,H),
- ets:insert(?attr_table,H#ct_conf{name='_UNDEF'}),
- release_allocated(T);
-release_allocated([]) ->
- ok.
-
-%%%-----------------------------------------------------------------
-%%% @spec
-%%%
-%%% @doc
-update_conf(Name, NewConfig) ->
- Old = ets:select(?attr_table,[{#ct_conf{name=Name,_='_'},[],['$_']}]),
- lists:foreach(fun(OldElem) ->
- NewElem = OldElem#ct_conf{value=NewConfig},
- ets:delete_object(?attr_table, OldElem),
- ets:insert(?attr_table, NewElem)
- end, Old),
- ok.
-
%%%-----------------------------------------------------------------
%%% @spec close_connections() -> ok
%%%
@@ -889,166 +620,6 @@ get_testdir(Dir, Suite) when is_list(Suite) ->
get_testdir(Dir, _) ->
get_testdir(Dir, all).
-%%%-----------------------------------------------------------------
-%%% @spec
-%%%
-%%% @doc
-encrypt_config_file(SrcFileName, EncryptFileName) ->
- case get_crypt_key_from_file() of
- {error,_} = E ->
- E;
- Key ->
- encrypt_config_file(SrcFileName, EncryptFileName, {key,Key})
- end.
-
-%%%-----------------------------------------------------------------
-%%% @spec
-%%%
-%%% @doc
-encrypt_config_file(SrcFileName, EncryptFileName, {file,KeyFile}) ->
- case get_crypt_key_from_file(KeyFile) of
- {error,_} = E ->
- E;
- Key ->
- encrypt_config_file(SrcFileName, EncryptFileName, {key,Key})
- end;
-
-encrypt_config_file(SrcFileName, EncryptFileName, {key,Key}) ->
- crypto:start(),
- {K1,K2,K3,IVec} = make_crypto_key(Key),
- case file:read_file(SrcFileName) of
- {ok,Bin0} ->
- Bin1 = term_to_binary({SrcFileName,Bin0}),
- Bin2 = case byte_size(Bin1) rem 8 of
- 0 -> Bin1;
- N -> list_to_binary([Bin1,random_bytes(8-N)])
- end,
- EncBin = crypto:des3_cbc_encrypt(K1, K2, K3, IVec, Bin2),
- case file:write_file(EncryptFileName, EncBin) of
- ok ->
- io:format("~s --(encrypt)--> ~s~n",
- [SrcFileName,EncryptFileName]),
- ok;
- {error,Reason} ->
- {error,{Reason,EncryptFileName}}
- end;
- {error,Reason} ->
- {error,{Reason,SrcFileName}}
- end.
-
-%%%-----------------------------------------------------------------
-%%% @spec
-%%%
-%%% @doc
-decrypt_config_file(EncryptFileName, TargetFileName) ->
- case get_crypt_key_from_file() of
- {error,_} = E ->
- E;
- Key ->
- decrypt_config_file(EncryptFileName, TargetFileName, {key,Key})
- end.
-
-
-%%%-----------------------------------------------------------------
-%%% @spec
-%%%
-%%% @doc
-decrypt_config_file(EncryptFileName, TargetFileName, {file,KeyFile}) ->
- case get_crypt_key_from_file(KeyFile) of
- {error,_} = E ->
- E;
- Key ->
- decrypt_config_file(EncryptFileName, TargetFileName, {key,Key})
- end;
-
-decrypt_config_file(EncryptFileName, TargetFileName, {key,Key}) ->
- crypto:start(),
- {K1,K2,K3,IVec} = make_crypto_key(Key),
- case file:read_file(EncryptFileName) of
- {ok,Bin} ->
- DecBin = crypto:des3_cbc_decrypt(K1, K2, K3, IVec, Bin),
- case catch binary_to_term(DecBin) of
- {'EXIT',_} ->
- {error,bad_file};
- {_SrcFile,SrcBin} ->
- case TargetFileName of
- undefined ->
- {ok,SrcBin};
- _ ->
- case file:write_file(TargetFileName, SrcBin) of
- ok ->
- io:format("~s --(decrypt)--> ~s~n",
- [EncryptFileName,TargetFileName]),
- ok;
- {error,Reason} ->
- {error,{Reason,TargetFileName}}
- end
- end
- end;
- {error,Reason} ->
- {error,{Reason,EncryptFileName}}
- end.
-
-
-get_crypt_key_from_file(File) ->
- case file:read_file(File) of
- {ok,Bin} ->
- case catch string:tokens(binary_to_list(Bin), [$\n,$\r]) of
- [Key] ->
- Key;
- _ ->
- {error,{bad_crypt_file,File}}
- end;
- {error,Reason} ->
- {error,{Reason,File}}
- end.
-
-get_crypt_key_from_file() ->
- CwdFile = filename:join(".",?cryptfile),
- {Result,FullName} =
- case file:read_file(CwdFile) of
- {ok,Bin} ->
- {Bin,CwdFile};
- _ ->
- case init:get_argument(home) of
- {ok,[[Home]]} ->
- HomeFile = filename:join(Home,?cryptfile),
- case file:read_file(HomeFile) of
- {ok,Bin} ->
- {Bin,HomeFile};
- _ ->
- {{error,no_crypt_file},noent}
- end;
- _ ->
- {{error,no_crypt_file},noent}
- end
- end,
- case FullName of
- noent ->
- Result;
- _ ->
- case catch string:tokens(binary_to_list(Result), [$\n,$\r]) of
- [Key] ->
- io:format("~nCrypt key file: ~s~n", [FullName]),
- Key;
- _ ->
- {error,{bad_crypt_file,FullName}}
- end
- end.
-
-make_crypto_key(String) ->
- <<K1:8/binary,K2:8/binary>> = First = erlang:md5(String),
- <<K3:8/binary,IVec:8/binary>> = erlang:md5([First|lists:reverse(String)]),
- {K1,K2,K3,IVec}.
-
-random_bytes(N) ->
- {A,B,C} = now(),
- random:seed(A, B, C),
- random_bytes_1(N, []).
-
-random_bytes_1(0, Acc) -> Acc;
-random_bytes_1(N, Acc) -> random_bytes_1(N-1, [random:uniform(255)|Acc]).
-
%%%-----------------------------------------------------------------
%%% @spec
@@ -1142,37 +713,6 @@ ct_make_ref_loop(N) ->
From ! {self(),N},
ct_make_ref_loop(N+1)
end.
-
-get_ref_from_name(Name) ->
- case ets:select(?attr_table,[{#ct_conf{name=Name,ref='$1',_='_'},
- [],
- ['$1']}]) of
- [Ref] ->
- {ok,Ref};
- _ ->
- {error,{no_such_name,Name}}
- end.
-
-get_name_from_ref(Ref) ->
- case ets:select(?attr_table,[{#ct_conf{name='$1',ref=Ref,_='_'},
- [],
- ['$1']}]) of
- [Name] ->
- {ok,Name};
- _ ->
- {error,{no_such_ref,Ref}}
- end.
-
-get_key_from_name(Name) ->
- case ets:select(?attr_table,[{#ct_conf{name=Name,key='$1',_='_'},
- [],
- ['$1']}]) of
- [Key|_] ->
- {ok,Key};
- _ ->
- {error,{no_such_name,Name}}
- end.
-
abs_name(Dir0) ->
Abs = filename:absname(Dir0),