summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
authorJilles Tjoelker <jilles@irssi.org>2008-11-28 00:16:51 +0000
committerjilles <jilles@dbcabf3a-b0e7-0310-adc4-f8d773084564>2008-11-28 00:16:51 +0000
commit89cd47bf3a937c3077acdc95d98cc4b389e30608 (patch)
treee96f73aa452cc2fbec41f45f973cfaf42acacb3a /src/irc
parentaefa7b47c14f2bd8801b233907a84de4f6eee3b8 (diff)
downloadirssi-89cd47bf3a937c3077acdc95d98cc4b389e30608.zip
Allow storing multiple "other" prefixes such as +q and +a.
Original patch by JasonX, somewhat changed by exg and me. git-svn-id: file:///var/www/svn.irssi.org/SVN/irssi/trunk@4922 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/core/irc-expandos.c18
-rw-r--r--src/irc/core/irc-nicklist.c14
-rw-r--r--src/irc/core/irc-session.c6
-rw-r--r--src/irc/core/modes.c59
-rw-r--r--src/irc/core/modes.h3
-rw-r--r--src/irc/core/netsplit.c2
-rw-r--r--src/irc/core/netsplit.h2
-rw-r--r--src/irc/proxy/dump.c10
8 files changed, 80 insertions, 34 deletions
diff --git a/src/irc/core/irc-expandos.c b/src/irc/core/irc-expandos.c
index 901edc6a..0c0da643 100644
--- a/src/irc/core/irc-expandos.c
+++ b/src/irc/core/irc-expandos.c
@@ -86,18 +86,12 @@ static char *expando_usermode(SERVER_REC *server, void *item, int *free_ret)
static char *expando_cumode(SERVER_REC *server, void *item, int *free_ret)
{
if (IS_IRC_CHANNEL(item) && CHANNEL(item)->ownnick) {
- char other = NICK(CHANNEL(item)->ownnick)->other;
- if (other != '\0') {
- char *cumode = g_malloc(2);
- cumode[0] = other;
- cumode[1] = '\0';
- *free_ret = TRUE;
- return cumode;
- }
-
- return NICK(CHANNEL(item)->ownnick)->op ? "@" :
- NICK(CHANNEL(item)->ownnick)->halfop ? "%" :
- NICK(CHANNEL(item)->ownnick)->voice ? "+" : "";
+ char prefix = NICK(CHANNEL(item)->ownnick)->prefixes[0];
+ char *cumode = g_malloc(2);
+ cumode[0] = prefix;
+ cumode[1] = '\0';
+ *free_ret = TRUE;
+ return cumode; /* will be "\0\0" = "" if there is no prefix */
}
return "";
}
diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c
index 7d97196f..81bb6cfe 100644
--- a/src/irc/core/irc-nicklist.c
+++ b/src/irc/core/irc-nicklist.c
@@ -99,7 +99,8 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data)
IRC_CHANNEL_REC *chanrec;
NICK_REC *rec;
char *params, *type, *channel, *names, *ptr;
- int op, halfop, voice, other;
+ int op, halfop, voice;
+ char prefixes[MAX_USER_PREFIXES+1];
g_return_if_fail(data != NULL);
@@ -137,9 +138,11 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data)
/* some servers show ".@nick", there's also been talk about
showing "@+nick" and since none of these chars are valid
nick chars, just check them until a non-nickflag char is
- found. FIXME: we just ignore owner char now. */
- op = halfop = voice = other = FALSE;
+ found. */
+ op = halfop = voice = FALSE;
+ prefixes[0] = '\0';
while (isnickflag(server, *ptr)) {
+ prefix_add(prefixes, *ptr, (SERVER_REC *) server);
switch (*ptr) {
case '@':
op = TRUE;
@@ -150,8 +153,6 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data)
case '+':
voice = TRUE;
break;
- default:
- other = *ptr;
}
ptr++;
}
@@ -159,8 +160,7 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data)
if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) {
rec = irc_nicklist_insert(chanrec, ptr, op, halfop,
voice, FALSE);
- if (other)
- rec->other = other;
+ memcpy(rec->prefixes, prefixes, sizeof(rec->prefixes));
}
}
diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c
index ac2b0a07..5cd5cc43 100644
--- a/src/irc/core/irc-session.c
+++ b/src/irc/core/irc-session.c
@@ -114,7 +114,6 @@ static void sig_session_restore_nick(IRC_CHANNEL_REC *channel,
CONFIG_NODE *node)
{
const char *nick;
- char *other;
int op, halfop, voice;
NICK_REC *nickrec;
@@ -129,8 +128,9 @@ static void sig_session_restore_nick(IRC_CHANNEL_REC *channel,
voice = config_node_get_bool(node, "voice", FALSE);
halfop = config_node_get_bool(node, "halfop", FALSE);
nickrec = irc_nicklist_insert(channel, nick, op, halfop, voice, FALSE);
- other = config_node_get_str(node, "other", NULL);
- nickrec->other = other == NULL ? '\0' : other[0];
+ strocpy(nickrec->prefixes,
+ config_node_get_str(node, "prefixes", ""),
+ sizeof(nickrec->prefixes));
}
static void session_restore_channel(IRC_CHANNEL_REC *channel)
diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c
index 994a55f3..5c4a45da 100644
--- a/src/irc/core/modes.c
+++ b/src/irc/core/modes.c
@@ -46,8 +46,12 @@ static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick,
if (mode == '@') nickrec->op = type == '+';
else if (mode == '+') nickrec->voice = type == '+';
else if (mode == '%') nickrec->halfop = type == '+';
- else if (channel->server->prefix[(unsigned char) mode] != '\0')
- nickrec->other = (type == '+' ? mode : '\0');
+ if (channel->server->prefix[(unsigned char) mode] != '\0') {
+ if (type == '+')
+ prefix_add(nickrec->prefixes, mode, (SERVER_REC *) channel->server);
+ else
+ prefix_del(nickrec->prefixes, mode);
+ }
modestr[0] = mode; modestr[1] = '\0';
typestr[0] = type; typestr[1] = '\0';
@@ -55,6 +59,57 @@ static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick,
channel, nickrec, setby, modestr, typestr);
}
+void prefix_add(char *prefixes, char newprefix, SERVER_REC *server)
+{
+ const char *prefixlst;
+ char newprefixes[MAX_USER_PREFIXES+1]; /* to hold the new prefixes */
+ unsigned int newpos = 0; /* to hold our position in the new prefixes */
+ unsigned int oldpos = 0; /* to hold our position in the old prefixes */
+
+ prefixlst = server->get_nick_flags(server);
+
+ /* go through the possible prefixes, copy higher ones, and find this one's place
+ * always leave room for the current prefix to be added, though.
+ */
+ while (*prefixlst != '\0' && prefixes[oldpos] != '\0' &&
+ newpos < MAX_USER_PREFIXES - 1) {
+ if (prefixes[oldpos] == newprefix)
+ return; /* already inserted. why are we here? */
+
+ if (*prefixlst == newprefix)
+ break; /* insert the new prefix here */
+
+ if (*prefixlst == prefixes[oldpos]) {
+ /* this prefix is present.
+ * the one we are inserting goes after it.
+ * copy it over, and continue searching.
+ */
+ newprefixes[newpos++] = prefixes[oldpos++];
+ }
+ prefixlst++;
+ }
+
+ /* newpos is now the position in which we wish to insert the prefix */
+ newprefixes[newpos++] = newprefix;
+
+ /* finish copying the remaining prefixes */
+ while (prefixes[oldpos] != '\0' && newpos < MAX_USER_PREFIXES)
+ newprefixes[newpos++] = prefixes[oldpos++];
+
+ newprefixes[newpos] = '\0';
+
+ memcpy(prefixes, newprefixes, sizeof(prefixes));
+}
+
+void prefix_del(char *prefixes, char oldprefix)
+{
+ char *todel;
+
+ todel = strchr(prefixes, oldprefix);
+ if (todel)
+ memmove(todel, todel+1, strlen(todel));
+}
+
static int mode_is_set(const char *str, char mode)
{
char *end, *pos;
diff --git a/src/irc/core/modes.h b/src/irc/core/modes.h
index 70b19042..e9326c7a 100644
--- a/src/irc/core/modes.h
+++ b/src/irc/core/modes.h
@@ -54,6 +54,9 @@ void channel_set_singlemode(IRC_CHANNEL_REC *channel, const char *nicks,
void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
const char *mode);
+void prefix_add(char *prefixes, char newprefix, SERVER_REC *server);
+void prefix_del(char *prefixes, char oldprefix);
+
mode_func_t modes_type_a;
mode_func_t modes_type_b;
mode_func_t modes_type_c;
diff --git a/src/irc/core/netsplit.c b/src/irc/core/netsplit.c
index 51f3a630..269d2556 100644
--- a/src/irc/core/netsplit.c
+++ b/src/irc/core/netsplit.c
@@ -135,7 +135,7 @@ static NETSPLIT_REC *netsplit_add(IRC_SERVER_REC *server, const char *nick,
splitchan->op = nickrec->op;
splitchan->halfop = nickrec->halfop;
splitchan->voice = nickrec->voice;
- splitchan->other = nickrec->other;
+ memcpy(splitchan->prefixes, nickrec->prefixes, sizeof(splitchan->prefixes));
rec->channels = g_slist_append(rec->channels, splitchan);
}
diff --git a/src/irc/core/netsplit.h b/src/irc/core/netsplit.h
index 23e6d636..cbe3f26f 100644
--- a/src/irc/core/netsplit.h
+++ b/src/irc/core/netsplit.h
@@ -28,7 +28,7 @@ typedef struct {
unsigned int op:1;
unsigned int halfop:1;
unsigned int voice:1;
- unsigned int other:7;
+ char prefixes[MAX_USER_PREFIXES+1];
} NETSPLIT_CHAN_REC;
void netsplit_init(void);
diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c
index a7a996d5..5829023d 100644
--- a/src/irc/proxy/dump.c
+++ b/src/irc/proxy/dump.c
@@ -180,14 +180,8 @@ static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client)
else
g_string_append_c(str, ' ');
- if (nick->other)
- g_string_append_c(str, nick->other);
- else if (nick->op)
- g_string_append_c(str, '@');
- else if (nick->halfop)
- g_string_append_c(str, '%');
- else if (nick->voice)
- g_string_append_c(str, '+');
+ if (nick->prefixes[0])
+ g_string_append_c(str, nick->prefixes[0]);
g_string_append(str, nick->nick);
}
g_slist_free(nicks);