diff --git a/ChangeLog b/ChangeLog index 87f6e6f1c..e0e127f71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-12-22 Christophe Romain + + * src/ejabberd_sm.erl: change incoming_presence_hook to + presence_probe_hook + * src/ejabberd_c2s.erl: Likewise + + * src/mod_pubsub/mod_pubsub.erl: send last pep item bugfix and + broadcast optimization (EJAB-468) (EJAB-467) (EJAB-460) + * src/mod_pubsub/pubsub.hrl: Likewise + * src/mod_pubsub/node_default.erl: Likewise + 2007-12-22 Badlop * src/mod_caps.erl: Bugfix in timeout checking. Check for timeout diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 7954f0586..8a449a8c8 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1385,6 +1385,7 @@ process_presence_probe(From, To, StateData) -> deny -> ok; allow -> + ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Packet]), ejabberd_router:route(To, From, Packet) end; Cond2 -> diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 9dca35290..025b6de68 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -386,9 +386,7 @@ do_route(From, To, Packet) -> From, jlib:jid_replace_resource(To, R), Packet) - end, PResources), - ejabberd_hooks:run(incoming_presence_hook, LServer, - [From, To, Packet]); + end, PResources); true -> ok end; diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl index fcb146821..96f1f2880 100644 --- a/src/mod_pubsub/mod_pubsub.erl +++ b/src/mod_pubsub/mod_pubsub.erl @@ -23,7 +23,6 @@ %%% TODO %%% plugin: generate Reply (do not use broadcast atom anymore) -%%% to be implemented: deliver_notifications -module(mod_pubsub). -version('1.10-01'). @@ -40,9 +39,7 @@ -define(PEPNODE, "pep"). %% exports for hooks --export([set_presence/4, - unset_presence/4, - incoming_presence/3, +-export([presence_probe/3, remove_user/2, disco_local_identity/5, disco_local_features/5, @@ -142,9 +139,6 @@ init([ServerHost, Opts]) -> Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"), ServedHosts = gen_mod:get_opt(served_hosts, Opts, []), Access = gen_mod:get_opt(access_createnode, Opts, all), - mnesia:create_table(pubsub_presence, - [{disc_copies, [node()]}, - {attributes, record_info(fields, pubsub_presence)}]), mod_disco:register_feature(ServerHost, ?NS_PUBSUB), ejabberd_hooks:add(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75), ejabberd_hooks:add(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75), @@ -152,9 +146,7 @@ init([ServerHost, Opts]) -> ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75), ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75), ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), - ejabberd_hooks:add(incoming_presence_hook, ServerHost, ?MODULE, incoming_presence, 50), - %%ejabberd_hooks:add(set_presence_hook, ServerHost, ?MODULE, set_presence, 50), - %%ejabberd_hooks:add(unset_presence_hook, ServerHost, ?MODULE, unset_presence, 50), + ejabberd_hooks:add(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 50), ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), lists:foreach( @@ -218,12 +210,12 @@ terminate_plugins(Host, ServerHost, Plugins, TreePlugin) -> ok. init_nodes(Host, ServerHost, ServedHosts) -> - create_node(Host, ServerHost, ["pubsub"], ?PUBSUB_JID, ?STDNODE), - create_node(Host, ServerHost, ["pubsub", "nodes"], ?PUBSUB_JID, ?STDNODE), - create_node(Host, ServerHost, ["home"], ?PUBSUB_JID, ?STDNODE), + create_node(Host, ServerHost, ["pubsub"], service_jid(Host), ?STDNODE), + create_node(Host, ServerHost, ["pubsub", "nodes"], service_jid(Host), ?STDNODE), + create_node(Host, ServerHost, ["home"], service_jid(Host), ?STDNODE), lists:foreach( fun(H) -> - create_node(Host, ServerHost, ["home", H], ?PUBSUB_JID, ?STDNODE) + create_node(Host, ServerHost, ["home", H], service_jid(Host), ?STDNODE) end, [ServerHost | ServedHosts]), ok. @@ -390,13 +382,7 @@ disco_sm_items(Acc, _From, To, Node, _Lang) -> %% presence hooks handling functions %% -set_presence(User, Server, Resource, Presence) -> - Proc = gen_mod:get_module_proc(Server, ?PROCNAME), - gen_server:cast(Proc, {set_presence, User, Server, Resource, Presence}). -unset_presence(User, Server, Resource, Status) -> - Proc = gen_mod:get_module_proc(Server, ?PROCNAME), - gen_server:cast(Proc, {unset_presence, User, Server, Resource, Status}). -incoming_presence(From, #jid{lserver = Host} = To, Packet) -> +presence_probe(#jid{lserver = Host} = From, To, Packet) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:cast(Proc, {presence, From, To, Packet}). @@ -438,102 +424,70 @@ handle_call(stop, _From, State) -> %%-------------------------------------------------------------------- %% @private handle_cast({presence, From, To, Packet}, State) -> - Plugins = State#state.plugins, - Key = {To#jid.lserver, From#jid.luser, From#jid.lserver}, - Record = #pubsub_presence{key = Key, resource = From#jid.lresource}, - Priority = case xml:get_subtag(Packet, "priority") of - false -> 0; - SubEl -> - case catch list_to_integer(xml:get_tag_cdata(SubEl)) of - P when is_integer(P) -> P; - _ -> 0 - end - end, - PresenceType = case xml:get_tag_attr_s("type", Packet) of - "" -> - if Priority < 0 -> unavailable; - true -> available - end; - "unavailable" -> unavailable; - "error" -> unavailable; - _ -> none - end, - PreviouslyAvailable = - lists:member(From#jid.lresource, - lists:map(fun(#pubsub_presence{resource = R}) -> R end, - case catch mnesia:dirty_read(pubsub_presence, Key) of - Result when is_list(Result) -> Result; - _ -> [] - end)), - case PresenceType of - available -> mnesia:dirty_write(Record); - unavailable -> mnesia:dirty_delete_object(Record); - _ -> ok - end, - if PreviouslyAvailable == false, - PresenceType == available -> - %% A new resource is available. Loop through all subscriptions - %% and if the node is so configured, send the last item. - JID = jlib:jid_tolower(From), - Host = State#state.host, - ServerHost = State#state.server_host, + %% A new resource is available. send last published items + JID = jlib:jid_tolower(From), + Host = State#state.host, + ServerHost = State#state.server_host, + if From == To -> + %% for each node From is subscribed to + %% and if the node is so configured, send the last published item to From + lists:foreach(fun(Type) -> + {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, From]), lists:foreach( - fun(Type) -> - {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, From]), - Options = node_options(Type), - SendLast = get_option(Options, send_last_published_item), - AccessModel = get_option(Options, access_model), - AllowedGroups = get_option(Options, roster_groups_allowed), - lists:foreach( - fun({Node, Subscription}) -> - if - Subscription /= none, Subscription /= pending, SendLast == on_sub_and_presence -> + fun({Node, subscribed}) -> + case tree_action(Host, get_node, [Host, Node]) of + #pubsub_node{options = Options} -> + case get_option(Options, send_last_published_item) of + on_sub_and_presence -> send_last_item(Host, Node, JID); - SendLast == on_sub_and_presence -> - {PresenceSubscription, RosterGroup} = get_roster_info( - To#jid.luser, To#jid.lserver, JID, AllowedGroups), - Features = case catch mod_caps:get_features(ServerHost, mod_caps:read_caps(element(4, Packet))) of - F when is_list(F) -> F; - _ -> [] - end, - case lists:member(Node ++ "+notify", Features) of - true -> - MaySubscribe = - case AccessModel of - open -> true; - presence -> PresenceSubscription; - whitelist -> false; % subscribers are added manually - authorize -> false; % likewise - roster -> RosterGroup - end, - if MaySubscribe -> - send_last_item(Host, Node, JID); - true -> - ok - end; - false -> - ok - end; - true -> + _ -> ok end; - (_) -> + _ -> ok - end, Subscriptions) - end, Plugins), - {noreply, State}; - true -> - {noreply, State} - end; - -handle_cast({set_presence, _User, _Server, _Resource, _Presence}, State) -> - {noreply, State}; -handle_cast({unset_presence, _User, _Server, _Resource, _Status}, State) -> + end; + (_) -> + ok + end, Subscriptions) + end, State#state.plugins); + true -> + ok + end, + %% and send to From last PEP events published by To + PepKey = jlib:jid_tolower(jlib:jid_remove_resource(To)), + Caps = mod_caps:read_caps(element(4, Packet)), + lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options}) -> + case get_option(Options, send_last_published_item) of + on_sub_and_presence -> + case is_caps_notify(ServerHost, Node, Caps) of + true -> + AllowedGroups = get_option(Options, roster_groups_allowed), + {PresenceSubscription, RosterGroup} = get_roster_info( + To#jid.luser, To#jid.lserver, JID, AllowedGroups), + Subscribed = case get_option(Options, access_model) of + open -> true; + presence -> PresenceSubscription; + whitelist -> false; % subscribers are added manually + authorize -> false; % likewise + roster -> RosterGroup + end, + if Subscribed -> + send_last_item(PepKey, Node, JID); + true -> + ok + end; + false -> + ok + end; + _ -> + ok + end + end, tree_action(Host, get_nodes, [PepKey])), {noreply, State}; handle_cast({remove, User, Server}, State) -> Owner = jlib:make_jid(User, Server, ""), - delete_nodes(Server, Owner, State#state.plugins), + delete_nodes(Server, Owner), {noreply, State}; handle_cast(_Msg, State) -> @@ -578,9 +532,7 @@ terminate(_Reason, #state{host = Host, ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75), ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75), ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), - ejabberd_hooks:delete(incoming_presence_hook, ServerHost, ?MODULE, incoming_presence, 50), - %%ejabberd_hooks:delete(set_presence_hook, ServerHost, ?MODULE, set_presence, 50), - %%ejabberd_hooks:delete(unset_presence_hook, ServerHost, ?MODULE, unset_presence, 50), + ejabberd_hooks:delete(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 50), ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50), lists:foreach(fun({NS,Mod}) -> gen_iq_handler:remove_iq_handler(Mod, ServerHost, NS) @@ -666,9 +618,7 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, - ejabberd_router:route(To, - From, - jlib:iq_to_xml(Res)); + ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{} -> Err = jlib:make_error_reply( Packet, @@ -678,7 +628,7 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) -> ok end; "presence" -> - incoming_presence(From, To, Packet), + presence_probe(From, To, Packet), ok; "message" -> case xml:get_attr_s("type", Attrs) of @@ -1022,8 +972,7 @@ send_authorization_request(Host, Node, Subscriber) -> #pubsub_node{owners = Owners} -> lists:foreach( fun(Owner) -> - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(Owner), - Stanza) + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(Owner), Stanza} end, Owners), ok; _ -> @@ -1096,8 +1045,9 @@ handle_authorization_response(Host, From, To, Packet, XFields) -> end, case transaction(Host, Node, Action, sync_dirty) of {error, Error} -> - ejabberd_router:route(To, From, - jlib:make_error_reply(Packet, Error)); + ejabberd_router:route( + To, From, + jlib:make_error_reply(Packet, Error)); {result, _NewSubscription} -> %% XXX: notify about subscription state change, section 12.11 ok; @@ -1312,25 +1262,12 @@ delete_node(Host, Node, Owner) -> {result, Result} -> {result, Result} end. -delete_nodes(Host, Owner, Plugins) -> +delete_nodes(Host, Owner) -> %% This removes only PEP nodes when user is removed OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), lists:foreach(fun(#pubsub_node{nodeid={NodeKey, NodeName}}) -> delete_node(NodeKey, NodeName, Owner) end, tree_action(Host, get_nodes, [OwnerKey])). -% TODO: may be best to use the generic following code -% lists:foreach(fun(Type) -> -% {result, Affiliations} = node_action(Type, get_entity_affiliations, [Host, Owner]), -% NodeKey = case Type of -% ?PEPNODE -> OwnerKey; -% _ -> Host -% end, -% lists:foreach( -% fun({NodeId, owner}) -> delete_node(NodeKey, NodeId, Owner); -% (_) -> ok -% end -% end, Affiliations) -% end, Plugins), %% @spec (Host, Node, From, JID) -> %% {error, Reason::stanzaError()} | @@ -1407,7 +1344,6 @@ subscribe_node(Host, Node, From, JID) -> {error, Error} -> {error, Error}; {result, {Result, subscribed, send_last}} -> - %% TODO was send_last_published_item send_all_items(Host, Node, Subscriber), case Result of default -> {result, Reply(subscribed)}; @@ -1505,7 +1441,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> node_call(Type, publish_item, [Host, Node, Publisher, Model, MaxItems, ItemId, Payload]) end end, - %%ejabberd_hooks:run(pubsub_publish_item, Host, [Host, Node, JID, ?PUBSUB_JID, ItemId, Payload]), + %%ejabberd_hooks:run(pubsub_publish_item, Host, [Host, Node, JID, service_jid(Host), ItemId, Payload]), Reply = [], case transaction(Host, Node, Action, sync_dirty) of {error, ?ERR_ITEM_NOT_FOUND} -> @@ -1741,7 +1677,7 @@ send_items(Host, Node, LJID, Number) -> [{xmlelement, "x", [{"xmlns", ?NS_PUBSUB_EVENT}], [{xmlelement, "items", [{"node", node_to_string(Node)}], ItemsEls}]}]}, - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(LJID), Stanza). + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(LJID), Stanza}. %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() @@ -2055,18 +1991,30 @@ node_to_string(Node) -> string_to_node(SNode) -> string:tokens(SNode, "/"). -%% @spec (Host, JID, PresenceDelivery) -> boolean() +%% @spec (Host) -> jid() %% Host = host() -%% JID = jid() +%% @doc

Generate pubsub service JID.

+service_jid(Host) -> + case Host of + {U,S,_} -> {jid, U, S, "", U, S, ""}; + _ -> {jid, "", Host, "", "", Host, ""} + end. + +%% @spec (LJID, PresenceDelivery) -> boolean() +%% LJID = jid() +%% Subscription = atom() %% PresenceDelivery = boolean() %% @doc

Check if a notification must be delivered or not -to_be_delivered(_Host, _JID, false) -> - % default is true - true; -to_be_delivered(Host, JID, true) -> - case mnesia:dirty_read(pubsub_presence, {Host, element(1, JID), element(2, JID)}) of - [_] -> true; - [] -> false +is_to_delivered(_, none, _) -> false; +is_to_delivered(_, pending, _) -> false; +is_to_delivered(_, _, false) -> true; +is_to_delivered({User, Server, _}, _, true) -> + case mnesia:dirty_match_object({session, '_', '_', {User, Server}, '_', '_'}) of + [] -> false; + Ss -> + lists:foldl(fun({session, _, _, _, undefined, _}, Acc) -> Acc; + ({session, _, _, _, _Priority, _}, _Acc) -> true + end, false, Ss) end. %%%%%% broadcast functions @@ -2094,22 +2042,19 @@ broadcast_publish_item(Host, Node, ItemId, _From, Payload) -> [{xmlelement, "items", [{"node", node_to_string(Node)}], [{xmlelement, "item", ItemAttrs, Content}]}]}]}, lists:foreach( - fun(#pubsub_state{stateid = {JID, _}, + fun(#pubsub_state{stateid = {LJID, _}, subscription = Subscription}) -> - ToBeSent = to_be_delivered(Host, JID, PresenceDelivery), - if - (Subscription /= none) and - (Subscription /= pending) and - ToBeSent -> + case is_to_delivered(LJID, Subscription, PresenceDelivery) of + true -> DestJIDs = case BroadcastAll of - true -> ejabberd_sm:get_user_resources(element(1, JID), element(2, JID)); - false -> [JID] + true -> ejabberd_sm:get_user_resources(element(1, LJID), element(2, LJID)); + false -> [LJID] end, lists:foreach( fun(DestJID) -> - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(DestJID), Stanza) + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(DestJID), Stanza} end, DestJIDs); - true -> + false -> ok end end, States), @@ -2148,7 +2093,7 @@ broadcast_retract_item(Host, Node, ItemId, ForceNotify) -> subscription = Subscription}) -> if (Subscription /= none) and (Subscription /= pending) -> - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza); + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza}; true -> ok end @@ -2181,7 +2126,7 @@ broadcast_purge_node(Host, Node) -> subscription = Subscription}) -> if (Subscription /= none) and (Subscription /= pending) -> - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza); + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza}; true -> ok end @@ -2213,7 +2158,7 @@ broadcast_removed_node(Host, Removed) -> subscription = Subscription}) -> if (Subscription /= none) and (Subscription /= pending) -> - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza); + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza}; true -> ok end @@ -2253,14 +2198,12 @@ broadcast_config_notification(Host, Node, Lang) -> [{xmlelement, "item", [{"id", "configuration"}], Content}]}]}]}, lists:foreach( - fun(#pubsub_state{stateid = {JID, _}, + fun(#pubsub_state{stateid = {LJID, _}, subscription = Subscription}) -> - ToBeSent = to_be_delivered(Host, JID, PresenceDelivery), - if (Subscription /= none) and - (Subscription /= pending) and - ToBeSent -> - ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza); - true -> + case is_to_delivered(LJID, Subscription, PresenceDelivery) of + true -> + ejabberd_router ! {route, service_jid(Host), jlib:make_jid(LJID), Stanza}; + false -> ok end end, States), @@ -2298,11 +2241,10 @@ broadcast_config_notification(Host, Node, Lang) -> broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) -> ?DEBUG("looking for pid of ~p@~p/~p", [LUser, LServer, LResource]), %% We need to know the resource, so we can ask for presence data. - SenderResources = ejabberd_sm:get_user_resources(LUser, LServer), SenderResource = case LResource of "" -> %% If we don't know the resource, just pick one. - case SenderResources of + case ejabberd_sm:get_user_resources(LUser, LServer) of [R|_] -> R; [] -> @@ -2322,36 +2264,19 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) -> case catch ejabberd_c2s:get_subscribed_and_online(C2SPid) of ContactsWithCaps when is_list(ContactsWithCaps) -> ?DEBUG("found contacts with caps: ~p", [ContactsWithCaps]), - LookingFor = Node ++ "+notify", lists:foreach( fun({JID, Caps}) -> - case catch mod_caps:get_features(LServer, Caps) of - Features when is_list(Features) -> - case lists:member(LookingFor, Features) of - true -> - To = jlib:make_jid(JID), - ejabberd_router:route(Sender, To, Stanza); - _ -> - ok - end; - _ -> - %% couldn't get entity capabilities. - %% nothing to do about that... - ok - end + case is_caps_notify(LServer, Node, Caps) of + true -> + To = jlib:make_jid(JID), + ejabberd_router ! {route, Sender, To, Stanza}; + false -> + ok + end end, ContactsWithCaps); _ -> ok end, - %% also send a notification to any - %% of the account owner's available resources. - %% See: XEP-0163 1.1 section 3 - %% Note: ejabberd_c2s:get_subscribed_and_online already returns owner online resources - %% this loop should be deleted - % lists:foreach(fun(Resource) -> - % To = jlib:make_jid(LUser, LServer, Resource), - % ejabberd_router:route(Sender, To, Stanza) - % end, SenderResources), ok; _ -> ok @@ -2359,6 +2284,12 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) -> broadcast_by_caps(_, _, _, _) -> ok. +is_caps_notify(Host, Node, Caps) -> + case catch mod_caps:get_features(Host, Caps) of + Features when is_list(Features) -> lists:member(Node ++ "+notify", Features); + _ -> false + end. + %%%%%%% Configuration handling %%

There are several reasons why the default node configuration options request might fail:

diff --git a/src/mod_pubsub/node_default.erl b/src/mod_pubsub/node_default.erl index b5e8d9f67..b02eb6c0f 100644 --- a/src/mod_pubsub/node_default.erl +++ b/src/mod_pubsub/node_default.erl @@ -177,21 +177,21 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), {User, Server, _Resource} = LOwner, Allowed = case acl:match_rule(ServerHost, Access, LOwner) of - allow -> - if Server == Host -> %% Server == ServerHost ?? - true; - true -> - case Node of - ["home", Server, User | _] -> true; - _ -> false - end - end; - _ -> - case Owner of - ?PUBSUB_JID -> true; - _ -> false - end - end, + allow -> + if Server == Host -> %% Server == ServerHost ?? + true; + true -> + case Node of + ["home", Server, User | _] -> true; + _ -> false + end + end; + _ -> + case Owner of + {jid, "", _, "", "", _, ""} -> true; + _ -> false + end + end, ChildOK = true, %% TODO test with ParentNode {result, Allowed and ChildOK}. diff --git a/src/mod_pubsub/pubsub.hrl b/src/mod_pubsub/pubsub.hrl index 199a8dd2e..7755f8a96 100644 --- a/src/mod_pubsub/pubsub.hrl +++ b/src/mod_pubsub/pubsub.hrl @@ -1,12 +1,11 @@ %%% ==================================================================== -%%% This software is copyright 2006, Process-one. +%%% This software is copyright 2007, Process-one. %%% %%% This file contains pubsub types definition. %%% ==================================================================== %% ------------------------------- %% Pubsub constants --define(PUBSUB_JID, {jid, "", Host, "", "", Host, ""}). -define(ERR_EXTENDED(E,C), mod_pubsub:extended_error(E,C)). %% this is currently a hard limit.