+2003-09-28 Alexey Shchepin <alexey@sevcom.net>
+
+ * src/stringprep/stringprep_drv.c: Added support for nameprep,
+ nodeprep and resourceprep
+ * src/stringprep/stringprep.erl: Likewise
+
+ * src/ejabberd_sup.erl: Added loading of stringprep
+
+ * src/ejabberd_sm.erl: Cleanup
+
2003-09-26 Alexey Shchepin <alexey@sevcom.net>
* src/stringprep/: Support for stringprep (not completed yet)
all: $(ERLSHLIBS)
erl -s make all report -noinput -s erlang halt
+ cd stringprep; make
$(ERLSHLIBS): %.so: %.c
gcc -Wall $(INCLUDES) $(LIBDIRS) \
loop();
{open_session, User, Resource, From} ->
register_connection(User, Resource, From),
- %replace_and_register_my_connection(User, Resource, From),
- %replace_alien_connection(User, Resource),
loop();
{close_session, User, Resource} ->
remove_connection(User, Resource),
end.
-
-replace_alien_connection(User, Resource) ->
- LUser = jlib:tolower(User),
- F = fun() ->
- UR = {LUser, Resource},
- Es = mnesia:read({session, UR}),
- mnesia:write(#session{ur = UR, user = LUser, node = node()}),
- Es
- end,
- case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:foreach(
- fun(R) ->
- if R#session.node /= node() ->
- {ejabberd_sm, R#session.node} !
- {replace, User, Resource};
- true ->
- ok
- end
- end, Rs);
- _ ->
- false
- end.
-
-
replace_my_connection(User, Resource) ->
LUser = jlib:tolower(User),
F = fun() ->
false
end.
+
remove_connection(User, Resource) ->
LUser = jlib:tolower(User),
F = fun() ->
end,
mnesia:transaction(F).
-replace_and_register_my_connection(User, Resource, Pid) ->
- LUser = jlib:tolower(User),
- F = fun() ->
- UR = {LUser, Resource},
- Es = mnesia:read({local_session, UR}),
- mnesia:write(#local_session{ur = UR, pid = Pid}),
- Es
- end,
- case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:foreach(
- fun(R) ->
- R#local_session.pid ! replaced
- end, Rs);
- _ ->
- false
- end.
-
clean_table_from_bad_node(Node) ->
F = fun() ->
From, To, IQ);
[] ->
Err = jlib:make_error_reply(
- Packet, "501", "Not Implemented"),
+ Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router ! {route, To, From, Err}
end;
reply ->
infinity,
supervisor,
[ejabberd_listener]},
+ StringPrep =
+ {stringprep,
+ {stringprep, start_link, []},
+ permanent,
+ brutal_kill,
+ worker,
+ [stringprep]},
C2SSupervisor =
{ejabberd_c2s_sup,
{ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]},
[ejabberd_tmp_sup]},
{ok, {{one_for_one, 10, 1},
[Router, SM, S2S, Local,
+ StringPrep,
C2SSupervisor,
S2SInSupervisor,
S2SOutSupervisor,
-behaviour(gen_server).
--export([start/0, start_link/0, tolower/1]).
+-export([start/0, start_link/0,
+ tolower/1,
+ nameprep/1,
+ nodeprep/1,
+ resourceprep/1]).
%% Internal exports, call-back functions.
-export([init/1,
code_change/3,
terminate/2]).
-
+-define(NAMEPREP_COMMAND, 1).
+-define(NODEPREP_COMMAND, 2).
+-define(RESOURCEPREP_COMMAND, 3).
start() ->
gen_server:start({local, ?MODULE}, ?MODULE, [], []).
tolower(String) ->
+ control(0, String).
+
+nameprep(String) ->
+ control(?NAMEPREP_COMMAND, String).
+
+nodeprep(String) ->
+ control(?NODEPREP_COMMAND, String).
+
+resourceprep(String) ->
+ control(?RESOURCEPREP_COMMAND, String).
+
+control(Command, String) ->
[{port, Port} | _] = ets:lookup(stringprep_table, port),
- Res = port_control(Port, 1, String),
- binary_to_list(Res).
+ case port_control(Port, Command, String) of
+ [0 | _] -> error;
+ [1 | Res] -> Res
+ end.
#include "uni_data.c"
+#define NAMEPREP_COMMAND 1
+#define NODEPREP_COMMAND 2
+#define RESOURCEPREP_COMMAND 3
+
typedef struct {
ErlDrvPort port;
} stringprep_data;
stringprep_data* d = (stringprep_data*)driver_alloc(sizeof(stringprep_data));
d->port = port;
- set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
+ //set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
return (ErlDrvData)d;
}
char *buf, int len,
char **rbuf, int rlen)
{
- int i, j=0;
+ int i, j=1;
unsigned char c;
int bad = 0;
int uc, ruc;
int size;
int info;
- ErlDrvBinary *b;
+ int prohibit, tolower;
char *rstring;
- size = len;
+ size = len + 1;
+
+ rstring = driver_alloc(size);
+ rstring[0] = 0;
- rstring = malloc(size);
+ switch (command)
+ {
+ case 0:
+ prohibit = ACMask;
+ tolower = 1;
+ break;
+
+ case NAMEPREP_COMMAND:
+ prohibit = ACMask;
+ tolower = 1;
+ break;
+
+ case NODEPREP_COMMAND:
+ prohibit = ACMask | C11Mask | C21Mask | XNPMask;
+ tolower = 1;
+ break;
+
+ case RESOURCEPREP_COMMAND:
+ prohibit = ACMask | C21Mask;
+ tolower = 0;
+ break;
+ }
for(i=0; i < len; i++)
{
}
if(bad) {
- *rbuf = (char*)(b = driver_alloc_binary(1));
- b->orig_bytes[0] = 0;
- free(rstring);
+ *rbuf = rstring;
return 1;
}
-
info = GetUniCharInfo(uc);
- ruc = uc + GetDelta(info);
+ if(info & prohibit) {
+ *rbuf = rstring;
+ return 1;
+ }
- if(ruc < 0x80) {
- if(j >= size) {
- size = 2*size + 1;
- rstring = realloc(rstring, size);
- }
- rstring[j] = (char) ruc;
- j++;
- } else if(ruc < 0x7FF) {
- if(j >= size) {
- size = 2*size + 2;
- rstring = realloc(rstring, size);
+
+ if(!(info & B1Mask))
+ {
+ if(tolower) {
+ ruc = uc + GetDelta(info);
+ } else {
+ ruc = uc;
}
- rstring[j] = (char) ((ruc >> 6) | 0xC0);
- rstring[j+1] = (char) ((ruc | 0x80) & 0xBF);
- j += 2;
- } else if(ruc < 0xFFFF) {
- if(j >= size) {
- size = 2*size + 3;
- rstring = realloc(rstring, size);
+
+ if(ruc < 0x80) {
+ if(j >= size) {
+ size = 2*size + 1;
+ rstring = driver_realloc(rstring, size);
+ }
+ rstring[j] = (char) ruc;
+ j++;
+ } else if(ruc < 0x7FF) {
+ if(j + 1 >= size) {
+ size = 2*size + 2;
+ rstring = driver_realloc(rstring, size);
+ }
+ rstring[j] = (char) ((ruc >> 6) | 0xC0);
+ rstring[j+1] = (char) ((ruc | 0x80) & 0xBF);
+ j += 2;
+ } else if(ruc < 0xFFFF) {
+ if(j + 2 >= size) {
+ size = 2*size + 3;
+ rstring = driver_realloc(rstring, size);
+ }
+ rstring[j] = (char) ((ruc >> 12) | 0xE0);
+ rstring[j+1] = (char) (((ruc >> 6) | 0x80) & 0xBF);
+ rstring[j+2] = (char) ((ruc | 0x80) & 0xBF);
+ j += 3;
}
- rstring[j] = (char) ((ruc >> 12) | 0xE0);
- rstring[j+1] = (char) (((ruc >> 6) | 0x80) & 0xBF);
- rstring[j+2] = (char) ((ruc | 0x80) & 0xBF);
- j += 3;
}
}
-
-
- *rbuf = (char*)(b = driver_alloc_binary(j));
- memcpy(b->orig_bytes, rstring, j);
- free(rstring);
+ rstring[0] = 1;
+ *rbuf = rstring;
return j;
}
ErlDrvEntry stringprep_driver_entry = {
- NULL, /* F_PTR init, N/A */
- stringprep_erl_start, /* L_PTR start, called when port is opened */
- stringprep_erl_stop, /* F_PTR stop, called when port is closed */
- NULL, /* F_PTR output, called when erlang has sent */
- NULL, /* F_PTR ready_input, called when input descriptor ready */
- NULL, /* F_PTR ready_output, called when output descriptor ready */
- "stringprep_drv", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- stringprep_erl_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL /* F_PTR outputv, reserved */
+ NULL, /* F_PTR init, N/A */
+ stringprep_erl_start, /* L_PTR start, called when port is opened */
+ stringprep_erl_stop, /* F_PTR stop, called when port is closed */
+ NULL, /* F_PTR output, called when erlang has sent */
+ NULL, /* F_PTR ready_input, called when input descriptor ready */
+ NULL, /* F_PTR ready_output, called when output descriptor ready */
+ "stringprep_drv", /* char *driver_name, the argument to open_port */
+ NULL, /* F_PTR finish, called when unloaded */
+ NULL, /* handle */
+ stringprep_erl_control, /* F_PTR control, port_command callback */
+ NULL, /* F_PTR timeout, reserved */
+ NULL /* F_PTR outputv, reserved */
};
#ifdef WIN32