mirror of
https://github.com/processone/ejabberd.git
synced 2024-10-05 14:51:05 +02:00
* src/expat_erl.c: Now uses port control instead of port output
* src/xml_stream.erl: Likewise * src/stringprep/stringprep.erl: Now register port instead of storing it in ets table * doc/guide.tex: Updated URLs to R10C release SVN Revision: 287
This commit is contained in:
parent
3d1ff452cb
commit
fb977729a9
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2004-12-01 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/expat_erl.c: Now uses port control instead of port output
|
||||
* src/xml_stream.erl: Likewise
|
||||
|
||||
2004-11-30 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/stringprep/stringprep.erl: Now register port instead of
|
||||
storing it in ets table
|
||||
|
||||
2004-11-28 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* doc/guide.tex: Updated URLs to R10C release
|
||||
|
||||
2004-11-20 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/mod_vcard.erl: Added missed index
|
||||
|
@ -179,7 +179,7 @@ To compile <TT>ejabberd</TT> in MS Windows environment, you will need the follow
|
||||
packages:
|
||||
<UL><LI>
|
||||
MS Visual C++ 6.0 Compiler
|
||||
<LI><A HREF="http://www.erlang.org/download/otp_win32_R9C-0.exe">Erlang/OTP R9C-0</A>
|
||||
<LI><A HREF="http://erlang.org/download/otp_win32_R10B-1a.exe">Erlang/OTP R10B-1a</A>
|
||||
<LI><A HREF="http://prdownloads.sourceforge.net/expat/expat_win32bin_1_95_7.exe?download">Expat 1.95.7</A>
|
||||
<LI><A HREF="http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.9.1.tar.gz">Iconv 1.9.1</A>
|
||||
(optional)
|
||||
@ -410,7 +410,8 @@ The following ACLs pre-defined:
|
||||
<B><TT>all</TT></B><DD> Matches all JIDs.
|
||||
<DT><B><TT>none</TT></B><DD> Matches none JIDs.
|
||||
</DL>
|
||||
An entry allowing or denying different services would look similar to this:
|
||||
An entry allowing or denying access to different services would look similar to
|
||||
this:
|
||||
<PRE>
|
||||
{access, <accessname>, [{allow, <aclname>},
|
||||
{deny, <aclname>},
|
||||
@ -811,7 +812,7 @@ Replicating of table makes lookup in this table faster on this node,
|
||||
replicas is down, other replicas will be used.<BR>
|
||||
<BR>
|
||||
Also section ``5.3 Table Fragmentation''
|
||||
<A HREF="http://erlang.org/doc/r9c/lib/mnesia-4.1.4/doc/html/part_frame.html">here</A>
|
||||
<A HREF="http://www.erlang.se/doc/doc-5.4/lib/mnesia-4.2/doc/html/index.html">here</A>
|
||||
can be useful.<BR>
|
||||
<BR>
|
||||
(alt) Same as in previous item, but for other tables.<BR>
|
||||
|
@ -157,7 +157,7 @@ To compile \ejabberd{} in MS Windows environment, you will need the following
|
||||
packages:
|
||||
\begin{itemize}
|
||||
\item MS Visual C++ 6.0 Compiler
|
||||
\item \footahref{http://www.erlang.org/download/otp\_win32\_R9C-0.exe}{Erlang/OTP R9C-0}
|
||||
\item \footahref{http://erlang.org/download/otp_win32_R10B-1a.exe}{Erlang/OTP R10B-1a}
|
||||
\item \footahref{http://prdownloads.sourceforge.net/expat/expat\_win32bin\_1\_95\_7.exe?download}{Expat 1.95.7}
|
||||
\item
|
||||
\footahref{http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.9.1.tar.gz}{Iconv 1.9.1}
|
||||
@ -406,7 +406,8 @@ The following ACLs pre-defined:
|
||||
\titem{none} Matches none JIDs.
|
||||
\end{description}
|
||||
|
||||
An entry allowing or denying different services would look similar to this:
|
||||
An entry allowing or denying access to different services would look similar to
|
||||
this:
|
||||
\begin{verbatim}
|
||||
{access, <accessname>, [{allow, <aclname>},
|
||||
{deny, <aclname>},
|
||||
@ -813,7 +814,7 @@ mnesia:change_table_copy_type(schema, node(), disc_copies).
|
||||
replicas is down, other replicas will be used.
|
||||
|
||||
Also section ``5.3 Table Fragmentation''
|
||||
\footahref{http://erlang.org/doc/r9c/lib/mnesia-4.1.4/doc/html/part_frame.html}{here}
|
||||
\footahref{http://www.erlang.se/doc/doc-5.4/lib/mnesia-4.2/doc/html/index.html}{here}
|
||||
can be useful.
|
||||
|
||||
(alt) Same as in previous item, but for other tables.
|
||||
|
148
src/expat_erl.c
148
src/expat_erl.c
@ -106,6 +106,9 @@ int ei_x_encode_string_fixed(ei_x_buff* x, const char* s)
|
||||
#define XML_CDATA 2
|
||||
#define XML_ERROR 3
|
||||
|
||||
#define PARSE_COMMAND 0
|
||||
|
||||
ei_x_buff event_buf;
|
||||
|
||||
typedef struct {
|
||||
ErlDrvPort port;
|
||||
@ -117,44 +120,39 @@ void *erlXML_StartElementHandler(expat_data *d,
|
||||
const XML_Char **atts)
|
||||
{
|
||||
int i;
|
||||
ei_x_buff buf;
|
||||
|
||||
ei_x_new_with_version(&buf);
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_long(&buf, XML_START);
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_string_fixed(&buf, name);
|
||||
|
||||
|
||||
ei_x_encode_list_header(&event_buf, 1);
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_long(&event_buf, XML_START);
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_string_fixed(&event_buf, name);
|
||||
|
||||
for (i = 0; atts[i]; i += 2) {}
|
||||
|
||||
ei_x_encode_list_header(&buf, i/2);
|
||||
|
||||
for (i = 0; atts[i]; i += 2)
|
||||
if (i > 0)
|
||||
{
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_string_fixed(&buf, atts[i]);
|
||||
ei_x_encode_string_fixed(&buf, atts[i+1]);
|
||||
ei_x_encode_list_header(&event_buf, i/2);
|
||||
|
||||
for (i = 0; atts[i]; i += 2)
|
||||
{
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_string_fixed(&event_buf, atts[i]);
|
||||
ei_x_encode_string_fixed(&event_buf, atts[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
ei_x_encode_empty_list(&buf);
|
||||
|
||||
driver_output(d->port, buf.buff, buf.index);
|
||||
ei_x_free(&buf);
|
||||
|
||||
ei_x_encode_empty_list(&event_buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *erlXML_EndElementHandler(expat_data *d,
|
||||
const XML_Char *name)
|
||||
{
|
||||
ei_x_buff buf;
|
||||
|
||||
ei_x_new_with_version(&buf);
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_long(&buf, XML_END);
|
||||
ei_x_encode_string_fixed(&buf, name);
|
||||
|
||||
driver_output(d->port, buf.buff, buf.index);
|
||||
ei_x_free(&buf);
|
||||
ei_x_encode_list_header(&event_buf, 1);
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_long(&event_buf, XML_END);
|
||||
ei_x_encode_string_fixed(&event_buf, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -162,15 +160,10 @@ void *erlXML_CharacterDataHandler(expat_data *d,
|
||||
const XML_Char *s,
|
||||
int len)
|
||||
{
|
||||
ei_x_buff buf;
|
||||
|
||||
ei_x_new_with_version(&buf);
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_long(&buf, XML_CDATA);
|
||||
ei_x_encode_string_len_fixed(&buf, s, len);
|
||||
|
||||
driver_output(d->port, buf.buff, buf.index);
|
||||
ei_x_free(&buf);
|
||||
ei_x_encode_list_header(&event_buf, 1);
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_long(&event_buf, XML_CDATA);
|
||||
ei_x_encode_string_len_fixed(&event_buf, s, len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -182,6 +175,8 @@ static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
|
||||
d->parser = XML_ParserCreate("UTF-8");
|
||||
XML_SetUserData(d->parser, d);
|
||||
|
||||
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
|
||||
|
||||
XML_SetStartElementHandler(
|
||||
d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
|
||||
XML_SetEndElementHandler(
|
||||
@ -199,48 +194,65 @@ static void expat_erl_stop(ErlDrvData handle)
|
||||
driver_free((char*)handle);
|
||||
}
|
||||
|
||||
static void expat_erl_output(ErlDrvData handle, char *buff, int bufflen)
|
||||
static int expat_erl_control(ErlDrvData drv_data,
|
||||
unsigned int command,
|
||||
char *buf, int len,
|
||||
char **rbuf, int rlen)
|
||||
{
|
||||
expat_data* d = (expat_data*)handle;
|
||||
expat_data* d = (expat_data*)drv_data;
|
||||
int res, errcode;
|
||||
char *errstring;
|
||||
ei_x_buff buf;
|
||||
ErlDrvBinary *b;
|
||||
size_t size;
|
||||
|
||||
res = XML_Parse(d->parser, buff, bufflen, 0);
|
||||
|
||||
if(!res)
|
||||
switch (command)
|
||||
{
|
||||
errcode = XML_GetErrorCode(d->parser);
|
||||
errstring = (char *)XML_ErrorString(errcode);
|
||||
case PARSE_COMMAND:
|
||||
ei_x_new_with_version(&event_buf);
|
||||
res = XML_Parse(d->parser, buf, len, 0);
|
||||
|
||||
ei_x_new_with_version(&buf);
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_long(&buf, XML_ERROR);
|
||||
ei_x_encode_tuple_header(&buf, 2);
|
||||
ei_x_encode_long(&buf, errcode);
|
||||
ei_x_encode_string_fixed(&buf, errstring);
|
||||
if(!res)
|
||||
{
|
||||
errcode = XML_GetErrorCode(d->parser);
|
||||
errstring = (char *)XML_ErrorString(errcode);
|
||||
|
||||
driver_output(d->port, buf.buff, buf.index);
|
||||
ei_x_free(&buf);
|
||||
ei_x_encode_list_header(&event_buf, 1);
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_long(&event_buf, XML_ERROR);
|
||||
ei_x_encode_tuple_header(&event_buf, 2);
|
||||
ei_x_encode_long(&event_buf, errcode);
|
||||
ei_x_encode_string_fixed(&event_buf, errstring);
|
||||
}
|
||||
|
||||
ei_x_encode_empty_list(&event_buf);
|
||||
|
||||
size = event_buf.index;
|
||||
|
||||
b = driver_alloc_binary(size);
|
||||
memcpy(b->orig_bytes, event_buf.buff, size);
|
||||
|
||||
ei_x_free(&event_buf);
|
||||
|
||||
*rbuf = (char *)b;
|
||||
return size;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
//driver_output(d->port, &res, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ErlDrvEntry expat_driver_entry = {
|
||||
NULL, /* F_PTR init, N/A */
|
||||
expat_erl_start, /* L_PTR start, called when port is opened */
|
||||
expat_erl_stop, /* F_PTR stop, called when port is closed */
|
||||
expat_erl_output, /* 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 */
|
||||
"expat_erl", /* char *driver_name, the argument to open_port */
|
||||
NULL, /* F_PTR finish, called when unloaded */
|
||||
NULL, /* F_PTR control, port_command callback */
|
||||
NULL, /* F_PTR timeout, reserved */
|
||||
NULL /* F_PTR outputv, reserved */
|
||||
NULL, /* F_PTR init, N/A */
|
||||
expat_erl_start, /* L_PTR start, called when port is opened */
|
||||
expat_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 */
|
||||
"expat_erl", /* char *driver_name, the argument to open_port */
|
||||
NULL, /* F_PTR finish, called when unloaded */
|
||||
NULL, /* handle */
|
||||
expat_erl_control, /* F_PTR control, port_command callback */
|
||||
NULL, /* F_PTR timeout, reserved */
|
||||
NULL /* F_PTR outputv, reserved */
|
||||
};
|
||||
|
||||
DRIVER_INIT(expat_erl) /* must match name in driver_entry */
|
||||
|
@ -26,6 +26,8 @@
|
||||
code_change/3,
|
||||
terminate/2]).
|
||||
|
||||
-define(STRINGPREP_PORT, stringprep_port).
|
||||
|
||||
-define(NAMEPREP_COMMAND, 1).
|
||||
-define(NODEPREP_COMMAND, 2).
|
||||
-define(RESOURCEPREP_COMMAND, 3).
|
||||
@ -39,8 +41,7 @@ start_link() ->
|
||||
init([]) ->
|
||||
ok = erl_ddll:load_driver(ejabberd:get_so_path(), stringprep_drv),
|
||||
Port = open_port({spawn, stringprep_drv}, []),
|
||||
ets:new(stringprep_table, [set, public, named_table]),
|
||||
ets:insert(stringprep_table, {port, Port}),
|
||||
register(?STRINGPREP_PORT, Port),
|
||||
{ok, Port}.
|
||||
|
||||
|
||||
@ -84,8 +85,7 @@ resourceprep(String) ->
|
||||
control(?RESOURCEPREP_COMMAND, String).
|
||||
|
||||
control(Command, String) ->
|
||||
[{port, Port} | _] = ets:lookup(stringprep_table, port),
|
||||
case port_control(Port, Command, String) of
|
||||
case port_control(?STRINGPREP_PORT, Command, String) of
|
||||
[0 | _] -> error;
|
||||
[1 | Res] -> Res
|
||||
end.
|
||||
|
@ -17,6 +17,8 @@
|
||||
-define(XML_CDATA, 2).
|
||||
-define(XML_ERROR, 3).
|
||||
|
||||
-define(PARSE_COMMAND, 0).
|
||||
|
||||
start(CallbackPid) ->
|
||||
spawn(?MODULE, init, [CallbackPid]).
|
||||
|
||||
@ -38,8 +40,12 @@ loop(CallbackPid, Port, Stack) ->
|
||||
Data = binary_to_term(Bin),
|
||||
loop(CallbackPid, Port, process_data(CallbackPid, Stack, Data));
|
||||
{_From, {send, Str}} ->
|
||||
Port ! {self(), {command, Str}},
|
||||
loop(CallbackPid, Port, Stack);
|
||||
Res = port_control(Port, ?PARSE_COMMAND, Str),
|
||||
NewStack = lists:foldl(
|
||||
fun(Data, St) ->
|
||||
process_data(CallbackPid, St, Data)
|
||||
end, Stack, binary_to_term(Res)),
|
||||
loop(CallbackPid, Port, NewStack);
|
||||
{'DOWN', _Ref, _Type, _Object, _Info} ->
|
||||
ok
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user