Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
biboumi
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
88
Issues
88
List
Boards
Labels
Service Desk
Milestones
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
louiz’
biboumi
Commits
e1d69806
Commit
e1d69806
authored
Nov 12, 2014
by
louiz’
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
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
Showing
6 changed files
with
84 additions
and
55 deletions
+84
-55
src/bridge/bridge.cpp
src/bridge/bridge.cpp
+52
-46
src/bridge/bridge.hpp
src/bridge/bridge.hpp
+7
-7
src/irc/iid.hpp
src/irc/iid.hpp
+1
-1
src/irc/irc_client.cpp
src/irc/irc_client.cpp
+1
-1
src/xmpp/xmpp_component.cpp
src/xmpp/xmpp_component.cpp
+9
-0
src/xmpp/xmpp_component.hpp
src/xmpp/xmpp_component.hpp
+14
-0
No files found.
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_iq
;
std
::
list
<
i
rc_responder_callback_t
>
waiting_irc
;
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
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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