summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2004-01-25 18:18:18 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2004-01-25 18:18:18 +0000
commit33e7528edb3a22bbc90f122a948fb47e22df4bd0 (patch)
tree55a016fbadfbbe271f7aad07fafe3014e79c69be /src
parentd94a55a38b50f13b846b8f9b506a8614a5f2d485 (diff)
downloadirssi-33e7528edb3a22bbc90f122a948fb47e22df4bd0.zip
isupport updates
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3219 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src')
-rw-r--r--src/fe-common/irc/fe-netjoin.c36
-rw-r--r--src/irc/core/irc-nicklist.c10
-rw-r--r--src/irc/core/irc-servers.c31
-rw-r--r--src/irc/core/modes.c14
-rw-r--r--src/irc/core/modes.h5
5 files changed, 60 insertions, 36 deletions
diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c
index 2629d462..70833a3d 100644
--- a/src/fe-common/irc/fe-netjoin.c
+++ b/src/fe-common/irc/fe-netjoin.c
@@ -321,10 +321,11 @@ static void msg_join(IRC_SERVER_REC *server, const char *channel,
signal_stop();
}
-static int netjoin_set_nickmode(NETJOIN_REC *rec, const char *channel,
- char mode)
+static int netjoin_set_nickmode(IRC_SERVER_REC *server, NETJOIN_REC *rec,
+ const char *channel, char prefix)
{
GSList *pos;
+ const char *flags;
char *found_chan = NULL;
for (pos = rec->now_channels; pos != NULL; pos = pos->next) {
@@ -338,26 +339,25 @@ static int netjoin_set_nickmode(NETJOIN_REC *rec, const char *channel,
if (found_chan == NULL)
return FALSE;
- if (found_chan[0] == '@')
- return TRUE;
- if (found_chan[0] == '%' && mode == '+')
- return TRUE;
-
- found_chan[0] = mode;
+ flags = server->get_nick_flags(SERVER(server));
+ while (*flags != '\0') {
+ if (found_chan[0] == *flags)
+ break;
+ if (prefix == *flags) {
+ found_chan[0] = prefix;
+ break;
+ }
+ flags++;
+ }
return TRUE;
}
-#define isnickmode(c) \
- ((c) == 'o' || (c) == 'v' || (c) == 'h')
-#define nickmodechar(c) \
- ((c) == 'o' ? '@' : ((c) == 'v' ? '+' : ((c) == 'h' ? '%' : '\0')))
-
static void msg_mode(IRC_SERVER_REC *server, const char *channel,
const char *sender, const char *addr, const char *data)
{
NETJOIN_REC *rec;
char *params, *mode, *nicks;
- char **nicklist, **nick, type, modechr;
+ char **nicklist, **nick, type, prefix;
int show;
g_return_if_fail(data != NULL);
@@ -378,12 +378,12 @@ static void msg_mode(IRC_SERVER_REC *server, const char *channel,
continue;
}
- if (*nick != NULL && isnickmode(*mode)) {
+ if (*nick != NULL && GET_MODE_PREFIX(server, *mode)) {
/* give/remove ops */
rec = netjoin_find(server, *nick);
- modechr = nickmodechar(*mode);
- if (rec == NULL || type != '+' || modechr == '\0' ||
- !netjoin_set_nickmode(rec, channel, modechr))
+ prefix = GET_MODE_PREFIX(server, *mode);
+ if (rec == NULL || type != '+' || prefix == '\0' ||
+ !netjoin_set_nickmode(server, rec, channel, prefix))
show = TRUE;
nick++;
} else {
diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c
index e5d25d5c..53c4abe0 100644
--- a/src/irc/core/irc-nicklist.c
+++ b/src/irc/core/irc-nicklist.c
@@ -404,15 +404,11 @@ static void sig_usermode(SERVER_REC *server)
static const char *get_nick_flags(SERVER_REC *server)
{
IRC_SERVER_REC *irc_server = (IRC_SERVER_REC *) server;
- static char *std = "@%+";
- char *prefix = g_hash_table_lookup(irc_server->isupport, "prefix");
+ const char *prefix =
+ g_hash_table_lookup(irc_server->isupport, "PREFIX");
- if (prefix == NULL)
- return std;
prefix = strchr(prefix, ')');
- if (prefix != NULL || *++prefix == '\0') /* FIXME: ugly to modify it */
- return std;
- return prefix;
+ return prefix == NULL ? "" : prefix+1;
}
static void sig_connected(IRC_SERVER_REC *server)
diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c
index 6e139c9b..c3a342c5 100644
--- a/src/irc/core/irc-servers.c
+++ b/src/irc/core/irc-servers.c
@@ -162,7 +162,11 @@ static void server_init(IRC_SERVER_REC *server)
}
server->isupport = g_hash_table_new((GHashFunc) g_istr_hash,
- (GCompareFunc) g_istr_equal);
+ (GCompareFunc) g_istr_equal);
+
+ /* set the standards */
+ g_hash_table_insert(server->isupport, "CHANMODES", "b,k,l,imnpst");
+ g_hash_table_insert(server->isupport, "PREFIX", "(ohv)@%+");
server->cmdcount = 0;
}
@@ -309,7 +313,11 @@ static void sig_disconnected(IRC_SERVER_REC *server)
g_slist_free(server->cmdqueue);
server->cmdqueue = NULL;
- g_hash_table_foreach(server->isupport, (GHFunc) isupport_destroy_hash, server);
+ if (server->isupport_sent) {
+ /* these are dynamically allocated only if isupport was sent */
+ g_hash_table_foreach(server->isupport,
+ (GHFunc) isupport_destroy_hash, server);
+ }
g_hash_table_destroy(server->isupport);
server->isupport = NULL;
@@ -588,6 +596,11 @@ static void parse_prefix(IRC_SERVER_REC *server, const char *sptr)
}
}
+static gboolean hash_clear(gpointer key, gpointer value, gpointer user_data)
+{
+ return TRUE;
+}
+
static void event_isupport(IRC_SERVER_REC *server, const char *data)
{
char **item, *sptr, *eptr;
@@ -602,6 +615,9 @@ static void event_isupport(IRC_SERVER_REC *server, const char *data)
return;
sptr++;
+ /* remove defaults */
+ g_hash_table_foreach_remove(server->isupport, hash_clear, NULL);
+
isupport = g_strsplit(sptr, " ", -1);
for(item = isupport; *item != NULL; item++) {
@@ -639,12 +655,19 @@ static void event_isupport(IRC_SERVER_REC *server, const char *data)
}
g_strfreev(isupport);
+ /* chanmodes/prefix will fully override defaults */
+ memset(server->modes, 0, sizeof(server->modes));
+ memset(server->prefix, 0, sizeof(server->prefix));
+
if ((sptr = g_hash_table_lookup(server->isupport, "CHANMODES")))
parse_chanmodes(server, sptr);
/* This is after chanmode because some servers define modes in both */
- if ((sptr = g_hash_table_lookup(server->isupport, "PREFIX")))
- parse_prefix(server, sptr);
+ if ((sptr = g_hash_table_lookup(server->isupport, "PREFIX")) == NULL) {
+ sptr = g_strdup("(ohv)@%+");
+ g_hash_table_insert(server->isupport, g_strdup("PREFIX"), sptr);
+ }
+ parse_prefix(server, sptr);
if ((sptr = g_hash_table_lookup(server->isupport, "MODES"))) {
server->max_modes_in_cmd = atoi(sptr);
diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c
index 159d375c..57609e71 100644
--- a/src/irc/core/modes.c
+++ b/src/irc/core/modes.c
@@ -187,15 +187,15 @@ static void mode_set(IRC_SERVER_REC *server, GString *str,
}
static void mode_set_arg(IRC_SERVER_REC *server, GString *str,
- char type, char mode, const char *arg)
+ char type, char mode, const char *arg, int user)
{
g_return_if_fail(str != NULL);
g_return_if_fail(type == '-' || arg != NULL);
if (type == '-')
- mode_remove(server, str, mode, TRUE);
+ mode_remove(server, str, mode, user);
else
- mode_add_sorted(server, str, mode, arg, TRUE);
+ mode_add_sorted(server, str, mode, arg, user);
}
/* Mode that needs a parameter of a mask for both setting and removing (eg: bans) */
@@ -213,12 +213,12 @@ void modes_type_a(IRC_CHANNEL_REC *channel, const char *setby, char type,
/* Mode that needs parameter for both setting and removing (eg: +k) */
void modes_type_b(IRC_CHANNEL_REC *channel, const char *setby, char type,
- char mode, char *arg, GString *newmode)
+ char mode, char *arg, GString *newmode)
{
if (mode == 'k') {
if (*arg == '\0' && type == '+')
arg = channel->key != NULL ? channel->key : "???";
- mode_set_arg(channel->server, newmode, type, 'k', arg);
+ mode_set_arg(channel->server, newmode, type, 'k', arg, FALSE);
if (arg != channel->key) {
g_free_and_null(channel->key);
@@ -233,7 +233,7 @@ void modes_type_c(IRC_CHANNEL_REC *channel, const char *setby,
char type, char mode, char *arg, GString *newmode)
{
if (mode == 'l') {
- mode_set_arg(channel->server, newmode, type, 'l', arg);
+ mode_set_arg(channel->server, newmode, type, 'l', arg, FALSE);
channel->limit = type == '-' ? 0 : atoi(arg);
}
}
@@ -355,7 +355,7 @@ char *modes_join(IRC_SERVER_REC *server, const char *old,
mode_set(server, newmode, type, *curmode, !channel);
else {
mode_set_arg(server, newmode, type, *curmode,
- cmd_get_param(&modestr));
+ cmd_get_param(&modestr), !channel);
}
curmode++;
diff --git a/src/irc/core/modes.h b/src/irc/core/modes.h
index d5af8403..70b19042 100644
--- a/src/irc/core/modes.h
+++ b/src/irc/core/modes.h
@@ -30,6 +30,11 @@ struct modes_type {
((type) == '+' ? HAS_MODE_ARG_SET(server,mode) : \
HAS_MODE_ARG_UNSET(server, mode))
+#define GET_MODE_PREFIX(server, c) \
+ ((server)->modes[(int)(unsigned char)c].prefix)
+#define GET_PREFIX_MODE(server, c) \
+ ((server)->prefix[(int)(unsigned char)c])
+
void modes_init(void);
void modes_deinit(void);
void modes_server_init(IRC_SERVER_REC *);