* src/mod_vcard.erl: Added checks for stringprep results
* src/expat_erl.c: Workaround for EI encode_string bug * src/xml_stream.erl: Slightly changed protocol to expat driver * src/expat_erl.c: Likewise * src/mod_configure.erl: Minor fix SVN Revision: 156
This commit is contained in:
parent
2e41080960
commit
f01ea1f0d5
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2003-10-20 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/mod_vcard.erl: Added checks for stringprep results
|
||||||
|
|
||||||
|
* src/expat_erl.c: Workaround for EI encode_string bug
|
||||||
|
|
||||||
|
* src/xml_stream.erl: Slightly changed protocol to expat driver
|
||||||
|
* src/expat_erl.c: Likewise
|
||||||
|
|
||||||
|
* src/mod_configure.erl: Minor fix
|
||||||
|
|
||||||
2003-10-19 Alexey Shchepin <alexey@sevcom.net>
|
2003-10-19 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* doc/guide.tex: Fixed typo
|
* doc/guide.tex: Fixed typo
|
||||||
|
|
|
@ -465,7 +465,7 @@ except admins have traffic limit 1000 b/s.
|
||||||
{ssl, [{certfile, "/path/to/ssl.pem"}]}]},
|
{ssl, [{certfile, "/path/to/ssl.pem"}]}]},
|
||||||
{5269, ejabberd_s2s_in, []},
|
{5269, ejabberd_s2s_in, []},
|
||||||
{8888, ejabberd_service,
|
{8888, ejabberd_service,
|
||||||
[{host, "conference.example.org", [{password, "secret"}]}]}
|
[{hosts, ["conference.example.org"], [{password, "secret"}]}]}
|
||||||
]}.
|
]}.
|
||||||
</PRE>
|
</PRE>
|
||||||
<!--TOC subsubsection Modules-->
|
<!--TOC subsubsection Modules-->
|
||||||
|
@ -807,8 +807,8 @@ Example:
|
||||||
<PRE>
|
<PRE>
|
||||||
{modules, [
|
{modules, [
|
||||||
...
|
...
|
||||||
{mod_disco, [[{extra_domains, ["jit.example.com",
|
{mod_disco, [{extra_domains, ["jit.example.com",
|
||||||
"etc.example.com"]}]]},
|
"etc.example.com"]}]},
|
||||||
...
|
...
|
||||||
]}.
|
]}.
|
||||||
</PRE>
|
</PRE>
|
||||||
|
|
128
src/expat_erl.c
128
src/expat_erl.c
|
@ -5,6 +5,107 @@
|
||||||
#include <ei.h>
|
#include <ei.h>
|
||||||
#include <expat.h>
|
#include <expat.h>
|
||||||
|
|
||||||
|
#define EI_ENCODE_STRING_BUG
|
||||||
|
|
||||||
|
#ifdef EI_ENCODE_STRING_BUG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Workaround for EI encode_string bug
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define put8(s,n) do { \
|
||||||
|
(s)[0] = (char)((n) & 0xff); \
|
||||||
|
(s) += 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define put16be(s,n) do { \
|
||||||
|
(s)[0] = ((n) >> 8) & 0xff; \
|
||||||
|
(s)[1] = (n) & 0xff; \
|
||||||
|
(s) += 2; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define put32be(s,n) do { \
|
||||||
|
(s)[0] = ((n) >> 24) & 0xff; \
|
||||||
|
(s)[1] = ((n) >> 16) & 0xff; \
|
||||||
|
(s)[2] = ((n) >> 8) & 0xff; \
|
||||||
|
(s)[3] = (n) & 0xff; \
|
||||||
|
(s) += 4; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int ei_encode_string_len_fixed(char *buf, int *index, const char *p, int len)
|
||||||
|
{
|
||||||
|
char *s = buf + *index;
|
||||||
|
char *s0 = s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (len <= 0xffff) {
|
||||||
|
if (!buf) s += 3;
|
||||||
|
else {
|
||||||
|
put8(s,ERL_STRING_EXT);
|
||||||
|
put16be(s,len);
|
||||||
|
memmove(s,p,len); /* unterminated string */
|
||||||
|
}
|
||||||
|
s += len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!buf) s += 6 + (2*len);
|
||||||
|
else {
|
||||||
|
/* strings longer than 65535 are encoded as lists */
|
||||||
|
put8(s,ERL_LIST_EXT);
|
||||||
|
put32be(s,len);
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
put8(s,ERL_SMALL_INTEGER_EXT);
|
||||||
|
put8(s,p[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
put8(s,ERL_NIL_EXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*index += s-s0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ei_encode_string_fixed(char *buf, int *index, const char *p)
|
||||||
|
{
|
||||||
|
return ei_encode_string_len_fixed(buf, index, p, strlen(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ei_x_encode_string_len_fixed(ei_x_buff* x, const char* s, int len)
|
||||||
|
{
|
||||||
|
int i = x->index;
|
||||||
|
ei_encode_string_len_fixed(NULL, &i, s, len);
|
||||||
|
if (!x_fix_buff(x, i))
|
||||||
|
return -1;
|
||||||
|
return ei_encode_string_len_fixed(x->buff, &x->index, s, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ei_x_encode_string_fixed(ei_x_buff* x, const char* s)
|
||||||
|
{
|
||||||
|
return ei_x_encode_string_len_fixed(x, s, strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ei_encode_string_len_fixed(buf, index, p, len) \
|
||||||
|
ei_encode_string_len(buf, index, p, len)
|
||||||
|
#define ei_encode_string_fixed(buf, index, p) \
|
||||||
|
ei_encode_string(buf, index, p)
|
||||||
|
#define ei_x_encode_string_len_fixed(x, s, len) \
|
||||||
|
ei_x_encode_string_len(x, s, len)
|
||||||
|
#define ei_x_encode_string_fixed(x, s) \
|
||||||
|
ei_x_encode_string(x, s)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XML_START 0
|
||||||
|
#define XML_END 1
|
||||||
|
#define XML_CDATA 2
|
||||||
|
#define XML_ERROR 3
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ErlDrvPort port;
|
ErlDrvPort port;
|
||||||
XML_Parser parser;
|
XML_Parser parser;
|
||||||
|
@ -19,19 +120,19 @@ void *erlXML_StartElementHandler(expat_data *d,
|
||||||
|
|
||||||
ei_x_new_with_version(&buf);
|
ei_x_new_with_version(&buf);
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_atom(&buf, "xmlstart");
|
ei_x_encode_long(&buf, XML_START);
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_string(&buf, name);
|
ei_x_encode_string_fixed(&buf, name);
|
||||||
|
|
||||||
for (i = 0; atts[i]; i += 2) {}
|
for (i = 0; atts[i]; i += 2) {}
|
||||||
|
|
||||||
ei_x_encode_list_header(&buf, i/2);
|
ei_x_encode_list_header(&buf, i/2);
|
||||||
|
|
||||||
for (i = 0; atts[i]; i += 2)
|
for (i = 0; atts[i]; i += 2)
|
||||||
{
|
{
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_string(&buf, atts[i]);
|
ei_x_encode_string_fixed(&buf, atts[i]);
|
||||||
ei_x_encode_string(&buf, atts[i+1]);
|
ei_x_encode_string_fixed(&buf, atts[i+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_x_encode_empty_list(&buf);
|
ei_x_encode_empty_list(&buf);
|
||||||
|
@ -48,8 +149,8 @@ void *erlXML_EndElementHandler(expat_data *d,
|
||||||
|
|
||||||
ei_x_new_with_version(&buf);
|
ei_x_new_with_version(&buf);
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_atom(&buf, "xmlend");
|
ei_x_encode_long(&buf, XML_END);
|
||||||
ei_x_encode_string(&buf, name);
|
ei_x_encode_string_fixed(&buf, name);
|
||||||
|
|
||||||
driver_output(d->port, buf.buff, buf.index);
|
driver_output(d->port, buf.buff, buf.index);
|
||||||
ei_x_free(&buf);
|
ei_x_free(&buf);
|
||||||
|
@ -64,8 +165,8 @@ void *erlXML_CharacterDataHandler(expat_data *d,
|
||||||
|
|
||||||
ei_x_new_with_version(&buf);
|
ei_x_new_with_version(&buf);
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_atom(&buf, "xmlcdata");
|
ei_x_encode_long(&buf, XML_CDATA);
|
||||||
ei_x_encode_string_len(&buf, s, len);
|
ei_x_encode_string_len_fixed(&buf, s, len);
|
||||||
|
|
||||||
driver_output(d->port, buf.buff, buf.index);
|
driver_output(d->port, buf.buff, buf.index);
|
||||||
ei_x_free(&buf);
|
ei_x_free(&buf);
|
||||||
|
@ -104,11 +205,6 @@ static void expat_erl_output(ErlDrvData handle, char *buff, int bufflen)
|
||||||
char *errstring;
|
char *errstring;
|
||||||
ei_x_buff buf;
|
ei_x_buff buf;
|
||||||
|
|
||||||
/*buff[bufflen] = 0;
|
|
||||||
|
|
||||||
fprintf(stderr, "RCVD: '%s'\n", buff);
|
|
||||||
fflush(stderr);*/
|
|
||||||
|
|
||||||
res = XML_Parse(d->parser, buff, bufflen, 0);
|
res = XML_Parse(d->parser, buff, bufflen, 0);
|
||||||
|
|
||||||
if(!res)
|
if(!res)
|
||||||
|
@ -118,10 +214,10 @@ static void expat_erl_output(ErlDrvData handle, char *buff, int bufflen)
|
||||||
|
|
||||||
ei_x_new_with_version(&buf);
|
ei_x_new_with_version(&buf);
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_atom(&buf, "xmlerror");
|
ei_x_encode_long(&buf, XML_ERROR);
|
||||||
ei_x_encode_tuple_header(&buf, 2);
|
ei_x_encode_tuple_header(&buf, 2);
|
||||||
ei_x_encode_long(&buf, errcode);
|
ei_x_encode_long(&buf, errcode);
|
||||||
ei_x_encode_string(&buf, errstring);
|
ei_x_encode_string_fixed(&buf, errstring);
|
||||||
|
|
||||||
driver_output(d->port, buf.buff, buf.index);
|
driver_output(d->port, buf.buff, buf.index);
|
||||||
ei_x_free(&buf);
|
ei_x_free(&buf);
|
||||||
|
|
|
@ -568,7 +568,8 @@ set_form(["running nodes", ENode, "import", "dir"], Lang, XData) ->
|
||||||
false ->
|
false ->
|
||||||
{error, ?ERR_BAD_REQUEST};
|
{error, ?ERR_BAD_REQUEST};
|
||||||
{value, {_, [String]}} ->
|
{value, {_, [String]}} ->
|
||||||
rpc:call(Node, jd2ejd, import_dir, [String]);
|
rpc:call(Node, jd2ejd, import_dir, [String]),
|
||||||
|
{result, []};
|
||||||
_ ->
|
_ ->
|
||||||
{error, ?ERR_BAD_REQUEST}
|
{error, ?ERR_BAD_REQUEST}
|
||||||
end
|
end
|
||||||
|
|
|
@ -84,7 +84,7 @@ loop() ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_local_iq(_From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
case Type of
|
case Type of
|
||||||
set ->
|
set ->
|
||||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
|
@ -128,7 +128,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
lists:map(fun(R) ->
|
lists:map(fun(R) ->
|
||||||
R#vcard.vcard
|
R#vcard.vcard
|
||||||
end, Rs);
|
end, Rs);
|
||||||
{aborted, Reason} ->
|
{aborted, _Reason} ->
|
||||||
[]
|
[]
|
||||||
end,
|
end,
|
||||||
{iq, ID, result, XMLNS, Els}
|
{iq, ID, result, XMLNS, Els}
|
||||||
|
@ -160,7 +160,22 @@ set_vcard(User, VCARD) ->
|
||||||
LOrgName = stringprep:tolower(OrgName),
|
LOrgName = stringprep:tolower(OrgName),
|
||||||
LOrgUnit = stringprep:tolower(OrgUnit),
|
LOrgUnit = stringprep:tolower(OrgUnit),
|
||||||
|
|
||||||
F = fun() ->
|
if
|
||||||
|
(LUser == error) or
|
||||||
|
(LFN == error) or
|
||||||
|
(LFamily == error) or
|
||||||
|
(LGiven == error) or
|
||||||
|
(LMiddle == error) or
|
||||||
|
(LNickname == error) or
|
||||||
|
(LBDay == error) or
|
||||||
|
(LCTRY == error) or
|
||||||
|
(LLocality == error) or
|
||||||
|
(LEMail == error) or
|
||||||
|
(LOrgName == error) or
|
||||||
|
(LOrgUnit == error) ->
|
||||||
|
{error, badarg};
|
||||||
|
true ->
|
||||||
|
F = fun() ->
|
||||||
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
||||||
mnesia:write(
|
mnesia:write(
|
||||||
#vcard_search{user = User, luser = LUser,
|
#vcard_search{user = User, luser = LUser,
|
||||||
|
@ -176,8 +191,9 @@ set_vcard(User, VCARD) ->
|
||||||
orgname = OrgName, lorgname = LOrgName,
|
orgname = OrgName, lorgname = LOrgName,
|
||||||
orgunit = OrgUnit, lorgunit = LOrgUnit
|
orgunit = OrgUnit, lorgunit = LOrgUnit
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F)
|
||||||
|
end.
|
||||||
|
|
||||||
-define(TLFIELD(Type, Label, Var),
|
-define(TLFIELD(Type, Label, Var),
|
||||||
{xmlelement, "field", [{"type", Type},
|
{xmlelement, "field", [{"type", Type},
|
||||||
|
@ -310,7 +326,7 @@ do_route(From, To, Packet) ->
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
find_xdata_el({xmlelement, Name, Attrs, SubEls}) ->
|
find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
|
||||||
find_xdata_el1(SubEls).
|
find_xdata_el1(SubEls).
|
||||||
|
|
||||||
find_xdata_el1([]) ->
|
find_xdata_el1([]) ->
|
||||||
|
@ -454,20 +470,36 @@ set_vcard_t(R, _) ->
|
||||||
LOrgName = stringprep:tolower(OrgName),
|
LOrgName = stringprep:tolower(OrgName),
|
||||||
LOrgUnit = stringprep:tolower(OrgUnit),
|
LOrgUnit = stringprep:tolower(OrgUnit),
|
||||||
|
|
||||||
mnesia:write(
|
if
|
||||||
#vcard_search{user = User, luser = LUser,
|
(LUser == error) or
|
||||||
fn = FN, lfn = LFN,
|
(LFN == error) or
|
||||||
family = Family, lfamily = LFamily,
|
(LFamily == error) or
|
||||||
given = Given, lgiven = LGiven,
|
(LGiven == error) or
|
||||||
middle = Middle, lmiddle = LMiddle,
|
(LMiddle == error) or
|
||||||
nickname = Nickname, lnickname = LNickname,
|
(LNickname == error) or
|
||||||
bday = BDay, lbday = LBDay,
|
(LBDay == error) or
|
||||||
ctry = CTRY, lctry = LCTRY,
|
(LCTRY == error) or
|
||||||
locality = Locality, llocality = LLocality,
|
(LLocality == error) or
|
||||||
email = EMail, lemail = LEMail,
|
(LEMail == error) or
|
||||||
orgname = OrgName, lorgname = LOrgName,
|
(LOrgName == error) or
|
||||||
orgunit = OrgUnit, lorgunit = LOrgUnit
|
(LOrgUnit == error) ->
|
||||||
}).
|
{error, badarg};
|
||||||
|
true ->
|
||||||
|
mnesia:write(
|
||||||
|
#vcard_search{user = User, luser = LUser,
|
||||||
|
fn = FN, lfn = LFN,
|
||||||
|
family = Family, lfamily = LFamily,
|
||||||
|
given = Given, lgiven = LGiven,
|
||||||
|
middle = Middle, lmiddle = LMiddle,
|
||||||
|
nickname = Nickname, lnickname = LNickname,
|
||||||
|
bday = BDay, lbday = LBDay,
|
||||||
|
ctry = CTRY, lctry = LCTRY,
|
||||||
|
locality = Locality, llocality = LLocality,
|
||||||
|
email = EMail, lemail = LEMail,
|
||||||
|
orgname = OrgName, lorgname = LOrgName,
|
||||||
|
orgunit = OrgUnit, lorgunit = LOrgUnit
|
||||||
|
})
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
reindex_vcards() ->
|
reindex_vcards() ->
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
-export([start/1, init/1, send_text/2]).
|
-export([start/1, init/1, send_text/2]).
|
||||||
|
|
||||||
|
-define(XML_START, 0).
|
||||||
|
-define(XML_END, 1).
|
||||||
|
-define(XML_CDATA, 2).
|
||||||
|
-define(XML_ERROR, 3).
|
||||||
|
|
||||||
start(CallbackPid) ->
|
start(CallbackPid) ->
|
||||||
spawn(?MODULE, init, [CallbackPid]).
|
spawn(?MODULE, init, [CallbackPid]).
|
||||||
|
|
||||||
|
@ -22,24 +27,23 @@ init(CallbackPid) ->
|
||||||
loop(CallbackPid, Port, Stack) ->
|
loop(CallbackPid, Port, Stack) ->
|
||||||
receive
|
receive
|
||||||
{Port, {data, Bin}} ->
|
{Port, {data, Bin}} ->
|
||||||
%CallbackPid ! binary_to_term(Bin),
|
|
||||||
Data = binary_to_term(Bin),
|
Data = binary_to_term(Bin),
|
||||||
loop(CallbackPid, Port, process_data(CallbackPid, Stack, Data));
|
loop(CallbackPid, Port, process_data(CallbackPid, Stack, Data));
|
||||||
{From, {send, Str}} ->
|
{_From, {send, Str}} ->
|
||||||
Port ! {self(), {command, Str}},
|
Port ! {self(), {command, Str}},
|
||||||
loop(CallbackPid, Port, Stack)
|
loop(CallbackPid, Port, Stack)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
process_data(CallbackPid, Stack, Data) ->
|
process_data(CallbackPid, Stack, Data) ->
|
||||||
case Data of
|
case Data of
|
||||||
{xmlstart, {Name, Attrs}} ->
|
{?XML_START, {Name, Attrs}} ->
|
||||||
if Stack == [] ->
|
if Stack == [] ->
|
||||||
gen_fsm:send_event(CallbackPid,
|
gen_fsm:send_event(CallbackPid,
|
||||||
{xmlstreamstart, Name, Attrs});
|
{xmlstreamstart, Name, Attrs});
|
||||||
true -> true
|
true -> true
|
||||||
end,
|
end,
|
||||||
[{xmlelement, Name, Attrs, []} | Stack];
|
[{xmlelement, Name, Attrs, []} | Stack];
|
||||||
{xmlend, EndName} ->
|
{?XML_END, EndName} ->
|
||||||
case Stack of
|
case Stack of
|
||||||
[{xmlelement, Name, Attrs, Els} | Tail] ->
|
[{xmlelement, Name, Attrs, Els} | Tail] ->
|
||||||
NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
|
NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
|
||||||
|
@ -56,10 +60,10 @@ process_data(CallbackPid, Stack, Data) ->
|
||||||
Tail
|
Tail
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
{xmlcdata, CData} ->
|
{?XML_CDATA, CData} ->
|
||||||
add_subelement({xmlcdata, CData}, Stack);
|
add_subelement({xmlcdata, CData}, Stack);
|
||||||
{xmlerror, Err} -> gen_fsm:send_event(CallbackPid,
|
{?XML_ERROR, Err} -> gen_fsm:send_event(CallbackPid,
|
||||||
{xmlstreamerror, Err})
|
{xmlstreamerror, Err})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue