25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00

Store registered nicknames, rooms and domains as binary().

Use document_to_iolist/1 and iolist_size/1 instead of document_to_list/1.

SVN Revision: 1820
This commit is contained in:
Pablo Polvorin 2009-01-15 15:21:54 +00:00
parent e8f630b93a
commit 2538001b08
3 changed files with 58 additions and 46 deletions

View File

@ -1,3 +1,10 @@
2009-01-15 Pablo Polvorin <pablo.polvorin@process-one.net>
* src/mod_muc/mod_muc.erl, src/mod_muc/mod_muc_room.erl:
Store registered nicknames, rooms and domains as binary().
Use document_to_iolist/1 and iolist_size/1 instead of
document_to_list/1.
2009-01-11 Pablo Polvorin <pablo.polvorin@process-one.net> 2009-01-11 Pablo Polvorin <pablo.polvorin@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: Fix typo, initial update * src/mod_pubsub/mod_pubsub.erl: Fix typo, initial update

View File

@ -125,7 +125,7 @@ forget_room(Host, Name) when is_binary(Host), is_binary(Name) ->
end, end,
mnesia:transaction(F). mnesia:transaction(F).
process_iq_disco_items(Host, From, To, #iq{} = IQ) -> process_iq_disco_items(Host, From, To, #iq{} = IQ) when is_binary(Host) ->
Lang = exmpp_stanza:get_lang(IQ), Lang = exmpp_stanza:get_lang(IQ),
Res = exmpp_iq:result(IQ, #xmlel{ns = ?NS_DISCO_ITEMS, Res = exmpp_iq:result(IQ, #xmlel{ns = ?NS_DISCO_ITEMS,
name = 'query', name = 'query',
@ -134,10 +134,10 @@ process_iq_disco_items(Host, From, To, #iq{} = IQ) ->
From, From,
exmpp_iq:iq_to_xmlel(Res)). exmpp_iq:iq_to_xmlel(Res)).
can_use_nick(_Host, _JID, "") -> can_use_nick(_Host, _JID, <<>>) ->
false; false;
can_use_nick(Host, JID, Nick) -> can_use_nick(Host, JID, Nick) when is_binary(Host), is_binary(Nick) ->
LUS = {exmpp_jid:lnode_as_list(JID), exmpp_jid:ldomain_as_list(JID)}, LUS = {exmpp_jid:lnode(JID), exmpp_jid:ldomain(JID)},
case catch mnesia:dirty_select( case catch mnesia:dirty_select(
muc_registered, muc_registered,
[{#muc_registered{us_host = '$1', [{#muc_registered{us_host = '$1',
@ -176,7 +176,8 @@ init([Host, Opts]) ->
{attributes, record_info(fields, muc_online_room)}]), {attributes, record_info(fields, muc_online_room)}]),
mnesia:add_table_copy(muc_online_room, node(), ram_copies), mnesia:add_table_copy(muc_online_room, node(), ram_copies),
catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]), catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]),
MyHost = gen_mod:get_opt_host(Host, Opts, "conference.@HOST@"), MyHost_L = gen_mod:get_opt_host(Host, Opts, "conference.@HOST@"),
MyHost = list_to_binary(MyHost_L),
update_tables(MyHost), update_tables(MyHost),
clean_table_from_bad_node(node(), MyHost), clean_table_from_bad_node(node(), MyHost),
mnesia:add_table_index(muc_registered, nick), mnesia:add_table_index(muc_registered, nick),
@ -188,7 +189,7 @@ init([Host, Opts]) ->
HistorySize = gen_mod:get_opt(history_size, Opts, 20), HistorySize = gen_mod:get_opt(history_size, Opts, 20),
DefRoomOpts = gen_mod:get_opt(default_room_options, Opts, []), DefRoomOpts = gen_mod:get_opt(default_room_options, Opts, []),
RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), RoomShaper = gen_mod:get_opt(room_shaper, Opts, none),
ejabberd_router:register_route(MyHost), ejabberd_router:register_route(MyHost_L),
load_permanent_rooms(MyHost, Host, load_permanent_rooms(MyHost, Host,
{Access, AccessCreate, AccessAdmin, AccessPersistent}, {Access, AccessCreate, AccessAdmin, AccessPersistent},
HistorySize, HistorySize,
@ -313,8 +314,8 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
From, To, Packet, DefRoomOpts) -> From, To, Packet, DefRoomOpts) ->
{_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access, {_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access,
Room = exmpp_jid:lnode_as_list(To), Room = exmpp_jid:lnode(To),
Nick = exmpp_jid:lresource_as_list(To), Nick = exmpp_jid:lresource(To),
#xmlel{name = Name} = Packet, #xmlel{name = Name} = Packet,
case Room of case Room of
'undefined' -> 'undefined' ->
@ -484,7 +485,7 @@ load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) ->
end, Rs) end, Rs)
end. end.
register_room(Host, Room, Pid) -> register_room(Host, Room, Pid) when is_binary(Host), is_binary(Room) ->
F = fun() -> F = fun() ->
mnesia:write(#muc_online_room{name_host = {Room, Host}, mnesia:write(#muc_online_room{name_host = {Room, Host},
pid = Pid}) pid = Pid})
@ -518,7 +519,7 @@ iq_disco_info(Lang) ->
iq_disco_items(Host, From, Lang) -> iq_disco_items(Host, From, Lang) when is_binary(Host) ->
lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) ->
case catch gen_fsm:sync_send_all_state_event( case catch gen_fsm:sync_send_all_state_event(
Pid, {get_disco_item, From, Lang}, 100) of Pid, {get_disco_item, From, Lang}, 100) of
@ -527,9 +528,9 @@ iq_disco_items(Host, From, Lang) ->
{true, {true,
#xmlel{name = 'item', #xmlel{name = 'item',
attrs = [#xmlattr{name = 'jid', attrs = [#xmlattr{name = 'jid',
value = exmpp_jid:jid_to_list(Name, value = exmpp_jid:jid_to_binary(Name,
Host, Host,
"")}, <<>>)},
#xmlattr{name = 'name', #xmlattr{name = 'name',
value = Desc}]}}; value = Desc}]}};
_ -> _ ->
@ -554,9 +555,9 @@ flush() ->
children = [#xmlel{name = 'value', children = [#xmlel{name = 'value',
children = [#xmlcdata{cdata = Val}]}]}). children = [#xmlcdata{cdata = Val}]}]}).
iq_get_register_info(Host, From, Lang) -> iq_get_register_info(Host, From, Lang) ->
LUser = exmpp_jid:lnode_as_list(From), LUser = exmpp_jid:lnode(From),
LServer = exmpp_jid:ldomain_as_list(From), LServer = exmpp_jid:ldomain(From),
LUS = {LUser, LServer}, LUS = {LUser, LServer},
{Nick, Registered} = {Nick, Registered} =
case catch mnesia:dirty_read(muc_registered, {LUS, Host}) of case catch mnesia:dirty_read(muc_registered, {LUS, Host}) of
@ -576,21 +577,21 @@ iq_get_register_info(Host, From, Lang) ->
children = [ children = [
#xmlel{ns = ?NS_DATA_FORMS, name = 'title', #xmlel{ns = ?NS_DATA_FORMS, name = 'title',
children = [#xmlcdata{cdata = children = [#xmlcdata{cdata =
translate:translate(Lang, "Nickname Registration at ") ++ Host}]}, [translate:translate(Lang, "Nickname Registration at "), Host]}]},
#xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions',
children = [#xmlcdata{cdata = children = [#xmlcdata{cdata =
translate:translate(Lang, "Enter nickname you want to register")}]}, translate:translate(Lang, "Enter nickname you want to register")}]},
?XFIELD("text-single", "Nickname", "nick", Nick)]}]. ?XFIELD(<<"text-single">>, "Nickname", <<"nick">>, Nick)]}].
iq_set_register_info(Host, From, Nick, Lang) -> iq_set_register_info(Host, From, Nick, Lang) when is_binary(Host), is_binary(Nick) ->
LUser = exmpp_jid:lnode_as_list(From), LUser = exmpp_jid:lnode(From),
LServer = exmpp_jid:ldomain_as_list(From), LServer = exmpp_jid:ldomain(From),
LUS = {LUser, LServer}, LUS = {LUser, LServer},
F = fun() -> F = fun() ->
case Nick of case Nick of
"" -> <<>> ->
mnesia:delete({muc_registered, {LUS, Host}}), mnesia:delete({muc_registered, {LUS, Host}}),
ok; ok;
_ -> _ ->
@ -654,7 +655,7 @@ process_iq_register_set(Host, From, SubEl, Lang) ->
{Lang, translate:translate(Lang,ErrText)}), {Lang, translate:translate(Lang,ErrText)}),
{error, Err}; {error, Err};
{value, {_, [Nick]}} -> {value, {_, [Nick]}} ->
iq_set_register_info(Host, From, Nick, Lang) iq_set_register_info(Host, From, list_to_binary(Nick), Lang)
end end
end; end;
_ -> _ ->
@ -664,7 +665,7 @@ process_iq_register_set(Host, From, SubEl, Lang) ->
{error, 'bad-request'} {error, 'bad-request'}
end; end;
_ -> _ ->
iq_set_register_info(Host, From, "", Lang) iq_set_register_info(Host, From, <<>>, Lang)
end. end.
iq_get_vcard(Lang) -> iq_get_vcard(Lang) ->
@ -687,7 +688,7 @@ broadcast_service_message(Host, Msg) ->
Pid, {service_message, Msg}) Pid, {service_message, Msg})
end, get_vh_rooms(Host)). end, get_vh_rooms(Host)).
get_vh_rooms(Host) -> get_vh_rooms(Host) when is_binary(Host) ->
mnesia:dirty_select(muc_online_room, mnesia:dirty_select(muc_online_room,
[{#muc_online_room{name_host = '$1', _ = '_'}, [{#muc_online_room{name_host = '$1', _ = '_'},
[{'==', {element, 2, '$1'}, Host}], [{'==', {element, 2, '$1'}, Host}],

View File

@ -117,7 +117,9 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts) ->
%% ignore | %% ignore |
%% {stop, StopReason} %% {stop, StopReason}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts]) -> init([HostB, ServerHost, Access, RoomB, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts]) ->
Host = binary_to_list(HostB),
Room = binary_to_list(RoomB),
process_flag(trap_exit, true), process_flag(trap_exit, true),
Shaper = shaper:new(RoomShaper), Shaper = shaper:new(RoomShaper),
State = set_affiliation(Creator, owner, State = set_affiliation(Creator, owner,
@ -133,7 +135,9 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, D
?INFO_MSG("Created MUC room ~s@~s by ~s", ?INFO_MSG("Created MUC room ~s@~s by ~s",
[Room, Host, exmpp_jid:jid_to_list(Creator)]), [Room, Host, exmpp_jid:jid_to_list(Creator)]),
{ok, normal_state, State1}; {ok, normal_state, State1};
init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts]) -> init([HostB, ServerHost, Access, RoomB, HistorySize, RoomShaper, Opts]) ->
Host = binary_to_list(HostB),
Room = binary_to_list(RoomB),
process_flag(trap_exit, true), process_flag(trap_exit, true),
Shaper = shaper:new(RoomShaper), Shaper = shaper:new(RoomShaper),
State = set_opts(Opts, #state{host = Host, State = set_opts(Opts, #state{host = Host,
@ -166,7 +170,7 @@ normal_state({route, From, undefined,
trunc(gen_mod:get_module_opt( trunc(gen_mod:get_module_opt(
StateData#state.server_host, StateData#state.server_host,
mod_muc, min_message_interval, 0) * 1000000), mod_muc, min_message_interval, 0) * 1000000),
Size = lists:flatlength(exmpp_xml:document_to_list(Packet)), Size = erlang:iolist_size(exmpp_xml:document_to_binary(Packet)),
{MessageShaper, MessageShaperInterval} = {MessageShaper, MessageShaperInterval} =
shaper:update(Activity#activity.message_shaper, Size), shaper:update(Activity#activity.message_shaper, Size),
if if
@ -720,7 +724,7 @@ terminate(_Reason, _StateName, StateData) ->
fun(J, _, _) -> fun(J, _, _) ->
tab_remove_online_user(J, StateData) tab_remove_online_user(J, StateData)
end, [], StateData#state.users), end, [], StateData#state.users),
mod_muc:room_destroyed(StateData#state.host, StateData#state.room, self(), mod_muc:room_destroyed(list_to_binary(StateData#state.host), list_to_binary(StateData#state.room), self(),
StateData#state.server_host), StateData#state.server_host),
ok. ok.
@ -892,7 +896,7 @@ process_presence(From, Nick, #xmlel{name = 'presence'} = Packet,
true -> true ->
case {is_nick_exists(Nick, StateData), case {is_nick_exists(Nick, StateData),
mod_muc:can_use_nick( mod_muc:can_use_nick(
StateData#state.host, From, Nick), list_to_binary(StateData#state.host), From, Nick),
{(StateData#state.config)#config.allow_visitor_nickchange, {(StateData#state.config)#config.allow_visitor_nickchange,
is_visitor(From, StateData)}} of is_visitor(From, StateData)}} of
{_, _, {false, true}} -> {_, _, {false, true}} ->
@ -1323,7 +1327,7 @@ prepare_room_queue(StateData) ->
{{value, {message, From}}, _RoomQueue} -> {{value, {message, From}}, _RoomQueue} ->
Activity = get_user_activity(From, StateData), Activity = get_user_activity(From, StateData),
Packet = Activity#activity.message, Packet = Activity#activity.message,
Size = lists:flatlength(exmpp_xml:documenent_to_list(Packet)), Size = erlang:iolist_size(exmpp_xml:documenent_to_iolist(Packet)),
{RoomShaper, RoomShaperInterval} = {RoomShaper, RoomShaperInterval} =
shaper:update(StateData#state.room_shaper, Size), shaper:update(StateData#state.room_shaper, Size),
erlang:send_after( erlang:send_after(
@ -1334,7 +1338,7 @@ prepare_room_queue(StateData) ->
{{value, {presence, From}}, _RoomQueue} -> {{value, {presence, From}}, _RoomQueue} ->
Activity = get_user_activity(From, StateData), Activity = get_user_activity(From, StateData),
{_Nick, Packet} = Activity#activity.presence, {_Nick, Packet} = Activity#activity.presence,
Size = lists:flatlength(exmpp_xml:document_to_list(Packet)), Size = erlang:iolist_size(exmpp_xml:document_to_iolist(Packet)),
{RoomShaper, RoomShaperInterval} = {RoomShaper, RoomShaperInterval} =
shaper:update(StateData#state.room_shaper, Size), shaper:update(StateData#state.room_shaper, Size),
erlang:send_after( erlang:send_after(
@ -1461,7 +1465,7 @@ add_new_user(From, Nick, Packet, StateData) ->
NUsers < MaxUsers) andalso NUsers < MaxUsers) andalso
NConferences < MaxConferences, NConferences < MaxConferences,
is_nick_exists(Nick, StateData), is_nick_exists(Nick, StateData),
mod_muc:can_use_nick(StateData#state.host, From, Nick), mod_muc:can_use_nick(list_to_binary(StateData#state.host), From, Nick),
get_default_role(Affiliation, StateData)} of get_default_role(Affiliation, StateData)} of
{false, _, _, _} -> {false, _, _, _} ->
% max user reached and user is not admin or owner % max user reached and user is not admin or owner
@ -1766,7 +1770,7 @@ send_new_presence(NJID, Reason, StateData) ->
case (Info#user.role == moderator) orelse case (Info#user.role == moderator) orelse
((StateData#state.config)#config.anonymous == false) of ((StateData#state.config)#config.anonymous == false) of
true -> true ->
[#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(RealJID)}, [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_binary(RealJID)},
#xmlattr{name = 'affiliation', value = SAffiliation}, #xmlattr{name = 'affiliation', value = SAffiliation},
#xmlattr{name = 'role', value = SRole}]; #xmlattr{name = 'role', value = SRole}];
_ -> _ ->
@ -1822,7 +1826,7 @@ send_existing_presences(ToJID, StateData) ->
((StateData#state.config)#config.anonymous == ((StateData#state.config)#config.anonymous ==
false) of false) of
true -> true ->
[#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(FromJID)}, [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_binary(FromJID)},
#xmlattr{name = 'affiliation', #xmlattr{name = 'affiliation',
value = affiliation_to_binary(FromAffiliation)}, value = affiliation_to_binary(FromAffiliation)},
#xmlattr{name = 'role', value = role_to_binary(FromRole)}]; #xmlattr{name = 'role', value = role_to_binary(FromRole)}];
@ -1879,7 +1883,7 @@ send_nick_changing(JID, OldNick, StateData) ->
case (Info#user.role == moderator) orelse case (Info#user.role == moderator) orelse
((StateData#state.config)#config.anonymous == false) of ((StateData#state.config)#config.anonymous == false) of
true -> true ->
[#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(RealJID)}, [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_binary(RealJID)},
#xmlattr{name = 'affiliation', value = SAffiliation}, #xmlattr{name = 'affiliation', value = SAffiliation},
#xmlattr{name = 'role', value = SRole}, #xmlattr{name = 'role', value = SRole},
#xmlattr{name = 'nick', value = Nick}]; #xmlattr{name = 'nick', value = Nick}];
@ -1892,7 +1896,7 @@ send_nick_changing(JID, OldNick, StateData) ->
case (Info#user.role == moderator) orelse case (Info#user.role == moderator) orelse
((StateData#state.config)#config.anonymous == false) of ((StateData#state.config)#config.anonymous == false) of
true -> true ->
[#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(RealJID)}, [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_binary(RealJID)},
#xmlattr{name = 'affiliation', value = SAffiliation}, #xmlattr{name = 'affiliation', value = SAffiliation},
#xmlattr{name = 'role', value = SRole}]; #xmlattr{name = 'role', value = SRole}];
_ -> _ ->
@ -1902,7 +1906,7 @@ send_nick_changing(JID, OldNick, StateData) ->
Packet1 = Packet1 =
#xmlel{ns = ?NS_JABBER_CLIENT, #xmlel{ns = ?NS_JABBER_CLIENT,
name = 'presence', name = 'presence',
attrs = [#xmlattr{name = 'type', value = "unavailable"}], attrs = [#xmlattr{name = 'type', value = <<"unavailable">>}],
children = [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = [#xmlel{ns = ?NS_MUC_USER, name = 'x',
children = [ children = [
#xmlel{ns = ?NS_MUC_USER, name = 'item', #xmlel{ns = ?NS_MUC_USER, name = 'item',
@ -1968,7 +1972,7 @@ add_message_to_history(FromNick, Packet, StateData) ->
jid_replace_resource(StateData#state.jid, FromNick)), jid_replace_resource(StateData#state.jid, FromNick)),
StateData#state.jid), StateData#state.jid),
Size = lists:flatlength(exmpp_xml:document_to_list(SPacket)), Size = erlang:iolist_size(exmpp_xml:document_to_iolist(SPacket)),
Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, TimeStamp, Size}, Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, TimeStamp, Size},
StateData#state.history), StateData#state.history),
add_to_log(text, {FromNick, Packet}, StateData), add_to_log(text, {FromNick, Packet}, StateData),
@ -3183,9 +3187,9 @@ process_iq_disco_items(From, get, _Lang, StateData) ->
fun({_LJID, Info}) -> fun({_LJID, Info}) ->
Nick = Info#user.nick, Nick = Info#user.nick,
#xmlel{name = 'item', attrs = [#xmlattr{name = 'jid', #xmlel{name = 'item', attrs = [#xmlattr{name = 'jid',
value = exmpp_jid:jid_to_list( value = exmpp_jid:jid_to_binary(
StateData#state.room, list_to_binary(StateData#state.room),
StateData#state.host, list_to_binary(StateData#state.host),
Nick)}, Nick)},
#xmlattr{name = 'name', #xmlattr{name = 'name',
value = Nick}]} value = Nick}]}
@ -3254,7 +3258,7 @@ check_invitation(From, Els, Lang, StateData) ->
[#xmlel{ns = ?NS_MUC_USER, [#xmlel{ns = ?NS_MUC_USER,
name = 'invite', name = 'invite',
attrs = [#xmlattr{name = 'from', attrs = [#xmlattr{name = 'from',
value = exmpp_jid:jid_to_list(From)}], value = exmpp_jid:jid_to_binary(From)}],
children = [#xmlel{ns =?NS_MUC_USER, name = 'reason', children = [#xmlel{ns =?NS_MUC_USER, name = 'reason',
children = [#xmlcdata{cdata = Reason} ]}] children = [#xmlcdata{cdata = Reason} ]}]
++ ContinueEl}], ++ ContinueEl}],
@ -3274,8 +3278,8 @@ check_invitation(From, Els, Lang, StateData) ->
io_lib:format( io_lib:format(
translate:translate(Lang, translate:translate(Lang,
"~s invites you to the room ~s"), "~s invites you to the room ~s"),
[exmpp_jid:jid_to_list(From), [exmpp_jid:jid_to_binary(From),
exmpp_jid:jid_to_list(StateData#state.room, exmpp_jid:jid_to_binary(StateData#state.room,
StateData#state.host, StateData#state.host,
"") "")
]), ]),
@ -3301,7 +3305,7 @@ check_invitation(From, Els, Lang, StateData) ->
children = IEl ++ PasswdEl}, children = IEl ++ PasswdEl},
#xmlel{ns = 'jabber:x:conference', name = 'x', #xmlel{ns = 'jabber:x:conference', name = 'x',
attrs = [#xmlattr{name = 'jid', attrs = [#xmlattr{name = 'jid',
value = exmpp_jid:jid_to_list( value = exmpp_jid:jid_to_binary(
StateData#state.room, StateData#state.room,
StateData#state.host, StateData#state.host,
"")}], "")}],
@ -3338,7 +3342,7 @@ check_decline_invitation(Packet) ->
%% The original stanza must be slightly modified. %% The original stanza must be slightly modified.
send_decline_invitation({Packet, XEl, DEl = #xmlel{name='decline'}, ToJID}, send_decline_invitation({Packet, XEl, DEl = #xmlel{name='decline'}, ToJID},
RoomJID, FromJID) -> RoomJID, FromJID) ->
FromString = exmpp_jid:jid_to_list(FromJID), FromString = exmpp_jid:jid_to_binary(FromJID),
DEl1 = exmpp_xml:remove_attribute(DEl, 'to'), DEl1 = exmpp_xml:remove_attribute(DEl, 'to'),
DEl2 = exmpp_xml:set_attribute(DEl1, 'from',FromString), DEl2 = exmpp_xml:set_attribute(DEl1, 'from',FromString),