Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
louiz’
biboumi
Commits
e1d69806
Commit
e1d69806
authored
Nov 12, 2014
by
louiz’
Browse files
Rename iq_responder_callback_t to irc_… and add the equivalent to wait for iqs
parent
dccd8039
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bridge/bridge.cpp
View file @
e1d69806
#include
<bridge/bridge.hpp>
#include
<bridge/colors.hpp>
#include
<xmpp/xmpp_component.hpp>
#include
<xmpp/xmpp_stanza.hpp>
#include
<irc/irc_message.hpp>
#include
<network/poller.hpp>
#include
<utils/encoding.hpp>
...
...
@@ -220,45 +221,49 @@ void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std:
const
std
::
string
&
iq_id
,
const
std
::
string
&
to_jid
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
());
if
(
irc
)
if
(
!
irc
)
return
;
irc
->
send_kick_command
(
iid
.
get_local
(),
target
,
reason
);
irc_responder_callback_t
cb
=
[
this
,
target
,
iq_id
,
to_jid
,
iid
](
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
->
bool
{
irc
->
send_kick_command
(
iid
.
get_local
(),
target
,
reason
);
this
->
add_waiting_iq
([
this
,
target
,
iq_id
,
to_jid
,
iid
](
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
){
if
(
irc_hostname
!=
iid
.
get_server
())
if
(
irc_hostname
!=
iid
.
get_server
())
return
false
;
if
(
message
.
command
==
"KICK"
&&
message
.
arguments
.
size
()
>=
2
)
{
const
std
::
string
target_later
=
message
.
arguments
[
1
];
const
std
::
string
chan_name_later
=
utils
::
tolower
(
message
.
arguments
[
0
]);
if
(
target_later
!=
target
||
chan_name_later
!=
iid
.
get_local
())
return
false
;
if
(
message
.
command
==
"KICK"
&&
message
.
arguments
.
size
()
>=
2
)
{
const
std
::
string
target_later
=
message
.
arguments
[
1
];
const
std
::
string
chan_name_later
=
utils
::
tolower
(
message
.
arguments
[
0
]);
if
(
target_later
!=
target
||
chan_name_later
!=
iid
.
get_local
())
return
false
;
this
->
xmpp
->
send_iq_result
(
iq_id
,
to_jid
,
std
::
to_string
(
iid
));
}
else
if
(
message
.
command
==
"401"
&&
message
.
arguments
.
size
()
>=
2
)
{
const
std
::
string
target_later
=
message
.
arguments
[
1
];
if
(
target_later
!=
target
)
return
false
;
std
::
string
error_message
=
"No such nick"
;
if
(
message
.
arguments
.
size
()
>=
3
)
error_message
=
message
.
arguments
[
2
];
this
->
xmpp
->
send_stanza_error
(
"iq"
,
to_jid
,
std
::
to_string
(
iid
),
iq_id
,
"cancel"
,
"item-not-found"
,
error_message
,
false
);
}
else
if
(
message
.
command
==
"482"
&&
message
.
arguments
.
size
()
>=
2
)
{
const
std
::
string
chan_name_later
=
utils
::
tolower
(
message
.
arguments
[
1
]);
if
(
chan_name_later
!=
iid
.
get_local
())
return
false
;
std
::
string
error_message
=
"You're not channel operator"
;
if
(
message
.
arguments
.
size
()
>=
3
)
error_message
=
message
.
arguments
[
2
];
this
->
xmpp
->
send_stanza_error
(
"iq"
,
to_jid
,
std
::
to_string
(
iid
),
iq_id
,
"cancel"
,
"not-allowed"
,
error_message
,
false
);
}
return
true
;
});
}
this
->
xmpp
->
send_iq_result
(
iq_id
,
to_jid
,
std
::
to_string
(
iid
));
}
else
if
(
message
.
command
==
"401"
&&
message
.
arguments
.
size
()
>=
2
)
{
const
std
::
string
target_later
=
message
.
arguments
[
1
];
if
(
target_later
!=
target
)
return
false
;
std
::
string
error_message
=
"No such nick"
;
if
(
message
.
arguments
.
size
()
>=
3
)
error_message
=
message
.
arguments
[
2
];
this
->
xmpp
->
send_stanza_error
(
"iq"
,
to_jid
,
std
::
to_string
(
iid
),
iq_id
,
"cancel"
,
"item-not-found"
,
error_message
,
false
);
}
else
if
(
message
.
command
==
"482"
&&
message
.
arguments
.
size
()
>=
2
)
{
const
std
::
string
chan_name_later
=
utils
::
tolower
(
message
.
arguments
[
1
]);
if
(
chan_name_later
!=
iid
.
get_local
())
return
false
;
std
::
string
error_message
=
"You're not channel operator"
;
if
(
message
.
arguments
.
size
()
>=
3
)
error_message
=
message
.
arguments
[
2
];
this
->
xmpp
->
send_stanza_error
(
"iq"
,
to_jid
,
std
::
to_string
(
iid
),
iq_id
,
"cancel"
,
"not-allowed"
,
error_message
,
false
);
}
return
true
;
};
this
->
add_waiting_irc
(
std
::
move
(
cb
));
}
void
Bridge
::
set_channel_topic
(
const
Iid
&
iid
,
const
std
::
string
&
subject
)
...
...
@@ -284,7 +289,8 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std
// TODO, add a timer to remove that waiting iq if the server does not
// respond with a matching command before n seconds
this
->
add_waiting_iq
([
this
,
target
,
iq_id
,
to_jid
,
irc_hostname
,
from_jid
](
const
std
::
string
&
hostname
,
const
IrcMessage
&
message
){
irc_responder_callback_t
cb
=
[
this
,
target
,
iq_id
,
to_jid
,
irc_hostname
,
from_jid
](
const
std
::
string
&
hostname
,
const
IrcMessage
&
message
)
->
bool
{
if
(
irc_hostname
!=
hostname
)
return
false
;
IrcUser
user
(
message
.
prefix
);
...
...
@@ -307,10 +313,10 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std
return
true
;
}
return
false
;
});
};
this
->
add_waiting_irc
(
std
::
move
(
cb
));
}
void
Bridge
::
send_message
(
const
Iid
&
iid
,
const
std
::
string
&
nick
,
const
std
::
string
&
body
,
const
bool
muc
)
{
if
(
muc
)
...
...
@@ -447,18 +453,18 @@ void Bridge::remove_preferred_from_jid(const std::string& nick)
this
->
preferred_user_from
.
erase
(
it
);
}
void
Bridge
::
add_waiting_i
q
(
iq
_responder_callback_t
&&
callback
)
void
Bridge
::
add_waiting_i
rc
(
irc
_responder_callback_t
&&
callback
)
{
this
->
waiting_i
q
.
emplace_back
(
std
::
move
(
callback
));
this
->
waiting_i
rc
.
emplace_back
(
std
::
move
(
callback
));
}
void
Bridge
::
trigger_
response_iq
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
void
Bridge
::
trigger_
on_irc_message
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
{
auto
it
=
this
->
waiting_i
q
.
begin
();
while
(
it
!=
this
->
waiting_i
q
.
end
())
auto
it
=
this
->
waiting_i
rc
.
begin
();
while
(
it
!=
this
->
waiting_i
rc
.
end
())
{
if
((
*
it
)(
irc_hostname
,
message
)
==
true
)
it
=
this
->
waiting_i
q
.
erase
(
it
);
it
=
this
->
waiting_i
rc
.
erase
(
it
);
else
++
it
;
}
...
...
src/bridge/bridge.hpp
View file @
e1d69806
...
...
@@ -17,11 +17,11 @@ class Poller;
/**
* A callback called for each IrcMessage we receive. If the message triggers
* a response, it must send
an
iq and return true (in that case it
is
* removed from the list), otherwise it must do nothing and just return
* a response, it must send
ore or more
iq and return true (in that case it
*
is
removed from the list), otherwise it must do nothing and just return
* false.
*/
typedef
std
::
function
<
bool
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
>
iq_responder_callback_t
;
using
irc_responder_callback_t
=
std
::
function
<
bool
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
)
>
;
/**
* One bridge is spawned for each XMPP user that uses the component. The
...
...
@@ -146,15 +146,15 @@ public:
*/
void
remove_preferred_from_jid
(
const
std
::
string
&
nick
);
/**
* Add a callback to the waiting
iq
list.
* Add a callback to the waiting list
of irc callbacks
.
*/
void
add_waiting_i
q
(
iq
_responder_callback_t
&&
callback
);
void
add_waiting_i
rc
(
irc
_responder_callback_t
&&
callback
);
/**
* Iter over all the waiting_iq, call the iq_responder_filter_t for each,
* whenever one of them returns true: call the corresponding
* iq_responder_callback_t and remove the callback from the list.
*/
void
trigger_
response_iq
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
);
void
trigger_
on_irc_message
(
const
std
::
string
&
irc_hostname
,
const
IrcMessage
&
message
);
private:
/**
...
...
@@ -203,7 +203,7 @@ private:
* request and we need a response from IRC to be able to provide the
* response iq.
*/
std
::
list
<
i
q
_responder_callback_t
>
waiting_i
q
;
std
::
list
<
i
rc
_responder_callback_t
>
waiting_i
rc
;
Bridge
(
const
Bridge
&
)
=
delete
;
Bridge
(
Bridge
&&
other
)
=
delete
;
...
...
src/irc/iid.hpp
View file @
e1d69806
...
...
@@ -42,7 +42,7 @@
class
Iid
{
public:
explicit
Iid
(
const
std
::
string
&
iid
);
Iid
(
const
std
::
string
&
iid
);
explicit
Iid
(
const
Iid
&
);
explicit
Iid
();
...
...
src/irc/irc_client.cpp
View file @
e1d69806
...
...
@@ -156,7 +156,7 @@ void IrcClient::parse_in_buffer(const size_t)
else
log_info
(
"No handler for command "
<<
message
.
command
);
// Try to find a waiting_iq, which response will be triggered by this IrcMessage
this
->
bridge
->
trigger_
response_iq
(
this
->
hostname
,
message
);
this
->
bridge
->
trigger_
on_irc_message
(
this
->
hostname
,
message
);
}
}
...
...
src/xmpp/xmpp_component.cpp
View file @
e1d69806
...
...
@@ -577,6 +577,15 @@ void XmppComponent::handle_iq(const Stanza& stanza)
const
Iid
iid
(
to
.
local
);
bridge
->
send_xmpp_version_to_irc
(
iid
,
name
,
version
,
os
);
}
else
{
const
auto
it
=
this
->
waiting_iq
.
find
(
id
);
if
(
it
!=
this
->
waiting_iq
.
end
())
{
it
->
second
(
bridge
,
stanza
);
this
->
waiting_iq
.
erase
(
it
);
}
}
}
error_type
=
"cancel"
;
error_name
=
"feature-not-implemented"
;
...
...
src/xmpp/xmpp_component.hpp
View file @
e1d69806
...
...
@@ -9,6 +9,7 @@
#include
<unordered_map>
#include
<memory>
#include
<string>
#include
<map>
#define STREAM_NS "http://etherx.jabber.org/streams"
#define COMPONENT_NS "jabber:component:accept"
...
...
@@ -23,6 +24,11 @@
#define STREAMS_NS "urn:ietf:params:xml:ns:xmpp-streams"
#define VERSION_NS "jabber:iq:version"
#define ADHOC_NS "http://jabber.org/protocol/commands"
/**
* A callback called when the waited iq result is received (it is matched
* against the iq id)
*/
using
iq_responder_callback_t
=
std
::
function
<
void
(
Bridge
*
bridge
,
const
Stanza
&
stanza
)
>
;
/**
* An XMPP component, communicating with an XMPP server using the protocole
...
...
@@ -256,6 +262,14 @@ private:
std
::
unordered_map
<
std
::
string
,
std
::
function
<
void
(
const
Stanza
&
)
>>
stanza_handlers
;
AdhocCommandsHandler
adhoc_commands_handler
;
/**
* A map of id -> callback. When we want to wait for an iq result, we add
* the callback to this map, with the iq id as the key. When an iq result
* is received, we look for a corresponding callback in this map. If
* found, we call it and remove it.
*/
std
::
map
<
std
::
string
,
iq_responder_callback_t
>
waiting_iq
;
/**
* One bridge for each user of the component. Indexed by the user's full
* jid
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment