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
98
Issues
98
List
Boards
Labels
Service Desk
Milestones
Merge Requests
12
Merge Requests
12
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
7c1a3899
Commit
7c1a3899
authored
Jun 11, 2014
by
louiz’
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite the whole IID usage
IRC users and channels are now distinguished by the separator used in the IID (% or !). ref
#2468
parent
6210a9d5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
279 additions
and
99 deletions
+279
-99
doc/biboumi.1.md
doc/biboumi.1.md
+26
-10
src/bridge/bridge.cpp
src/bridge/bridge.cpp
+36
-36
src/irc/iid.cpp
src/irc/iid.cpp
+52
-10
src/irc/iid.hpp
src/irc/iid.hpp
+50
-13
src/irc/irc_client.cpp
src/irc/irc_client.cpp
+36
-25
src/test.cpp
src/test.cpp
+36
-0
src/xmpp/xmpp_component.cpp
src/xmpp/xmpp_component.cpp
+36
-4
src/xmpp/xmpp_component.hpp
src/xmpp/xmpp_component.hpp
+7
-1
No files found.
doc/biboumi.1.md
View file @
7c1a3899
...
...
@@ -101,11 +101,12 @@ signal again or if a 2 seconds delay has passed.
### Addressing
IRC entities are represented by XMPP JIDs. The domain part of the JID is
the domain served by biboumi, and the local part depends on the concerned
entity.
the domain served by biboumi (the part after the
`@`
, biboumi.example.com in
the examples), and the local part (the part before the
`@`
) depends on the
concerned entity.
IRC channels
and IRC users JIDs have a local
part formed like this:
`
name`
, the
`'%'`
separator and the
`irc_server`
.
IRC channels
have a local
part formed like this:
`
channel_name`
%
`irc_server`
.
If the IRC channel you want to adress starts with the
`'#'`
character (or an
other character, announced by the IRC server, like
`'&'`
,
`'+'`
or
`'!'`
),
...
...
@@ -113,12 +114,16 @@ then you must include it in the JID. Some other gateway implementations, as
well as some IRC clients, do not require them to be started by one of these
characters, adding an implicit
`'#'`
in that case. Biboumi does not do that
because this gets confusing when trying to understand the difference between
the channels
*#foo*
, and
*##foo*
.
the channels
*#foo*
, and
*##foo*
. Note that biboumi does not use the
presence of these special characters to identify an IRC channel, only the
presence of the separator
`%`
is used for that.
The
name part
can also be empty (for example
`%irc.example.com`
), in that
The
channel name
can also be empty (for example
`%irc.example.com`
), in that
case this represents the virtual channel provided by biboumi. See
*
Connect
to an IRC server
*
for more details.
IRC users have a local part formed like this:
`user_name`
!
`irc_server`
.
On XMPP, the node part of the JID can only be lowercase. On the other hand,
IRC nicknames are case-insensitive, this means that the nicknames toto,
...
...
@@ -131,7 +136,7 @@ Examples:
irc.example.com IRC server, and this is served by the biboumi instance on
biboumi.example.com
`toto
%
irc.example.com@biboumi.example.com`
is the IRC user named toto, or
`toto
!
irc.example.com@biboumi.example.com`
is the IRC user named toto, or
TotO, etc.
`irc.example.com@biboumi.example.com`
is the IRC server irc.example.com.
...
...
@@ -139,9 +144,20 @@ Examples:
`%irc.example.com@biboumi.example.com`
is the virtual channel provided by
biboumi, for the IRC server irc.example.com.
If compiled with Libidn, an IRC user has a bare JID representing the
“hostname” provided by the IRC server. This JID can only be used to set IRC
modes (for example to ban a user based on its IP), or to identify user.
Note: Some JIDs are valid but make no sense in the context of
biboumi:
`!irc.example.com@biboumi.example.com`
is the empty-string nick on the
irc.example.com server. It makes no sense to try to send messages to it.
`#test%@biboumi.example.com`
, or any other JID that does not contain an
IRC server is invalid. Any message to that kind of JID will trigger an
error, or will be ignored.
If compiled with Libidn, an IRC channel participant has a bare JID
representing the “hostname” provided by the IRC server. This JID can only
be used to set IRC modes (for example to ban a user based on its IP), or to
identify user. It cannot be used to contact that user using biboumi.
### Join an IRC channel
...
...
src/bridge/bridge.cpp
View file @
7c1a3899
...
...
@@ -106,8 +106,8 @@ IrcClient* Bridge::get_irc_client(const std::string& hostname)
bool
Bridge
::
join_irc_channel
(
const
Iid
&
iid
,
const
std
::
string
&
username
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
,
username
);
if
(
iid
.
chan
.
empty
())
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
,
username
);
if
(
iid
.
get_local
()
.
empty
())
{
// Join the dummy channel
if
(
irc
->
is_welcomed
())
{
...
...
@@ -117,7 +117,7 @@ bool Bridge::join_irc_channel(const Iid& iid, const std::string& username)
// joined the channel
const
IrcMessage
join_message
(
irc
->
get_nick
(),
"JOIN"
,
{
""
});
irc
->
on_channel_join
(
join_message
);
const
IrcMessage
end_join_message
(
std
::
string
(
iid
.
server
),
"366"
,
const
IrcMessage
end_join_message
(
std
::
string
(
iid
.
get_server
()
),
"366"
,
{
irc
->
get_nick
(),
""
,
"End of NAMES list"
});
irc
->
on_channel_completely_joined
(
end_join_message
);
...
...
@@ -129,9 +129,9 @@ bool Bridge::join_irc_channel(const Iid& iid, const std::string& username)
}
return
true
;
}
if
(
irc
->
is_channel_joined
(
iid
.
chan
)
==
false
)
if
(
irc
->
is_channel_joined
(
iid
.
get_local
()
)
==
false
)
{
irc
->
send_join_command
(
iid
.
chan
);
irc
->
send_join_command
(
iid
.
get_local
()
);
return
true
;
}
return
false
;
...
...
@@ -139,15 +139,15 @@ bool Bridge::join_irc_channel(const Iid& iid, const std::string& username)
void
Bridge
::
send_channel_message
(
const
Iid
&
iid
,
const
std
::
string
&
body
)
{
if
(
iid
.
chan
.
empty
()
||
iid
.
server
.
empty
())
if
(
iid
.
get_local
().
empty
()
||
iid
.
get_server
()
.
empty
())
{
log_warning
(
"Cannot send message to channel: ["
<<
iid
.
chan
<<
"] on server ["
<<
iid
.
server
<<
"]"
);
log_warning
(
"Cannot send message to channel: ["
<<
iid
.
get_local
()
<<
"] on server ["
<<
iid
.
get_server
()
<<
"]"
);
return
;
}
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
!
irc
)
{
log_warning
(
"Cannot send message: no client exist for server "
<<
iid
.
server
);
log_warning
(
"Cannot send message: no client exist for server "
<<
iid
.
get_server
()
);
return
;
}
// Because an IRC message cannot contain \n, we need to convert each line
...
...
@@ -166,27 +166,27 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body)
if
(
line
.
substr
(
0
,
6
)
==
"/mode "
)
{
std
::
vector
<
std
::
string
>
args
=
utils
::
split
(
line
.
substr
(
6
),
' '
,
false
);
irc
->
send_mode_command
(
iid
.
chan
,
args
);
irc
->
send_mode_command
(
iid
.
get_local
()
,
args
);
continue
;
// We do not want to send that back to the
// XMPP user, that’s not a textual message.
}
else
if
(
line
.
substr
(
0
,
4
)
==
"/me "
)
irc
->
send_channel_message
(
iid
.
chan
,
action_prefix
+
line
.
substr
(
4
)
+
"
\01
"
);
irc
->
send_channel_message
(
iid
.
get_local
()
,
action_prefix
+
line
.
substr
(
4
)
+
"
\01
"
);
else
irc
->
send_channel_message
(
iid
.
chan
,
line
);
this
->
xmpp
->
send_muc_message
(
iid
.
chan
+
"%"
+
iid
.
server
,
irc
->
get_own_nick
(),
irc
->
send_channel_message
(
iid
.
get_local
()
,
line
);
this
->
xmpp
->
send_muc_message
(
std
::
to_string
(
iid
)
,
irc
->
get_own_nick
(),
this
->
make_xmpp_body
(
line
),
this
->
user_jid
);
}
}
void
Bridge
::
send_private_message
(
const
Iid
&
iid
,
const
std
::
string
&
body
,
const
std
::
string
&
type
)
{
if
(
iid
.
chan
.
empty
()
||
iid
.
server
.
empty
())
if
(
iid
.
get_local
().
empty
()
||
iid
.
get_server
()
.
empty
())
return
;
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
!
irc
)
{
log_warning
(
"Cannot send message: no client exist for server "
<<
iid
.
server
);
log_warning
(
"Cannot send message: no client exist for server "
<<
iid
.
get_server
()
);
return
;
}
std
::
vector
<
std
::
string
>
lines
=
utils
::
split
(
body
,
'\n'
,
true
);
...
...
@@ -195,38 +195,38 @@ void Bridge::send_private_message(const Iid& iid, const std::string& body, const
for
(
const
std
::
string
&
line
:
lines
)
{
if
(
line
.
substr
(
0
,
4
)
==
"/me "
)
irc
->
send_private_message
(
iid
.
chan
,
action_prefix
+
line
.
substr
(
4
)
+
"
\01
"
,
type
);
irc
->
send_private_message
(
iid
.
get_local
()
,
action_prefix
+
line
.
substr
(
4
)
+
"
\01
"
,
type
);
else
irc
->
send_private_message
(
iid
.
chan
,
line
,
type
);
irc
->
send_private_message
(
iid
.
get_local
()
,
line
,
type
);
}
}
void
Bridge
::
leave_irc_channel
(
Iid
&&
iid
,
std
::
string
&&
status_message
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
irc
)
irc
->
send_part_command
(
iid
.
chan
,
status_message
);
irc
->
send_part_command
(
iid
.
get_local
()
,
status_message
);
}
void
Bridge
::
send_irc_nick_change
(
const
Iid
&
iid
,
const
std
::
string
&
new_nick
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
irc
)
irc
->
send_nick_command
(
new_nick
);
}
void
Bridge
::
send_irc_kick
(
const
Iid
&
iid
,
const
std
::
string
&
target
,
const
std
::
string
&
reason
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
irc
)
irc
->
send_kick_command
(
iid
.
chan
,
target
,
reason
);
irc
->
send_kick_command
(
iid
.
get_local
()
,
target
,
reason
);
}
void
Bridge
::
set_channel_topic
(
const
Iid
&
iid
,
const
std
::
string
&
subject
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
irc
)
irc
->
send_topic_command
(
iid
.
chan
,
subject
);
irc
->
send_topic_command
(
iid
.
get_local
()
,
subject
);
}
void
Bridge
::
send_xmpp_version_to_irc
(
const
Iid
&
iid
,
const
std
::
string
&
name
,
const
std
::
string
&
version
,
const
std
::
string
&
os
)
...
...
@@ -239,22 +239,22 @@ void Bridge::send_xmpp_version_to_irc(const Iid& iid, const std::string& name, c
void
Bridge
::
send_message
(
const
Iid
&
iid
,
const
std
::
string
&
nick
,
const
std
::
string
&
body
,
const
bool
muc
)
{
if
(
muc
)
this
->
xmpp
->
send_muc_message
(
iid
.
chan
+
"%"
+
iid
.
server
,
nick
,
this
->
xmpp
->
send_muc_message
(
std
::
to_string
(
iid
)
,
nick
,
this
->
make_xmpp_body
(
body
),
this
->
user_jid
);
else
this
->
xmpp
->
send_message
(
iid
.
chan
+
"%"
+
iid
.
server
,
this
->
xmpp
->
send_message
(
std
::
to_string
(
iid
)
,
this
->
make_xmpp_body
(
body
),
this
->
user_jid
,
"chat"
);
}
void
Bridge
::
send_join_failed
(
const
Iid
&
iid
,
const
std
::
string
&
nick
,
const
std
::
string
&
type
,
const
std
::
string
&
condition
,
const
std
::
string
&
text
)
{
this
->
xmpp
->
send_presence_error
(
iid
.
chan
+
"%"
+
iid
.
server
,
nick
,
this
->
user_jid
,
type
,
condition
,
text
);
this
->
xmpp
->
send_presence_error
(
std
::
to_string
(
iid
)
,
nick
,
this
->
user_jid
,
type
,
condition
,
text
);
}
void
Bridge
::
send_muc_leave
(
Iid
&&
iid
,
std
::
string
&&
nick
,
const
std
::
string
&
message
,
const
bool
self
)
{
this
->
xmpp
->
send_muc_leave
(
std
::
move
(
iid
.
chan
)
+
"%"
+
std
::
move
(
iid
.
server
),
std
::
move
(
nick
),
this
->
make_xmpp_body
(
message
),
this
->
user_jid
,
self
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
this
->
xmpp
->
send_muc_leave
(
std
::
to_string
(
iid
),
std
::
move
(
nick
),
this
->
make_xmpp_body
(
message
),
this
->
user_jid
,
self
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
irc
&&
irc
->
number_of_joined_channels
()
==
0
)
irc
->
send_quit_command
(
""
);
}
...
...
@@ -269,7 +269,7 @@ void Bridge::send_nick_change(Iid&& iid,
std
::
string
role
;
std
::
tie
(
role
,
affiliation
)
=
get_role_affiliation_from_irc_mode
(
user_mode
);
this
->
xmpp
->
send_nick_change
(
std
::
move
(
iid
.
chan
)
+
"%"
+
std
::
move
(
iid
.
server
),
this
->
xmpp
->
send_nick_change
(
std
::
to_string
(
iid
),
old_nick
,
new_nick
,
affiliation
,
role
,
this
->
user_jid
,
self
);
}
...
...
@@ -309,7 +309,7 @@ void Bridge::send_topic(const std::string& hostname, const std::string& chan_nam
std
::
string
Bridge
::
get_own_nick
(
const
Iid
&
iid
)
{
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
server
);
IrcClient
*
irc
=
this
->
get_irc_client
(
iid
.
get_server
()
);
if
(
irc
)
return
irc
->
get_own_nick
();
return
""
;
...
...
@@ -322,12 +322,12 @@ size_t Bridge::active_clients() const
void
Bridge
::
kick_muc_user
(
Iid
&&
iid
,
const
std
::
string
&
target
,
const
std
::
string
&
reason
,
const
std
::
string
&
author
)
{
this
->
xmpp
->
kick_user
(
iid
.
chan
+
"%"
+
iid
.
server
,
target
,
reason
,
author
,
this
->
user_jid
);
this
->
xmpp
->
kick_user
(
std
::
to_string
(
iid
)
,
target
,
reason
,
author
,
this
->
user_jid
);
}
void
Bridge
::
send_nickname_conflict_error
(
const
Iid
&
iid
,
const
std
::
string
&
nickname
)
{
this
->
xmpp
->
send_nickname_conflict_error
(
iid
.
chan
+
"%"
+
iid
.
server
,
nickname
,
this
->
user_jid
);
this
->
xmpp
->
send_nickname_conflict_error
(
std
::
to_string
(
iid
)
,
nickname
,
this
->
user_jid
);
}
void
Bridge
::
send_affiliation_role_change
(
const
Iid
&
iid
,
const
std
::
string
&
target
,
const
char
mode
)
...
...
@@ -336,10 +336,10 @@ void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& tar
std
::
string
affiliation
;
std
::
tie
(
role
,
affiliation
)
=
get_role_affiliation_from_irc_mode
(
mode
);
this
->
xmpp
->
send_affiliation_role_change
(
iid
.
chan
+
"%"
+
iid
.
server
,
target
,
affiliation
,
role
,
this
->
user_jid
);
this
->
xmpp
->
send_affiliation_role_change
(
std
::
to_string
(
iid
)
,
target
,
affiliation
,
role
,
this
->
user_jid
);
}
void
Bridge
::
send_iq_version_request
(
const
std
::
string
&
nick
,
const
std
::
string
&
hostname
)
{
this
->
xmpp
->
send_iq_version_request
(
nick
+
"
%
"
+
hostname
,
this
->
user_jid
);
this
->
xmpp
->
send_iq_version_request
(
nick
+
"
!
"
+
hostname
,
this
->
user_jid
);
}
src/irc/iid.cpp
View file @
7c1a3899
#include <utils/tolower.hpp>
#include <irc/iid.hpp>
Iid
::
Iid
(
const
std
::
string
&
iid
)
Iid
::
Iid
(
const
std
::
string
&
iid
)
:
is_channel
(
false
),
is_user
(
false
)
{
std
::
string
::
size_type
sep
=
iid
.
find
(
"%
"
);
const
std
::
string
::
size_type
sep
=
iid
.
find_first_of
(
"%!
"
);
if
(
sep
!=
std
::
string
::
npos
)
{
this
->
chan
=
iid
.
substr
(
0
,
sep
);
sep
++
;
if
(
iid
[
sep
]
==
'%'
)
this
->
is_channel
=
true
;
else
this
->
is_user
=
true
;
this
->
set_local
(
iid
.
substr
(
0
,
sep
));
this
->
set_server
(
iid
.
substr
(
sep
+
1
));
}
else
{
this
->
chan
=
iid
;
return
;
}
this
->
server
=
iid
.
substr
(
sep
);
this
->
set_server
(
iid
);
}
Iid
::
Iid
()
:
is_channel
(
false
),
is_user
(
false
)
{
}
void
Iid
::
set_local
(
const
std
::
string
&
loc
)
{
this
->
local
=
utils
::
tolower
(
loc
);
}
void
Iid
::
set_server
(
const
std
::
string
&
serv
)
{
this
->
server
=
utils
::
tolower
(
serv
);
}
const
std
::
string
&
Iid
::
get_local
()
const
{
return
this
->
local
;
}
Iid
::
Iid
()
const
std
::
string
&
Iid
::
get_server
()
const
{
return
this
->
server
;
}
std
::
string
Iid
::
get_sep
()
const
{
if
(
this
->
is_channel
)
return
"%"
;
else
if
(
this
->
is_user
)
return
"!"
;
return
""
;
}
namespace
std
{
const
std
::
string
to_string
(
const
Iid
&
iid
)
{
return
iid
.
get_local
()
+
iid
.
get_sep
()
+
iid
.
get_server
();
}
}
src/irc/iid.hpp
View file @
7c1a3899
...
...
@@ -4,17 +4,40 @@
#include <string>
/**
* A name representing an IRC channel, on the same model than the XMPP JIDs (but much simpler).
* The separator between the server and the channel name is '%'
* #test%irc.freenode.org has :
* - chan: "#test" (the # is part of the name, it could very well be absent, or & instead
* - server: "irc.freenode.org"
* #test has:
* - chan: "#test"
* - server: ""
* %irc.freenode.org:
* - chan: ""
* - server: "irc.freenode.org"
* A name representing an IRC channel on an IRC server, or an IRC user on an
* IRC server, or just an IRC server.
*
* The separator for an user is '!', for a channel it's '%'. If no separator
* is present, it's just an irc server.
* It’s possible to have an empty-string server, but it makes no sense in
* the biboumi context.
*
* #test%irc.example.org has :
* - local: "#test" (the # is part of the name, it could very well be absent, or & (for example) instead)
* - server: "irc.example.org"
* - is_channel: true
* - is_user: false
*
* %irc.example.org:
* - local: ""
* - server: "irc.example.org"
* - is_channel: true
* - is_user: false
* Note: this is the special empty-string channel, used internal in biboumi
* but has no meaning on IRC.
*
* foo!irc.example.org
* - local: "foo"
* - server: "irc.example.org"
* - is_channel: false
* - is_user: true
* Note: the empty-string user (!irc.example.org) has no special meaning in biboumi
*
* irc.example.org:
* - local: ""
* - server: "irc.example.org"
* - is_channel: false
* - is_user: false
*/
class
Iid
{
...
...
@@ -22,14 +45,28 @@ public:
explicit
Iid
(
const
std
::
string
&
iid
);
explicit
Iid
();
std
::
string
chan
;
std
::
string
server
;
void
set_local
(
const
std
::
string
&
loc
);
void
set_server
(
const
std
::
string
&
serv
);
const
std
::
string
&
get_local
()
const
;
const
std
::
string
&
get_server
()
const
;
bool
is_channel
;
bool
is_user
;
std
::
string
get_sep
()
const
;
private:
std
::
string
local
;
std
::
string
server
;
Iid
(
const
Iid
&
)
=
delete
;
Iid
(
Iid
&&
)
=
delete
;
Iid
&
operator
=
(
const
Iid
&
)
=
delete
;
Iid
&
operator
=
(
Iid
&&
)
=
delete
;
};
namespace
std
{
const
std
::
string
to_string
(
const
Iid
&
iid
);
}
#endif // IID_INCLUDED
src/irc/irc_client.cpp
View file @
7c1a3899
...
...
@@ -102,10 +102,11 @@ void IrcClient::on_connection_close()
log_warning
(
message
);
}
IrcChannel
*
IrcClient
::
get_channel
(
const
std
::
string
&
n
ame
)
IrcChannel
*
IrcClient
::
get_channel
(
const
std
::
string
&
n
)
{
if
(
n
ame
.
empty
())
if
(
n
.
empty
())
return
&
this
->
dummy_channel
;
const
std
::
string
name
=
utils
::
tolower
(
n
);
try
{
return
this
->
channels
.
at
(
name
).
get
();
...
...
@@ -382,15 +383,18 @@ void IrcClient::on_channel_message(const IrcMessage& message)
const
IrcUser
user
(
message
.
prefix
);
const
std
::
string
nick
=
user
.
nick
;
Iid
iid
;
iid
.
chan
=
utils
::
tolower
(
message
.
arguments
[
0
]);
iid
.
se
rver
=
this
->
hostname
;
iid
.
set_local
(
message
.
arguments
[
0
]);
iid
.
se
t_server
(
this
->
hostname
)
;
const
std
::
string
body
=
message
.
arguments
[
1
];
bool
muc
=
true
;
if
(
!
this
->
get_channel
(
iid
.
chan
)
->
joined
)
if
(
!
this
->
get_channel
(
iid
.
get_local
()
)
->
joined
)
{
iid
.
chan
=
nick
;
iid
.
is_user
=
true
;
iid
.
set_local
(
nick
);
muc
=
false
;
}
else
iid
.
is_channel
=
true
;
if
(
!
body
.
empty
()
&&
body
[
0
]
==
'\01'
)
{
if
(
body
.
substr
(
1
,
6
)
==
"ACTION"
)
...
...
@@ -460,8 +464,9 @@ void IrcClient::on_nickname_conflict(const IrcMessage& message)
for
(
auto
it
=
this
->
channels
.
begin
();
it
!=
this
->
channels
.
end
();
++
it
)
{
Iid
iid
;
iid
.
chan
=
it
->
first
;
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
it
->
first
);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
this
->
bridge
->
send_nickname_conflict_error
(
iid
,
nickname
);
}
}
...
...
@@ -499,7 +504,7 @@ void IrcClient::on_welcome_message(const IrcMessage& message)
void
IrcClient
::
on_part
(
const
IrcMessage
&
message
)
{
const
std
::
string
chan_name
=
utils
::
tolower
(
message
.
arguments
[
0
])
;
const
std
::
string
chan_name
=
message
.
arguments
[
0
]
;
IrcChannel
*
channel
=
this
->
get_channel
(
chan_name
);
if
(
!
channel
->
joined
)
return
;
...
...
@@ -512,13 +517,14 @@ void IrcClient::on_part(const IrcMessage& message)
std
::
string
nick
=
user
->
nick
;
channel
->
remove_user
(
user
);
Iid
iid
;
iid
.
chan
=
chan_name
;
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
chan_name
);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
bool
self
=
channel
->
get_self
()
->
nick
==
nick
;
if
(
self
)
{
channel
->
joined
=
false
;
this
->
channels
.
erase
(
chan_name
);
this
->
channels
.
erase
(
utils
::
tolower
(
chan_name
)
);
// channel pointer is now invalid
channel
=
nullptr
;
}
...
...
@@ -533,8 +539,9 @@ void IrcClient::on_error(const IrcMessage& message)
for
(
auto
it
=
this
->
channels
.
begin
();
it
!=
this
->
channels
.
end
();
++
it
)
{
Iid
iid
;
iid
.
chan
=
it
->
first
;
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
it
->
first
);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
IrcChannel
*
channel
=
it
->
second
.
get
();
if
(
!
channel
->
joined
)
continue
;
...
...
@@ -560,8 +567,9 @@ void IrcClient::on_quit(const IrcMessage& message)
std
::
string
nick
=
user
->
nick
;
channel
->
remove_user
(
user
);
Iid
iid
;
iid
.
chan
=
chan_name
;
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
chan_name
);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
this
->
bridge
->
send_muc_leave
(
std
::
move
(
iid
),
std
::
move
(
nick
),
txt
,
false
);
}
}
...
...
@@ -579,8 +587,9 @@ void IrcClient::on_nick(const IrcMessage& message)
{
std
::
string
old_nick
=
user
->
nick
;
Iid
iid
;
iid
.
chan
=
chan_name
;
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
chan_name
);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
const
bool
self
=
channel
->
get_self
()
->
nick
==
old_nick
;
const
char
user_mode
=
user
->
get_most_significant_mode
(
this
->
sorted_user_modes
);
this
->
bridge
->
send_nick_change
(
std
::
move
(
iid
),
old_nick
,
new_nick
,
user_mode
,
self
);
...
...
@@ -606,8 +615,9 @@ void IrcClient::on_kick(const IrcMessage& message)
channel
->
joined
=
false
;
IrcUser
author
(
message
.
prefix
);
Iid
iid
;
iid
.
chan
=
chan_name
;
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
chan_name
);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
this
->
bridge
->
kick_muc_user
(
std
::
move
(
iid
),
target
,
reason
,
author
.
nick
);
}
...
...
@@ -625,8 +635,9 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
// For now, just transmit the modes so the user can know what happens
// TODO, actually interprete the mode.
Iid
iid
;
iid
.
chan
=
utils
::
tolower
(
message
.
arguments
[
0
]);
iid
.
server
=
this
->
hostname
;
iid
.
set_local
(
message
.
arguments
[
0
]);
iid
.
set_server
(
this
->
hostname
);
iid
.
is_channel
=
true
;
IrcUser
user
(
message
.
prefix
);
std
::
string
mode_arguments
;
for
(
size_t
i
=
1
;
i
<
message
.
arguments
.
size
();
++
i
)
...
...
@@ -638,10 +649,10 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
mode_arguments
+=
message
.
arguments
[
i
];
}
}
this
->
bridge
->
send_message
(
iid
,
""
,
"Mode "
s
+
iid
.
chan
+
this
->
bridge
->
send_message
(
iid
,
""
,
"Mode "
s
+
iid
.
get_local
()
+
" ["
+
mode_arguments
+
"] by "
+
user
.
nick
,
true
);
const
IrcChannel
*
channel
=
this
->
get_channel
(
iid
.
chan
);
const
IrcChannel
*
channel
=
this
->
get_channel
(
iid
.
get_local
()
);
if
(
!
channel
)
return
;
...
...
@@ -695,7 +706,7 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
if
(
!
user
)
{
log_warning
(
"Trying to set mode for non-existing user '"
<<
target
<<
"' in channel"
<<
iid
.
chan
);
<<
"' in channel"
<<
iid
.
get_local
()
);
return
;
}
if
(
add
)
...
...
src/test.cpp
View file @
7c1a3899
...
...
@@ -290,5 +290,41 @@ int main()
std
::
cout
<<
correctjid2
<<
std
::
endl
;
assert
(
correctjid2
==
"zigougou@poez.io"
);
/**
* IID parsing
*/
std
::
cout
<<
color
<<
"Testing IID parsing…"
<<
reset
<<
std
::
endl
;
Iid
iid1
(
"foo!irc.example.org"
);
std
::
cout
<<
std
::
to_string
(
iid1
)
<<
std
::
endl
;
assert
(
std
::
to_string
(
iid1
)
==
"foo!irc.example.org"
);
assert
(
iid1
.
get_local
()
==
"foo"
);
assert
(
iid1
.
get_server
()
==
"irc.example.org"
);
assert
(
!
iid1
.
is_channel
);
assert
(
iid1
.
is_user
);
Iid
iid2
(
"#test%irc.example.org"
);
std
::
cout
<<
std
::
to_string
(
iid2
)
<<
std
::
endl
;
assert
(
std
::
to_string
(
iid2
)
==
"#test%irc.example.org"
);
assert
(
iid2
.
get_local
()
==
"#test"
);
assert
(
iid2
.
get_server
()
==
"irc.example.org"
);
assert
(
iid2
.
is_channel
);
assert
(
!
iid2
.
is_user
);
Iid
iid3
(
"%irc.example.org"
);
std
::
cout
<<
std
::
to_string
(
iid3
)
<<
std
::
endl
;
assert
(
std
::
to_string
(
iid3
)
==
"%irc.example.org"
);
assert
(
iid3
.
get_local
()
==
""
);
assert
(
iid3
.
get_server
()
==
"irc.example.org"
);
assert
(
iid3
.
is_channel
);
assert
(
!
iid3
.
is_user
);
Iid
iid4
(
"irc.example.org"
);
std
::
cout
<<
std
::
to_string
(
iid4
)
<<
std
::
endl
;
assert
(
std
::
to_string
(
iid4
)
==
"irc.example.org"
);
assert
(
iid4
.
get_local
()
==
""
);
assert
(
iid4
.
get_server
()
==
"irc.example.org"
);
assert
(
!
iid4
.
is_channel
);
assert
(
!
iid4
.
is_user
);
return
0
;
}
src/xmpp/xmpp_component.cpp
View file @
7c1a3899
...
...
@@ -306,7 +306,7 @@ void XmppComponent::handle_presence(const Stanza& stanza)
error_type
,
error_name
,
""
);