commit 3c497099822920b38c34fb62b95465d988832d96
parent 2226320bf9f041bf7a5e80d1b07d64ddc06cf7f0
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Tue, 7 Aug 2012 21:57:46 +0200
fix channel password handling, add test for it
Diffstat:
irctk.c | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
test/password.sh | | | 14 | ++++++++++++++ |
2 files changed, 58 insertions(+), 32 deletions(-)
diff --git a/irctk.c b/irctk.c
@@ -912,27 +912,6 @@ char* first_chan()
else return args.nick;
}
-/* Join a channel, optionally suffixed with :PASSWORD */
-int join_channel(irc_session_t *s, char* chan)
-{
- char *password = chan;
- int pos = 0;
- int ret;
- // find the password if the password indicates a chan (last ':')
- while (password[pos] != ':' && password[pos])
- pos++;
- if (password[pos]) {
- chan[pos] = 0;
- password += pos + 1;
- } else {
- password = NULL;
- }
- ret = irc_cmd_join (s, chan, password);
- if (password)
- chan[pos] = ':';
- return ret;
-}
-
const char *input_nick(const char *nick) {
int c;
const char *result;
@@ -993,10 +972,10 @@ char* consume_word(char **from)
return result;
}
-int do_say(irc_session_t *s, char *chan, char *line) {
+int do_say(irc_session_t *s, char *chan, char *password, char *line) {
/* TODO2 only join channels we haven't joined yet */
if (args.join)
- join_channel(s, chan);
+ irc_cmd_join(s, chan, password);
if (args.own) {
mprintf("[%s] <%s%s> %s", chan,
output_nick(args.nick),
@@ -1007,12 +986,31 @@ int do_say(irc_session_t *s, char *chan, char *line) {
return irc_cmd_msg(s, chan, line);
}
+/* If chan is suffixed by a password, modify it and return the modified offset */
+int get_password(char *chan) {
+ int pos = 0;
+ while (chan[pos] != ':' && chan[pos])
+ pos++;
+ if (chan[pos]) {
+ chan[pos] = 0;
+ return pos;
+ }
+ return -1;
+}
+
+void revert_password(char *chan, int pos) {
+ if (pos < 0) return;
+ chan[pos] = ':';
+}
+
/* Send a message or do a command */
/* Return value is 0 if OK, >0 if error, -1 if correctly exited */
int do_cmd_msg(irc_session_t *s, char *chan, char* line)
{
int rsl = 0;
+ int pw_pos = get_password(chan);
+ char *password = chan + pw_pos + 1;
debug("do_cmd_msg %s %s\n", chan, line);
@@ -1035,6 +1033,8 @@ int do_cmd_msg(irc_session_t *s, char *chan, char* line)
}
} else if ((arg = MATCH_CMD0(line, "join"))) {
char *to_join = NULL;
+ // we must revert temporarily so that we can join
+ revert_password(chan, pw_pos);
if (!*arg || *arg == '\n') {
to_join = chan;
} else if (*arg == ' ') {
@@ -1042,13 +1042,19 @@ int do_cmd_msg(irc_session_t *s, char *chan, char* line)
}
if (to_join) {
if (args.join) {
- rsl = join_channel(s, to_join);
+ // now, get the right index
+ int pw_pos2 = get_password(to_join);
+ rsl = irc_cmd_join(s, to_join, to_join + pw_pos2 + 1);
+ // and revert
+ revert_password(to_join, pw_pos);
} else {
info("Will not join because --no-auto-join was set\n");
}
} else {
info("Unrecognized command: %s", line);
}
+ // and we go back to the previous state
+ pw_pos = get_password(chan);
} else if ((arg = MATCH_CMD(line, "topic"))) {
rsl = irc_cmd_topic(s, chan, arg);
} else if ((arg = MATCH_CMD0(line, "quit"))) {
@@ -1073,10 +1079,10 @@ int do_cmd_msg(irc_session_t *s, char *chan, char* line)
free(knick);
} else if ((arg = MATCH_CMD0(line, "say"))) {
// just a way to escape messages starting by '/'
- rsl = do_say(s, chan, arg + (*arg?1:0));
+ rsl = do_say(s, chan, password, arg + (*arg?1:0));
} else if (line[1] == ' ') {
// another way, compatible with irssi: "/ /message"
- rsl = do_say(s, chan, line + 2);
+ rsl = do_say(s, chan, password, line + 2);
} else {
info("Unrecognized or malformed command: %s", line);
}
@@ -1084,8 +1090,9 @@ int do_cmd_msg(irc_session_t *s, char *chan, char* line)
// with correct user tracking!
} else {
/* TODO2 only join channels we haven't joined yet */
- if (args.join)
- join_channel(s, chan);
+ if (args.join) {
+ rsl = irc_cmd_join(s, chan, password);
+ }
if (args.track != NO) {
char lline[MAX_LINE_LEN + MAX_NICK_LEN + 2];
@@ -1100,7 +1107,7 @@ int do_cmd_msg(irc_session_t *s, char *chan, char* line)
break;
}
if (seppos == -1) {
- rsl = do_say(s, chan, line);
+ rsl = do_say(s, chan, password, line);
} else {
char sep;
sep = line[seppos];
@@ -1114,12 +1121,15 @@ int do_cmd_msg(irc_session_t *s, char *chan, char* line)
pthread_mutex_unlock(&fifos.ctrl.mutex);
line[seppos] = sep;
strncat(lline, line + seppos, MAX_LINE_LEN-1);
- rsl = do_say(s, chan, lline);
+ rsl = do_say(s, chan, password, lline);
}
} else {
- rsl = do_say(s, chan, line);
+ rsl = do_say(s, chan, password, line);
}
}
+
+ revert_password(chan, pw_pos);
+
if (rsl)
return rsl;
@@ -1417,7 +1427,9 @@ void event_connect (irc_session_t *session, const char *event, const char *origi
for (i = 0; i < ctx->n_channels; i++) {
debug("Attempt to join %s\n", ctx->channels[i]);
- join_channel (session, ctx->channels[i]);
+ int pw_pos = get_password(ctx->channels[i]);
+ irc_cmd_join (session, ctx->channels[i], ctx->channels[i] + pw_pos + 1);
+ revert_password(ctx->channels[i], pw_pos);
}
}
diff --git a/test/password.sh b/test/password.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+trap 'kill $(jobs -p)' EXIT
+
+(echo -e "/mode +n\n/mode +k hunter2"; tail -f /dev/null) |
+ ../irctk op@localhost \#test:useless > heard &
+PID=$!
+sleep 2
+echo ok | ../irctk ok@localhost \#test:hunter2 2>/dev/null >/dev/null
+echo ko | ../irctk ko@localhost \#test:hunter3 2>/dev/null >/dev/null
+sleep 2
+kill $PID
+grep "ok" heard > /dev/null && grep -v "ko" heard > /dev/null
+