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 + -
显示快捷键?