diff --git a/ChangeLog b/ChangeLog index e11036721..872ad657d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-09-28 Alexey Shchepin + + * 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 * src/stringprep/: Support for stringprep (not completed yet) diff --git a/src/Makefile b/src/Makefile index b7496f527..9fd1c0dcd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,6 +12,7 @@ ERLSHLIBS = expat_erl.so all: $(ERLSHLIBS) erl -s make all report -noinput -s erlang halt + cd stringprep; make $(ERLSHLIBS): %.so: %.c gcc -Wall $(INCLUDES) $(LIBDIRS) \ diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 977f6979d..7368f9307 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -63,8 +63,6 @@ loop() -> 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), @@ -133,31 +131,6 @@ register_connection(User, Resource, Pid) -> 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() -> @@ -176,6 +149,7 @@ replace_my_connection(User, Resource) -> false end. + remove_connection(User, Resource) -> LUser = jlib:tolower(User), F = fun() -> @@ -185,24 +159,6 @@ remove_connection(User, Resource) -> 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() -> @@ -426,7 +382,7 @@ process_iq(From, To, Packet) -> 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 -> diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl index 865ed89dc..76dedc1ee 100644 --- a/src/ejabberd_sup.erl +++ b/src/ejabberd_sup.erl @@ -49,6 +49,13 @@ init([]) -> 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]}, @@ -90,6 +97,7 @@ init([]) -> [ejabberd_tmp_sup]}, {ok, {{one_for_one, 10, 1}, [Router, SM, S2S, Local, + StringPrep, C2SSupervisor, S2SInSupervisor, S2SOutSupervisor, diff --git a/src/stringprep/stringprep.erl b/src/stringprep/stringprep.erl index 919ae7a44..eb0c9ed4c 100644 --- a/src/stringprep/stringprep.erl +++ b/src/stringprep/stringprep.erl @@ -12,7 +12,11 @@ -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, @@ -22,7 +26,9 @@ code_change/3, terminate/2]). - +-define(NAMEPREP_COMMAND, 1). +-define(NODEPREP_COMMAND, 2). +-define(RESOURCEPREP_COMMAND, 3). start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). @@ -66,9 +72,23 @@ terminate(_Reason, Port) -> 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. diff --git a/src/stringprep/stringprep_drv.c b/src/stringprep/stringprep_drv.c index e6eb3d378..d74b93e57 100644 --- a/src/stringprep/stringprep_drv.c +++ b/src/stringprep/stringprep_drv.c @@ -7,6 +7,10 @@ #include "uni_data.c" +#define NAMEPREP_COMMAND 1 +#define NODEPREP_COMMAND 2 +#define RESOURCEPREP_COMMAND 3 + typedef struct { ErlDrvPort port; } stringprep_data; @@ -17,7 +21,7 @@ static ErlDrvData stringprep_erl_start(ErlDrvPort port, char *buff) 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; } @@ -32,18 +36,42 @@ static int stringprep_erl_control(ErlDrvData drv_data, 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 = malloc(size); + rstring = driver_alloc(size); + rstring[0] = 0; + + 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++) { @@ -74,48 +102,55 @@ static int stringprep_erl_control(ErlDrvData drv_data, } 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); + + if(!(info & B1Mask)) + { + if(tolower) { + ruc = uc + GetDelta(info); + } else { + ruc = uc; } - rstring[j] = (char) ruc; - j++; - } else if(ruc < 0x7FF) { - if(j >= size) { - size = 2*size + 2; - 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 >> 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); - } - 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; } @@ -123,18 +158,18 @@ static int stringprep_erl_control(ErlDrvData drv_data, 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