summaryrefslogtreecommitdiff
path: root/chat/ejabberd/patches/patch-ai
blob: b3ae478b4aa1aa71fecff7cb03aeb4c0481146b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
$NetBSD: patch-ai,v 1.1 2008/11/12 13:13:59 martti Exp $

Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)

--- src/web/ejabberd_web_admin.erl.orig	2008-08-27 12:37:52.000000000 +0300
+++ src/web/ejabberd_web_admin.erl
@@ -1806,15 +1806,21 @@ get_node(global, Node, ["ports"], Query,
 		  ok;
 	      {'EXIT', _Reason} ->
 		  error;
+	      {is_added, ok} ->
+		  ok;
+	      {is_added, {error, Reason}} ->
+		  {error, io_lib:format("~p", [Reason])};
 	      _ ->
 		  nothing
 	  end,
+    %% TODO: This sorting does not work when [{{Port, IP}, Module, Opts}]
     NewPorts = lists:sort(
 		 rpc:call(Node, ejabberd_config, get_local_option, [listen])),
     [?XC("h1", ?T("Listened Ports at ") ++ atom_to_list(Node))] ++
 	case Res of
 	    ok -> [?CT("Submitted"), ?P];
 	    error -> [?CT("Bad format"), ?P];
+	    {error, ReasonT} -> [?CT("Problem: "), ?C(ReasonT), ?P];
 	    nothing -> []
 	end ++
 	[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -2052,58 +2058,76 @@ node_ports_to_xhtml(Ports, Lang) ->
 	 [?XE("thead",
 	      [?XE("tr",
 		   [?XCT("td", "Port"),
+		    ?XCT("td", "IP"),
 		    ?XCT("td", "Module"),
 		    ?XCT("td", "Options")
 		   ])]),
 	  ?XE("tbody",
 	      lists:map(
-		fun({Port, Module, Opts} = _E) ->
-			SPort = integer_to_list(Port),
+		fun({PortIP, Module, Opts} = _E) ->
+			{_Port, SPort, _TIP, SIP, SSPort, OptsClean} =
+			    get_port_data(PortIP, Opts),
 			SModule = atom_to_list(Module),
 			%%ID = term_to_id(E),
 			?XE("tr",
-			    [?XC("td", SPort),
-			     ?XE("td", [?INPUT("text", "module" ++ SPort,
-					       SModule)]),
-			     ?XE("td", [?INPUTS("text", "opts" ++ SPort,
-						term_to_string(Opts), "40")]),
-			     ?XE("td", [?INPUTT("submit", "add" ++ SPort,
+			    [?XAE("td", [{"size", "6"}], [?C(SPort)]),
+			     ?XAE("td", [{"size", "15"}], [?C(SIP)]),
+			     ?XE("td", [?INPUTS("text", "module" ++ SSPort,
+						SModule, "15")]),
+			     ?XE("td", [?INPUTS("text", "opts" ++ SSPort,
+						term_to_string(OptsClean), "40")]),
+			     ?XE("td", [?INPUTT("submit", "add" ++ SSPort,
 						"Update")]),
-			     ?XE("td", [?INPUTT("submit", "delete" ++ SPort,
+			     ?XE("td", [?INPUTT("submit", "delete" ++ SSPort,
 						"Delete")])
 			    ]
 			   )
 		end, Ports) ++
 	      [?XE("tr",
 		   [?XE("td", [?INPUTS("text", "portnew", "", "6")]),
-		    ?XE("td", [?INPUT("text", "modulenew", "")]),
-		    ?XE("td", [?INPUTS("text", "optsnew", "", "40")]),
+		    ?XE("td", [?INPUTS("text", "ipnew", "0.0.0.0", "15")]),
+		    ?XE("td", [?INPUTS("text", "modulenew", "", "17")]),
+		    ?XE("td", [?INPUTS("text", "optsnew", "[]", "40")]),
 		    ?XAE("td", [{"colspan", "2"}],
 			 [?INPUTT("submit", "addnew", "Add New")])
 		   ]
 		  )]
 	     )]).
 
+get_port_data(PortIP, Opts) ->
+    {Port, IPT, IPS, _IPV, OptsClean} = ejabberd_listener:parse_listener_portip(PortIP, Opts),
+    SPort = io_lib:format("~p", [Port]),
+
+    SSPort = lists:flatten(
+	       lists:map(
+		 fun(N) -> io_lib:format("~.16b", [N]) end,
+		 binary_to_list(crypto:md5(SPort++IPS)))),
+    {Port, SPort, IPT, IPS, SSPort, OptsClean}.
 
 node_ports_parse_query(Node, Ports, Query) ->
     lists:foreach(
-      fun({Port, _Module1, _Opts1}) ->
-	      SPort = integer_to_list(Port),
-	      case lists:keysearch("add" ++ SPort, 1, Query) of
+      fun({PortIP, _Module1, Opts1}) ->
+	      {Port, _SPort, TIP, _SIP, SSPort, _OptsClean} =
+		  get_port_data(PortIP, Opts1),
+	      case lists:keysearch("add" ++ SSPort, 1, Query) of
 		  {value, _} ->
+		      PortIP2 = {Port, TIP},
 		      {{value, {_, SModule}}, {value, {_, SOpts}}} =
-			  {lists:keysearch("module" ++ SPort, 1, Query),
-			   lists:keysearch("opts" ++ SPort, 1, Query)},
+			  {lists:keysearch("module" ++ SSPort, 1, Query),
+			   lists:keysearch("opts" ++ SSPort, 1, Query)},
 		      Module = list_to_atom(SModule),
 		      {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
 		      {ok, Opts} = erl_parse:parse_term(Tokens),
-		      rpc:call(Node, ejabberd_listener, delete_listener, [Port]),
-		      rpc:call(Node, ejabberd_listener, add_listener, [Port, Module, Opts]),
-		      throw(submitted);
+		      rpc:call(Node, ejabberd_listener, delete_listener,
+			       [PortIP2]),
+		      R=rpc:call(Node, ejabberd_listener, add_listener,
+				 [PortIP2, Module, Opts]),
+		      throw({is_added, R});
 		  _ ->
-		      case lists:keysearch("delete" ++ SPort, 1, Query) of
+		      case lists:keysearch("delete" ++ SSPort, 1, Query) of
 			  {value, _} ->
-			      rpc:call(Node, ejabberd_listener, delete_listener, [Port]),
+			      rpc:call(Node, ejabberd_listener, delete_listener,
+				       [PortIP]),
 			      throw(submitted);
 			  _ ->
 			      ok
@@ -2113,17 +2137,28 @@ node_ports_parse_query(Node, Ports, Quer
     case lists:keysearch("addnew", 1, Query) of
 	{value, _} ->
 	    {{value, {_, SPort}},
+	     {value, {_, STIP}}, %% It is a string that may represent a tuple
 	     {value, {_, SModule}},
 	     {value, {_, SOpts}}} =
 		{lists:keysearch("portnew", 1, Query),
+		 lists:keysearch("ipnew", 1, Query),
 		 lists:keysearch("modulenew", 1, Query),
 		 lists:keysearch("optsnew", 1, Query)},
-	    Port = list_to_integer(SPort),
+	    {ok, Toks, _} = erl_scan:string(SPort ++ "."),
+	    {ok, Port2} = erl_parse:parse_term(Toks),
+	    {ok, ToksIP, _} = erl_scan:string(STIP ++ "."),
+	    STIP2 = case erl_parse:parse_term(ToksIP) of
+			{ok, IPTParsed} -> IPTParsed;
+			{error, _} -> STIP
+		    end,
 	    Module = list_to_atom(SModule),
 	    {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
 	    {ok, Opts} = erl_parse:parse_term(Tokens),
-	    rpc:call(Node, ejabberd_listener, add_listener, [Port, Module, Opts]),
-	    throw(submitted);
+	    {Port2, _SPort, IP2, _SIP, _SSPort, OptsClean} =
+		get_port_data({Port2, STIP2}, Opts),
+	    R=rpc:call(Node, ejabberd_listener, add_listener,
+		       [{Port2, IP2}, Module, OptsClean]),
+	    throw({is_added, R});
 	_ ->
 	    ok
     end.