Current section
Files
Jump to
Current section
Files
src/radius_dict_file.erl
-module(radius_dict_file).
-export([load/1]).
-include("radius.hrl").
load(File) ->
{ok, Fd} = file:open(dictionary_path(File), [read]),
lists:flatten(read_line(Fd)).
%% Internal functions
dictionary_path(File) ->
PrivDir = case code:priv_dir(radius) of
{error, bad_name} ->
"./priv";
D -> D
end,
filename:join([PrivDir, File]).
read_line(Fd) ->
read_line(Fd, []).
read_line(Fd, Acc) ->
case io:get_line(Fd, "") of
eof ->
ok = file:close(Fd),
lists:reverse(Acc);
Line ->
L = strip_comments(Line),
case parse_line(string:tokens(L, "\t\n\s")) of
{ok, Result} ->
read_line(Fd, [Result | Acc]);
_ ->
read_line(Fd, Acc)
end
end.
strip_comments(Line) ->
case string:chr(Line, $#) of
0 ->
Line;
I ->
L = string:sub_string(Line, 1, I - 1),
string:strip(L)
end.
parse_line(["$INCLUDE", File]) ->
{ok, load(File)};
parse_line(["ATTRIBUTE", Name, Code, Type]) ->
{ok, #attribute{name = Name, code = list_to_integer(Code), type = list_to_atom(Type)}};
parse_line(["ATTRIBUTE", Name, Code, Type, Extra]) ->
case get({vendor, Extra}) of
undefined ->
Opts = [parse_option(string:tokens(I, "=")) || I <- string:tokens(Extra, ",")],
A = #attribute{name = Name, code = list_to_integer(Code), type = list_to_atom(Type)},
{ok, A#attribute{opts = Opts}};
Vendor ->
C = {Vendor, list_to_integer(Code)},
A = #attribute{name = Name, code = C, type = list_to_atom(Type)},
{ok, A}
end;
parse_line(["VALUE", A, Name, Value]) ->
V = #value{aname = A, vname = Name, value = list_to_integer(Value)},
{ok, V};
parse_line(["VENDOR", Name, Code]) ->
put({vendor, Name}, list_to_integer(Code));
parse_line(_) ->
ok.
parse_option(["has_tag"]) ->
has_tag;
parse_option(["encrypt", Value]) ->
{encrypt, list_to_integer(Value)}.