inet_parse.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 745 行 · 第 1/2 页
ERL
745 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%-module(inet_parse).%% Parser for all kinds of ineternet configuration files-export([hosts/1, hosts/2]).-export([hosts_vxworks/1]).-export([protocols/1, protocols/2]).-export([netmasks/1, netmasks/2]).-export([networks/1, networks/2]).-export([services/1, services/2]).-export([rpc/1, rpc/2]).-export([resolv/1, resolv/2]).-export([host_conf_linux/1, host_conf_linux/2]).-export([host_conf_freebsd/1, host_conf_freebsd/2]).-export([host_conf_bsdos/1, host_conf_bsdos/2]).-export([nsswitch_conf/1, nsswitch_conf/2]).-export([ipv4_address/1, ipv6_address/1]).-export([address/1]).-export([visible_string/1, domain/1]).-export([ntoa/1, dots/1]).-export([split_line/1]).-import(lists, [reverse/1]).-include_lib("kernel/include/file.hrl").%% --------------------------------------------------------------------------%% Parse services internet style%% Syntax: %% Name Port/Protocol [Aliases] \n%% # comment%% --------------------------------------------------------------------------services(File) -> services(noname, File).services(Fname, File) -> Fn = fun([Name, PortProto | Aliases]) -> {Proto,Port} = port_proto(PortProto, 0), {Name,Proto,Port,Aliases} end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%% Parse rpc program names%% Syntax:%% Name Program [Aliases] \n |%% # comment%% --------------------------------------------------------------------------rpc(File) -> rpc(noname, File).rpc(Fname, File) -> Fn = fun([Name,Program | Aliases]) -> Prog = list_to_integer(Program), {Name,Prog,Aliases} end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%% Parse hosts file unix style%% Syntax:%% IP Name [Aliases] \n |%% # comment%% --------------------------------------------------------------------------hosts(File) -> hosts(noname,File).hosts(Fname,File) -> Fn = fun([Address, Name | Aliases]) -> {ok,IP} = address(Address), {IP, Name, Aliases} end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%% Parse hostShow vxworks style%% Syntax:%% Name IP [Aliases] \n %% --------------------------------------------------------------------------hosts_vxworks(Hosts) -> Fn = fun([Name, Address | Aliases]) -> {ok,IP} = address(Address), {IP, Name, Aliases} end, parse_file(Hosts, Fn).%% --------------------------------------------------------------------------%% Parse resolv file unix style%% Syntax:%% domain Domain \n%% nameserver IP \n%% search Dom1 Dom2 ... \n%% lookup Method1 Method2 Method3 \n%% # comment%% --------------------------------------------------------------------------resolv(File) -> resolv(noname,File).resolv(Fname, File) -> Fn = fun(["domain", Domain]) -> {domain, Domain}; (["nameserver", Address]) -> {ok,IP} = address(Address), {nameserver,IP}; (["search" | List]) -> {search, List}; (["lookup" | Types]) -> {lookup, Types}; (_) -> skip %% there are too many local options, we MUST skip end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%%%% Parse Linux host.conf file%% find "order" only.%%%% --------------------------------------------------------------------------host_conf_linux(File) -> host_conf_linux(noname,File).host_conf_linux(Fname, File) -> Fn = fun(["order" | Order]) -> %% XXX remove ',' between entries {lookup, split_comma(Order)}; (_) -> skip end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%%%% Parse Freebsd/Netbsd host.conf file%% find "order" only.%%%% --------------------------------------------------------------------------host_conf_freebsd(File) -> host_conf_freebsd(noname,File).host_conf_freebsd(Fname, File) -> Fn = fun([Type]) -> Type end, case parse_file(Fname, File, Fn) of {ok, Ls} -> {ok, [{lookup, Ls}]}; Error -> Error end.%% --------------------------------------------------------------------------%%%% Parse BSD/OS irs.conf file%% find "hosts" only and ignore options.%%%% Syntax: %% Map AccessMethod [,AccessMethod] [continue|merge [,merge|,continue]] \n%% # comment%% --------------------------------------------------------------------------host_conf_bsdos(File) -> host_conf_bsdos(noname,File).host_conf_bsdos(Fname, File) -> Fn = fun(["hosts" | List]) -> delete_options(split_comma(List)); (_) -> skip end, case parse_file(Fname, File, Fn) of {ok, Ls} -> {ok, [{lookup, lists:append(Ls)}]}; Error -> Error end.delete_options(["continue"|T]) -> delete_options(T);delete_options(["merge"|T]) -> delete_options(T);delete_options([H|T]) -> [H|delete_options(T)];delete_options([]) -> [].%% --------------------------------------------------------------------------%%%% Parse Solaris nsswitch.conf%% find "hosts:" only%%%% --------------------------------------------------------------------------nsswitch_conf(File) -> nsswitch_conf(noname,File).nsswitch_conf(Fname, File) -> Fn = fun(["hosts:" | Types]) -> {lookup, Types}; (_) -> skip end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%% Parse protocol file unix style%% Syntax:%% name protocol number name \n%% # comment%% --------------------------------------------------------------------------protocols(File) -> protocols(noname,File).protocols(Fname, File) -> Fn = fun([Name, Number, DName]) -> {list_to_atom(Name), list_to_integer(Number), DName} end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%% Parse netmasks file unix style%% Syntax:%% Network Subnetmask%% # comment%% --------------------------------------------------------------------------netmasks(File) -> netmasks(noname, File).netmasks(Fname, File) -> Fn = fun([Net, Subnetmask]) -> {ok, NetIP} = address(Net), {ok, Mask} = address(Subnetmask), {NetIP, Mask} end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%% Parse networks file unix style%% Syntax:%% network-name network-number aliases ...%% # comment%% --------------------------------------------------------------------------networks(File) -> networks(noname, File).networks(Fname, File) -> Fn = fun([NetName, NetNumber]) -> Number = list_to_integer(NetNumber), {NetName, Number} end, parse_file(Fname, File, Fn).%% --------------------------------------------------------------------------%%%% Simple Line by Line parser%%%% --------------------------------------------------------------------------parse_file(File, Fn) -> parse_file(noname, File, Fn).parse_file(Fname, {fd,Fd}, Fn) -> parse_fd(Fname,Fd, 1, Fn, []);parse_file(Fname, {chars,Cs}, Fn) when is_list(Cs) -> parse_cs(Fname, Cs, 1, Fn, []);parse_file(Fname, {chars,Cs}, Fn) when is_binary(Cs) -> parse_cs(Fname, binary_to_list(Cs), 1, Fn, []);parse_file(_, File, Fn) -> case file:open(File, [read]) of {ok, Fd} -> Result = parse_fd(File,Fd, 1, Fn, []), file:close(Fd), Result; Error -> Error end.parse_fd(Fname,Fd, Line, Fun, Ls) -> case read_line(Fd) of eof -> {ok, reverse(Ls)}; Cs -> case split_line(Cs) of [] -> parse_fd(Fname, Fd, Line+1, Fun, Ls); Toks -> case catch Fun(Toks) of {'EXIT',_} -> error("~p:~p: erroneous line, SKIPPED~n",[Fname,Line]), parse_fd(Fname, Fd,Line+1,Fun,Ls); {warning,Wlist,Val} -> warning("~p:~p: warning! strange domain name(s) ~p ~n",[Fname,Line,Wlist]), parse_fd(Fname, Fd,Line+1,Fun,[Val|Ls]); skip -> parse_fd(Fname, Fd, Line+1, Fun, Ls); Val -> parse_fd(Fname, Fd, Line+1, Fun, [Val|Ls]) end end end.parse_cs(Fname, Chars, Line, Fun, Ls) -> case get_line(Chars) of eof -> {ok, reverse(Ls)}; {Cs,Chars1} -> case split_line(Cs) of [] -> parse_cs(Fname, Chars1, Line+1, Fun, Ls); Toks -> case catch Fun(Toks) of {'EXIT',_} -> error("~p:~p: erroneous line, SKIPPED~n",[Fname,Line]), parse_cs(Fname, Chars1, Line+1, Fun, Ls); {warning,Wlist,Val} -> warning("~p:~p: warning! strange domain name(s) ~p ~n",[Fname,Line,Wlist]), parse_cs(Fname, Chars1, Line+1, Fun, [Val|Ls]); skip -> parse_cs(Fname, Chars1, Line+1, Fun, Ls); Val -> parse_cs(Fname, Chars1, Line+1, Fun, [Val|Ls]) end end end.get_line([]) -> eof;get_line(Chars) -> get_line(Chars,[]).get_line([], Acc) -> {reverse(Acc), []};get_line([$\r, $\n | Cs], Acc) -> {reverse([$\n|Acc]), Cs};get_line([$\n | Cs], Acc) -> {reverse([$\n|Acc]), Cs};get_line([C | Cs], Acc) -> get_line(Cs, [C|Acc]).%%%% Read a line%%read_line(Fd) when is_pid(Fd) -> io:get_line(Fd, '');read_line(Fd) when is_record(Fd, file_descriptor) -> collect_line(Fd, []).collect_line(Fd, Cs) -> case file:read(Fd, 80) of {ok, Line} when is_binary(Line) -> collect_line(Fd, size(Line), binary_to_list(Line), Cs); {ok, Line} -> collect_line(Fd, length(Line), Line, Cs); eof when Cs =:= [] -> eof; eof -> reverse(Cs) end. collect_line(Fd, N, [$\r, $\n|_], Cs) -> file:position(Fd, {cur,-(N-2)}), reverse([$\n|Cs]);collect_line(Fd, N, [$\n|_], Cs) -> file:position(Fd, {cur,-(N-1)}), reverse([$\n|Cs]);collect_line(Fd, _, [], Cs) ->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?