mirror of
https://github.com/irssi/irssi.git
synced 2025-02-02 15:08:01 -05:00
isupport patch by David Leadbeater
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3211 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
3ccbd0405b
commit
217283caea
@ -219,7 +219,7 @@ static void event_connected(SERVER_REC *server)
|
|||||||
|
|
||||||
static int match_nick_flags(SERVER_REC *server, NICK_REC *nick, char flag)
|
static int match_nick_flags(SERVER_REC *server, NICK_REC *nick, char flag)
|
||||||
{
|
{
|
||||||
const char *flags = server->get_nick_flags();
|
const char *flags = server->get_nick_flags(server);
|
||||||
|
|
||||||
return strchr(flags, flag) == NULL ||
|
return strchr(flags, flag) == NULL ||
|
||||||
(flag == flags[0] && nick->op) ||
|
(flag == flags[0] && nick->op) ||
|
||||||
@ -259,7 +259,7 @@ void channel_send_autocommands(CHANNEL_REC *channel)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
nick = nicklist_find_mask(channel,
|
nick = nicklist_find_mask(channel,
|
||||||
channel->server->isnickflag(*botnick) ?
|
channel->server->isnickflag(channel->server, *botnick) ?
|
||||||
botnick+1 : botnick);
|
botnick+1 : botnick);
|
||||||
if (nick != NULL &&
|
if (nick != NULL &&
|
||||||
match_nick_flags(channel->server, nick, *botnick)) {
|
match_nick_flags(channel->server, nick, *botnick)) {
|
||||||
|
@ -345,7 +345,7 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
|
|||||||
GHashTable *optlist;
|
GHashTable *optlist;
|
||||||
char *target, *origtarget, *msg;
|
char *target, *origtarget, *msg;
|
||||||
void *free_arg;
|
void *free_arg;
|
||||||
int free_ret, target_type;
|
int free_ret, target_type = SEND_TARGET_NICK;
|
||||||
|
|
||||||
g_return_if_fail(data != NULL);
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
@ -398,7 +398,6 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
|
|||||||
|
|
||||||
if (target != NULL)
|
if (target != NULL)
|
||||||
server->send_message(server, target, msg, target_type);
|
server->send_message(server, target, msg, target_type);
|
||||||
|
|
||||||
signal_emit(target != NULL && target_type == SEND_TARGET_CHANNEL ?
|
signal_emit(target != NULL && target_type == SEND_TARGET_CHANNEL ?
|
||||||
"message own_public" : "message own_private", 4,
|
"message own_public" : "message own_private", 4,
|
||||||
server, msg, target, origtarget);
|
server, msg, target, origtarget);
|
||||||
|
@ -19,6 +19,7 @@ unsigned int send_massjoin:1; /* Waiting to be sent in massjoin signal */
|
|||||||
unsigned int op:1;
|
unsigned int op:1;
|
||||||
unsigned int halfop:1;
|
unsigned int halfop:1;
|
||||||
unsigned int voice:1;
|
unsigned int voice:1;
|
||||||
|
unsigned int other:7;
|
||||||
|
|
||||||
/*GHashTable *module_data;*/
|
/*GHashTable *module_data;*/
|
||||||
|
|
||||||
|
@ -369,7 +369,10 @@ int nicklist_compare(NICK_REC *p1, NICK_REC *p2)
|
|||||||
* returns :-)
|
* returns :-)
|
||||||
* -- yath */
|
* -- yath */
|
||||||
|
|
||||||
if (p1->op)
|
/* Treat others as highest - should really use order in 005 numeric */
|
||||||
|
if (p1->other)
|
||||||
|
status1 = 5;
|
||||||
|
else if (p1->op)
|
||||||
status1 = 4;
|
status1 = 4;
|
||||||
else if (p1->halfop)
|
else if (p1->halfop)
|
||||||
status1 = 3;
|
status1 = 3;
|
||||||
@ -378,7 +381,9 @@ int nicklist_compare(NICK_REC *p1, NICK_REC *p2)
|
|||||||
else
|
else
|
||||||
status1 = 1;
|
status1 = 1;
|
||||||
|
|
||||||
if (p2->op)
|
if (p2->other)
|
||||||
|
status2 = 5;
|
||||||
|
else if (p2->op)
|
||||||
status2 = 4;
|
status2 = 4;
|
||||||
else if (p2->halfop)
|
else if (p2->halfop)
|
||||||
status2 = 3;
|
status2 = 3;
|
||||||
|
@ -53,12 +53,12 @@ GSList *queries;
|
|||||||
channel keys etc. */
|
channel keys etc. */
|
||||||
void (*channels_join)(SERVER_REC *server, const char *data, int automatic);
|
void (*channels_join)(SERVER_REC *server, const char *data, int automatic);
|
||||||
/* returns true if `flag' indicates a nick flag (op/voice/halfop) */
|
/* returns true if `flag' indicates a nick flag (op/voice/halfop) */
|
||||||
int (*isnickflag)(char flag);
|
int (*isnickflag)(SERVER_REC *server, char flag);
|
||||||
/* returns true if `data' indicates a channel */
|
/* returns true if `data' indicates a channel */
|
||||||
int (*ischannel)(SERVER_REC *server, const char *data);
|
int (*ischannel)(SERVER_REC *server, const char *data);
|
||||||
/* returns all nick flag characters in order op, voice, halfop. If some
|
/* returns all nick flag characters in order op, voice, halfop. If some
|
||||||
of them aren't supported '\0' can be used. */
|
of them aren't supported '\0' can be used. */
|
||||||
const char *(*get_nick_flags)(void);
|
const char *(*get_nick_flags)(SERVER_REC *server);
|
||||||
/* send public or private message to server */
|
/* send public or private message to server */
|
||||||
void (*send_message)(SERVER_REC *server, const char *target,
|
void (*send_message)(SERVER_REC *server, const char *target,
|
||||||
const char *msg, int target_type);
|
const char *msg, int target_type);
|
||||||
|
@ -118,12 +118,17 @@ static void cmd_upgrade(const char *data)
|
|||||||
static void session_save_nick(CHANNEL_REC *channel, NICK_REC *nick,
|
static void session_save_nick(CHANNEL_REC *channel, NICK_REC *nick,
|
||||||
CONFIG_REC *config, CONFIG_NODE *node)
|
CONFIG_REC *config, CONFIG_NODE *node)
|
||||||
{
|
{
|
||||||
|
static char other[2];
|
||||||
node = config_node_section(node, NULL, NODE_TYPE_BLOCK);
|
node = config_node_section(node, NULL, NODE_TYPE_BLOCK);
|
||||||
|
|
||||||
config_node_set_str(config, node, "nick", nick->nick);
|
config_node_set_str(config, node, "nick", nick->nick);
|
||||||
config_node_set_bool(config, node, "op", nick->op);
|
config_node_set_bool(config, node, "op", nick->op);
|
||||||
config_node_set_bool(config, node, "halfop", nick->halfop);
|
config_node_set_bool(config, node, "halfop", nick->halfop);
|
||||||
config_node_set_bool(config, node, "voice", nick->voice);
|
config_node_set_bool(config, node, "voice", nick->voice);
|
||||||
|
|
||||||
|
other[0] = nick->other;
|
||||||
|
other[1] = '\0';
|
||||||
|
config_node_set_str(config, node, "other", other);
|
||||||
|
|
||||||
signal_emit("session save nick", 4, channel, nick, config, node);
|
signal_emit("session save nick", 4, channel, nick, config, node);
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,9 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
|
|||||||
for (tmp = nicklist; tmp != NULL; tmp = tmp->next) {
|
for (tmp = nicklist; tmp != NULL; tmp = tmp->next) {
|
||||||
NICK_REC *rec = tmp->data;
|
NICK_REC *rec = tmp->data;
|
||||||
|
|
||||||
if (rec->op)
|
if (rec->other)
|
||||||
|
nickmode[0] = rec->other;
|
||||||
|
else if (rec->op)
|
||||||
nickmode[0] = '@';
|
nickmode[0] = '@';
|
||||||
else if (rec->halfop)
|
else if (rec->halfop)
|
||||||
nickmode[0] = '%';
|
nickmode[0] = '%';
|
||||||
|
@ -116,12 +116,19 @@ char *expand_emphasis(WI_ITEM_REC *item, const char *text)
|
|||||||
static char *channel_get_nickmode_rec(NICK_REC *nickrec)
|
static char *channel_get_nickmode_rec(NICK_REC *nickrec)
|
||||||
{
|
{
|
||||||
char *emptystr;
|
char *emptystr;
|
||||||
|
static char nickmode[2]; /* FIXME: bad */
|
||||||
|
|
||||||
if (!settings_get_bool("show_nickmode"))
|
if (!settings_get_bool("show_nickmode"))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
emptystr = settings_get_bool("show_nickmode_empty") ? " " : "";
|
emptystr = settings_get_bool("show_nickmode_empty") ? " " : "";
|
||||||
|
|
||||||
|
if (nickrec != NULL && nickrec->other) {
|
||||||
|
nickmode[0] = nickrec->other;
|
||||||
|
nickmode[1] = '\0';
|
||||||
|
return nickmode;
|
||||||
|
}
|
||||||
|
|
||||||
return nickrec == NULL ? emptystr :
|
return nickrec == NULL ? emptystr :
|
||||||
nickrec->op ? "@" :
|
nickrec->op ? "@" :
|
||||||
nickrec->halfop ? "%" :
|
nickrec->halfop ? "%" :
|
||||||
|
@ -945,6 +945,7 @@ void fe_events_numeric_init(void)
|
|||||||
signal_add("default event numeric", (SIGNAL_FUNC) event_numeric);
|
signal_add("default event numeric", (SIGNAL_FUNC) event_numeric);
|
||||||
signal_add("event 001", (SIGNAL_FUNC) event_received);
|
signal_add("event 001", (SIGNAL_FUNC) event_received);
|
||||||
signal_add("event 004", (SIGNAL_FUNC) event_received);
|
signal_add("event 004", (SIGNAL_FUNC) event_received);
|
||||||
|
signal_add("event 005", (SIGNAL_FUNC) event_received);
|
||||||
signal_add("event 254", (SIGNAL_FUNC) event_received);
|
signal_add("event 254", (SIGNAL_FUNC) event_received);
|
||||||
signal_add("event 364", (SIGNAL_FUNC) event_received);
|
signal_add("event 364", (SIGNAL_FUNC) event_received);
|
||||||
signal_add("event 365", (SIGNAL_FUNC) event_received);
|
signal_add("event 365", (SIGNAL_FUNC) event_received);
|
||||||
@ -1033,6 +1034,7 @@ void fe_events_numeric_deinit(void)
|
|||||||
signal_remove("default event numeric", (SIGNAL_FUNC) event_numeric);
|
signal_remove("default event numeric", (SIGNAL_FUNC) event_numeric);
|
||||||
signal_remove("event 001", (SIGNAL_FUNC) event_received);
|
signal_remove("event 001", (SIGNAL_FUNC) event_received);
|
||||||
signal_remove("event 004", (SIGNAL_FUNC) event_received);
|
signal_remove("event 004", (SIGNAL_FUNC) event_received);
|
||||||
|
signal_remove("event 005", (SIGNAL_FUNC) event_received);
|
||||||
signal_remove("event 254", (SIGNAL_FUNC) event_received);
|
signal_remove("event 254", (SIGNAL_FUNC) event_received);
|
||||||
signal_remove("event 364", (SIGNAL_FUNC) event_received);
|
signal_remove("event 364", (SIGNAL_FUNC) event_received);
|
||||||
signal_remove("event 365", (SIGNAL_FUNC) event_received);
|
signal_remove("event 365", (SIGNAL_FUNC) event_received);
|
||||||
|
@ -387,7 +387,7 @@ static void msg_mode(IRC_SERVER_REC *server, const char *channel,
|
|||||||
show = TRUE;
|
show = TRUE;
|
||||||
nick++;
|
nick++;
|
||||||
} else {
|
} else {
|
||||||
if (HAS_MODE_ARG(type, *mode) && *nick != NULL)
|
if (HAS_MODE_ARG(server, type, *mode) && *nick != NULL)
|
||||||
nick++;
|
nick++;
|
||||||
show = TRUE;
|
show = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -623,28 +623,39 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item
|
|||||||
chanrec = irc_channel_find(server, channame);
|
chanrec = irc_channel_find(server, channame);
|
||||||
if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
|
if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
|
||||||
|
|
||||||
/* send notice to all ops */
|
/* See if the server has advertised support of wallchops */
|
||||||
nicks = NULL;
|
if (g_hash_table_lookup(chanrec->server->isupport, "statusmsg") ||
|
||||||
g_hash_table_foreach(chanrec->nicks, (GHFunc) cmd_wall_hash, &nicks);
|
g_hash_table_lookup(chanrec->server->isupport, "wallchops"))
|
||||||
|
irc_send_cmdv(server, "NOTICE @%s :%s", chanrec->name, msg);
|
||||||
|
else {
|
||||||
|
/* Fall back to manually noticing each op */
|
||||||
|
nicks = NULL;
|
||||||
|
g_hash_table_foreach(chanrec->nicks,
|
||||||
|
(GHFunc) cmd_wall_hash, &nicks);
|
||||||
|
|
||||||
args = g_strconcat(chanrec->name, " ", msg, NULL);
|
args = g_strconcat(chanrec->name, " ", msg, NULL);
|
||||||
msg = parse_special_string(settings_get_str("wall_format"),
|
msg = parse_special_string(settings_get_str("wall_format"),
|
||||||
SERVER(server), item, args, NULL, 0);
|
SERVER(server), item, args, NULL, 0);
|
||||||
g_free(args);
|
g_free(args);
|
||||||
|
|
||||||
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
|
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
|
||||||
NICK_REC *rec = tmp->data;
|
NICK_REC *rec = tmp->data;
|
||||||
|
|
||||||
if (rec != chanrec->ownnick)
|
if (rec != chanrec->ownnick) {
|
||||||
irc_send_cmdv(server, "NOTICE %s :%s", rec->nick, msg);
|
irc_send_cmdv(server, "NOTICE %s :%s",
|
||||||
|
rec->nick, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free(msg);
|
||||||
|
g_slist_free(nicks);
|
||||||
}
|
}
|
||||||
g_free(msg);
|
|
||||||
g_slist_free(nicks);
|
|
||||||
|
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SYNTAX: WALLCHOPS <channel> <message> */
|
/* SYNTAX: WALLCHOPS <channel> <message> */
|
||||||
|
/* ircu is the only major server i can see which supports this
|
||||||
|
and it supports NOTICE @#channel anyway */
|
||||||
static void cmd_wallchops(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
|
static void cmd_wallchops(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
|
||||||
{
|
{
|
||||||
char *channame, *msg;
|
char *channame, *msg;
|
||||||
|
@ -82,10 +82,19 @@ static char *expando_usermode(SERVER_REC *server, void *item, int *free_ret)
|
|||||||
return IS_IRC_SERVER(server) ? IRC_SERVER(server)->usermode : "";
|
return IS_IRC_SERVER(server) ? IRC_SERVER(server)->usermode : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expands to your usermode on channel, op '@', halfop '%', "+" voice */
|
/* expands to your usermode on channel, op '@', halfop '%', "+" voice or other */
|
||||||
static char *expando_cumode(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) {
|
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 ? "@" :
|
return NICK(CHANNEL(item)->ownnick)->op ? "@" :
|
||||||
NICK(CHANNEL(item)->ownnick)->halfop ? "%" :
|
NICK(CHANNEL(item)->ownnick)->halfop ? "%" :
|
||||||
NICK(CHANNEL(item)->ownnick)->voice ? "+" : "";
|
NICK(CHANNEL(item)->ownnick)->voice ? "+" : "";
|
||||||
|
@ -74,11 +74,32 @@ char *irc_nick_strip(const char *nick)
|
|||||||
return stripped;
|
return stripped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int irc_nickcmp_rfc1459(const char *m, const char *n)
|
||||||
|
{
|
||||||
|
while (*m != '\0' && *n != '\0') {
|
||||||
|
if (to_rfc1459(*m) != to_rfc1459(*n))
|
||||||
|
return -1;
|
||||||
|
m++; n++;
|
||||||
|
}
|
||||||
|
return *m == *n ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int irc_nickcmp_ascii(const char *m, const char *n)
|
||||||
|
{
|
||||||
|
while (*m != '\0' && *n != '\0') {
|
||||||
|
if (to_ascii(*m) != to_ascii(*n))
|
||||||
|
return -1;
|
||||||
|
m++; n++;
|
||||||
|
}
|
||||||
|
return *m == *n ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void event_names_list(IRC_SERVER_REC *server, const char *data)
|
static void event_names_list(IRC_SERVER_REC *server, const char *data)
|
||||||
{
|
{
|
||||||
IRC_CHANNEL_REC *chanrec;
|
IRC_CHANNEL_REC *chanrec;
|
||||||
|
NICK_REC *rec;
|
||||||
char *params, *type, *channel, *names, *ptr;
|
char *params, *type, *channel, *names, *ptr;
|
||||||
int op, halfop, voice;
|
int op, halfop, voice, other;
|
||||||
|
|
||||||
g_return_if_fail(data != NULL);
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
@ -117,8 +138,8 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data)
|
|||||||
showing "@+nick" and since none of these chars are valid
|
showing "@+nick" and since none of these chars are valid
|
||||||
nick chars, just check them until a non-nickflag char is
|
nick chars, just check them until a non-nickflag char is
|
||||||
found. FIXME: we just ignore owner char now. */
|
found. FIXME: we just ignore owner char now. */
|
||||||
op = halfop = voice = FALSE;
|
op = halfop = voice = other = FALSE;
|
||||||
while (isnickflag(*ptr)) {
|
while (isnickflag(server, *ptr)) {
|
||||||
switch (*ptr) {
|
switch (*ptr) {
|
||||||
case '@':
|
case '@':
|
||||||
op = TRUE;
|
op = TRUE;
|
||||||
@ -129,13 +150,17 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data)
|
|||||||
case '+':
|
case '+':
|
||||||
voice = TRUE;
|
voice = TRUE;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
other = *ptr;
|
||||||
}
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) {
|
if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) {
|
||||||
irc_nicklist_insert(chanrec, ptr, op, halfop,
|
rec = irc_nicklist_insert(chanrec, ptr, op, halfop,
|
||||||
voice, FALSE);
|
voice, FALSE);
|
||||||
|
if (other)
|
||||||
|
rec->other = other;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,17 +401,24 @@ static void sig_usermode(SERVER_REC *server)
|
|||||||
nicklist_update_flags(server, server->nick, server->usermode_away, -1);
|
nicklist_update_flags(server, server->nick, server->usermode_away, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *get_nick_flags(void)
|
static const char *get_nick_flags(SERVER_REC *server)
|
||||||
{
|
{
|
||||||
return "@+%";
|
IRC_SERVER_REC *irc_server = (IRC_SERVER_REC *) server;
|
||||||
|
static char *std = "@%+";
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_connected(IRC_SERVER_REC *server)
|
static void sig_connected(IRC_SERVER_REC *server)
|
||||||
{
|
{
|
||||||
if (IS_IRC_SERVER(server)) {
|
if (IS_IRC_SERVER(server))
|
||||||
server->get_nick_flags =
|
server->get_nick_flags = get_nick_flags;
|
||||||
(const char *(*)(void)) get_nick_flags;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void irc_nicklist_init(void)
|
void irc_nicklist_init(void)
|
||||||
|
@ -10,7 +10,14 @@ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick,
|
|||||||
/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */
|
/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */
|
||||||
char *irc_nick_strip(const char *nick);
|
char *irc_nick_strip(const char *nick);
|
||||||
|
|
||||||
|
int irc_nickcmp_rfc1459(const char *, const char *);
|
||||||
|
int irc_nickcmp_ascii(const char *, const char *);
|
||||||
|
|
||||||
void irc_nicklist_init(void);
|
void irc_nicklist_init(void);
|
||||||
void irc_nicklist_deinit(void);
|
void irc_nicklist_deinit(void);
|
||||||
|
|
||||||
|
/* FIXME: to_rfc1459() is missing things */
|
||||||
|
#define to_rfc1459(x) ((x) >= 65 && (x) <= 94 ? (x) + 32 : (x))
|
||||||
|
#define to_ascii(x) ((x) >= 65 && (x) <= 94 ? (x) + 32 : (x))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
#include "irc-nicklist.h"
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
#include "irc-queries.h"
|
#include "irc-queries.h"
|
||||||
|
|
||||||
@ -40,6 +41,20 @@ QUERY_REC *irc_query_create(const char *server_tag,
|
|||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUERY_REC *irc_query_find(IRC_SERVER_REC *server, const char *nick)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
for (tmp = server->queries; tmp != NULL; tmp = tmp->next) {
|
||||||
|
QUERY_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (server->nick_comp_func(rec->name, nick) == 0)
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void check_query_changes(IRC_SERVER_REC *server, const char *nick,
|
static void check_query_changes(IRC_SERVER_REC *server, const char *nick,
|
||||||
const char *address, const char *target)
|
const char *address, const char *target)
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
void irc_queries_init(void);
|
void irc_queries_init(void);
|
||||||
void irc_queries_deinit(void);
|
void irc_queries_deinit(void);
|
||||||
|
|
||||||
#define irc_query_find(server, name) \
|
QUERY_REC *irc_query_find(IRC_SERVER_REC *server, const char *nick);
|
||||||
query_find(SERVER(server), name)
|
|
||||||
|
|
||||||
QUERY_REC *irc_query_create(const char *server_tag,
|
QUERY_REC *irc_query_create(const char *server_tag,
|
||||||
const char *nick, int automatic);
|
const char *nick, int automatic);
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "queries.h"
|
#include "queries.h"
|
||||||
|
|
||||||
|
#include "irc-nicklist.h"
|
||||||
|
#include "irc-queries.h"
|
||||||
#include "irc-servers-setup.h"
|
#include "irc-servers-setup.h"
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
#include "channel-rejoin.h"
|
#include "channel-rejoin.h"
|
||||||
@ -55,9 +57,11 @@ void irc_servers_reconnect_deinit(void);
|
|||||||
|
|
||||||
static int cmd_tag;
|
static int cmd_tag;
|
||||||
|
|
||||||
static int isnickflag_func(char flag)
|
static int isnickflag_func(SERVER_REC *server, char flag)
|
||||||
{
|
{
|
||||||
return isnickflag(flag);
|
IRC_SERVER_REC *irc_server = (IRC_SERVER_REC *) server;
|
||||||
|
|
||||||
|
return isnickflag(irc_server, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ischannel_func(SERVER_REC *server, const char *data)
|
static int ischannel_func(SERVER_REC *server, const char *data)
|
||||||
@ -157,6 +161,9 @@ static void server_init(IRC_SERVER_REC *server)
|
|||||||
conn->address, conn->port);
|
conn->address, conn->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server->isupport = g_hash_table_new((GHashFunc) g_istr_hash,
|
||||||
|
(GCompareFunc) g_istr_equal);
|
||||||
|
|
||||||
server->cmdcount = 0;
|
server->cmdcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +205,8 @@ SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn)
|
|||||||
ircconn->max_msgs : DEFAULT_MAX_MSGS;
|
ircconn->max_msgs : DEFAULT_MAX_MSGS;
|
||||||
server->connrec->use_ssl = conn->use_ssl;
|
server->connrec->use_ssl = conn->use_ssl;
|
||||||
|
|
||||||
|
modes_server_init(server);
|
||||||
|
|
||||||
server_connect_init((SERVER_REC *) server);
|
server_connect_init((SERVER_REC *) server);
|
||||||
return (SERVER_REC *) server;
|
return (SERVER_REC *) server;
|
||||||
}
|
}
|
||||||
@ -268,6 +277,9 @@ static void sig_connected(IRC_SERVER_REC *server)
|
|||||||
server->isnickflag = isnickflag_func;
|
server->isnickflag = isnickflag_func;
|
||||||
server->ischannel = ischannel_func;
|
server->ischannel = ischannel_func;
|
||||||
server->send_message = send_message;
|
server->send_message = send_message;
|
||||||
|
server->query_find_func =
|
||||||
|
(QUERY_REC *(*)(SERVER_REC *, const char *)) irc_query_find;
|
||||||
|
server->nick_comp_func = irc_nickcmp_ascii;
|
||||||
|
|
||||||
server->splits = g_hash_table_new((GHashFunc) g_istr_hash,
|
server->splits = g_hash_table_new((GHashFunc) g_istr_hash,
|
||||||
(GCompareFunc) g_istr_equal);
|
(GCompareFunc) g_istr_equal);
|
||||||
@ -276,6 +288,12 @@ static void sig_connected(IRC_SERVER_REC *server)
|
|||||||
server_init(server);
|
server_init(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void isupport_destroy_hash(void *key, void *value)
|
||||||
|
{
|
||||||
|
g_free(key);
|
||||||
|
g_free(value);
|
||||||
|
}
|
||||||
|
|
||||||
static void sig_disconnected(IRC_SERVER_REC *server)
|
static void sig_disconnected(IRC_SERVER_REC *server)
|
||||||
{
|
{
|
||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
@ -291,6 +309,10 @@ static void sig_disconnected(IRC_SERVER_REC *server)
|
|||||||
g_slist_free(server->cmdqueue);
|
g_slist_free(server->cmdqueue);
|
||||||
server->cmdqueue = NULL;
|
server->cmdqueue = NULL;
|
||||||
|
|
||||||
|
g_hash_table_foreach(server->isupport, (GHFunc) isupport_destroy_hash, server);
|
||||||
|
g_hash_table_destroy(server->isupport);
|
||||||
|
server->isupport = NULL;
|
||||||
|
|
||||||
g_free_and_null(server->wanted_usermode);
|
g_free_and_null(server->wanted_usermode);
|
||||||
g_free_and_null(server->real_address);
|
g_free_and_null(server->real_address);
|
||||||
g_free_and_null(server->usermode);
|
g_free_and_null(server->usermode);
|
||||||
@ -452,7 +474,7 @@ static int sig_set_user_mode(IRC_SERVER_REC *server)
|
|||||||
|
|
||||||
mode = server->connrec->usermode;
|
mode = server->connrec->usermode;
|
||||||
newmode = server->usermode == NULL ? NULL :
|
newmode = server->usermode == NULL ? NULL :
|
||||||
modes_join(server->usermode, mode, FALSE);
|
modes_join(NULL, server->usermode, mode, FALSE);
|
||||||
|
|
||||||
if (newmode == NULL || strcmp(newmode, server->usermode) != 0) {
|
if (newmode == NULL || strcmp(newmode, server->usermode) != 0) {
|
||||||
/* change the user mode. we used to do some trickery to
|
/* change the user mode. we used to do some trickery to
|
||||||
@ -521,6 +543,123 @@ static void event_server_info(IRC_SERVER_REC *server, const char *data)
|
|||||||
g_free(params);
|
g_free(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_chanmodes(IRC_SERVER_REC *server, const char *sptr)
|
||||||
|
{
|
||||||
|
mode_func_t *modefuncs[] = {
|
||||||
|
modes_type_a,
|
||||||
|
modes_type_b,
|
||||||
|
modes_type_c,
|
||||||
|
modes_type_d
|
||||||
|
};
|
||||||
|
char **item, **chanmodes;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
chanmodes = g_strsplit(sptr, ",", 5); /* ignore extras */
|
||||||
|
|
||||||
|
for (i = 0, item = chanmodes; *item != NULL && i < 4; item++, i++) {
|
||||||
|
unsigned char *p = *item;
|
||||||
|
while (*p != '\0') {
|
||||||
|
server->modes[(int)*p].func = modefuncs[i];
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev(chanmodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_prefix(IRC_SERVER_REC *server, const char *sptr)
|
||||||
|
{
|
||||||
|
const char *eptr;
|
||||||
|
|
||||||
|
if (*sptr++ != '(')
|
||||||
|
return; /* Unknown prefix format */
|
||||||
|
|
||||||
|
eptr = strchr(sptr, ')');
|
||||||
|
if (eptr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
eptr++;
|
||||||
|
while (*sptr != '\0' && *eptr != '\0' && *sptr != ')' && *eptr != ' ') {
|
||||||
|
server->modes[(int)(unsigned char) *sptr].func =
|
||||||
|
modes_type_prefix;
|
||||||
|
server->modes[(int)(unsigned char) *sptr].prefix = *eptr;
|
||||||
|
server->prefix[(int)(unsigned char) *eptr] = *sptr;
|
||||||
|
sptr++; eptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_isupport(IRC_SERVER_REC *server, const char *data)
|
||||||
|
{
|
||||||
|
char **item, *sptr, *eptr;
|
||||||
|
char **isupport;
|
||||||
|
|
||||||
|
g_return_if_fail(server != NULL);
|
||||||
|
|
||||||
|
server->isupport_sent = TRUE;
|
||||||
|
|
||||||
|
sptr = strchr(data, ' ');
|
||||||
|
if (sptr == NULL)
|
||||||
|
return;
|
||||||
|
sptr++;
|
||||||
|
|
||||||
|
isupport = g_strsplit(sptr, " ", -1);
|
||||||
|
|
||||||
|
for(item = isupport; *item != NULL; item++) {
|
||||||
|
int removed = FALSE;
|
||||||
|
gpointer key = NULL, value = NULL;
|
||||||
|
|
||||||
|
if (**item == ':')
|
||||||
|
break;
|
||||||
|
|
||||||
|
sptr = strchr(*item, '=');
|
||||||
|
if (sptr != NULL) {
|
||||||
|
*sptr = '\0';
|
||||||
|
sptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
eptr = *item;
|
||||||
|
if(*eptr == '-') {
|
||||||
|
removed = TRUE;
|
||||||
|
eptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_hash_table_lookup_extended(server->isupport, eptr,
|
||||||
|
&key, &value) && removed)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (removed)
|
||||||
|
g_hash_table_remove(server->isupport, eptr);
|
||||||
|
else {
|
||||||
|
g_hash_table_insert(server->isupport, g_strdup(eptr),
|
||||||
|
g_strdup(sptr != NULL ? sptr : ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(key);
|
||||||
|
g_free(value);
|
||||||
|
}
|
||||||
|
g_strfreev(isupport);
|
||||||
|
|
||||||
|
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, "MODES"))) {
|
||||||
|
server->max_modes_in_cmd = atoi(sptr);
|
||||||
|
if (server->max_modes_in_cmd < 1)
|
||||||
|
server->max_modes_in_cmd = DEFAULT_MAX_MODES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sptr = g_hash_table_lookup(server->isupport, "CASEMAPPING"))) {
|
||||||
|
if (strstr(sptr, "rfc1459") != NULL)
|
||||||
|
server->nick_comp_func = irc_nickcmp_rfc1459;
|
||||||
|
else
|
||||||
|
server->nick_comp_func = irc_nickcmp_ascii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void event_motd(IRC_SERVER_REC *server, const char *data, const char *from)
|
static void event_motd(IRC_SERVER_REC *server, const char *data, const char *from)
|
||||||
{
|
{
|
||||||
if (server->connected)
|
if (server->connected)
|
||||||
@ -599,6 +738,7 @@ void irc_servers_init(void)
|
|||||||
signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit);
|
signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit);
|
||||||
signal_add("event 001", (SIGNAL_FUNC) event_connected);
|
signal_add("event 001", (SIGNAL_FUNC) event_connected);
|
||||||
signal_add("event 004", (SIGNAL_FUNC) event_server_info);
|
signal_add("event 004", (SIGNAL_FUNC) event_server_info);
|
||||||
|
signal_add("event 005", (SIGNAL_FUNC) event_isupport);
|
||||||
signal_add("event 375", (SIGNAL_FUNC) event_motd);
|
signal_add("event 375", (SIGNAL_FUNC) event_motd);
|
||||||
signal_add_last("event 376", (SIGNAL_FUNC) event_end_of_motd);
|
signal_add_last("event 376", (SIGNAL_FUNC) event_end_of_motd);
|
||||||
signal_add_last("event 422", (SIGNAL_FUNC) event_end_of_motd); /* no motd */
|
signal_add_last("event 422", (SIGNAL_FUNC) event_end_of_motd); /* no motd */
|
||||||
@ -623,6 +763,7 @@ void irc_servers_deinit(void)
|
|||||||
signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit);
|
signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit);
|
||||||
signal_remove("event 001", (SIGNAL_FUNC) event_connected);
|
signal_remove("event 001", (SIGNAL_FUNC) event_connected);
|
||||||
signal_remove("event 004", (SIGNAL_FUNC) event_server_info);
|
signal_remove("event 004", (SIGNAL_FUNC) event_server_info);
|
||||||
|
signal_remove("event 005", (SIGNAL_FUNC) event_isupport);
|
||||||
signal_remove("event 375", (SIGNAL_FUNC) event_motd);
|
signal_remove("event 375", (SIGNAL_FUNC) event_motd);
|
||||||
signal_remove("event 376", (SIGNAL_FUNC) event_end_of_motd);
|
signal_remove("event 376", (SIGNAL_FUNC) event_end_of_motd);
|
||||||
signal_remove("event 422", (SIGNAL_FUNC) event_end_of_motd); /* no motd */
|
signal_remove("event 422", (SIGNAL_FUNC) event_end_of_motd); /* no motd */
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "chat-protocols.h"
|
#include "chat-protocols.h"
|
||||||
#include "servers.h"
|
#include "servers.h"
|
||||||
|
#include "modes.h"
|
||||||
|
|
||||||
/* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */
|
/* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */
|
||||||
#define IRC_SERVER(server) \
|
#define IRC_SERVER(server) \
|
||||||
@ -61,6 +62,7 @@ struct _IRC_SERVER_REC {
|
|||||||
unsigned int disable_lag:1; /* Disable lag detection (PING command doesn't exist) */
|
unsigned int disable_lag:1; /* Disable lag detection (PING command doesn't exist) */
|
||||||
unsigned int nick_collision:1; /* We're just now being killed because of nick collision */
|
unsigned int nick_collision:1; /* We're just now being killed because of nick collision */
|
||||||
unsigned int motd_got:1; /* We've received MOTD */
|
unsigned int motd_got:1; /* We've received MOTD */
|
||||||
|
unsigned int isupport_sent:1; /* Server has sent us an isupport reply */
|
||||||
|
|
||||||
int max_kicks_in_cmd; /* max. number of people to kick with one /KICK command */
|
int max_kicks_in_cmd; /* max. number of people to kick with one /KICK command */
|
||||||
int max_modes_in_cmd; /* max. number of mode changes in one /MODE command */
|
int max_modes_in_cmd; /* max. number of mode changes in one /MODE command */
|
||||||
@ -96,6 +98,12 @@ struct _IRC_SERVER_REC {
|
|||||||
channels go here if they're "temporarily unavailable"
|
channels go here if they're "temporarily unavailable"
|
||||||
because of netsplits */
|
because of netsplits */
|
||||||
void *chanqueries;
|
void *chanqueries;
|
||||||
|
|
||||||
|
GHashTable *isupport;
|
||||||
|
struct modes_type modes[256]; /* Stores the modes sent by a server in an isupport reply */
|
||||||
|
char prefix[256];
|
||||||
|
|
||||||
|
int (*nick_comp_func)(const char *, const char *); /* Function for comparing nicknames on this server */
|
||||||
};
|
};
|
||||||
|
|
||||||
SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn);
|
SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn);
|
||||||
|
@ -22,15 +22,25 @@
|
|||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
#include "net-sendbuffer.h"
|
#include "net-sendbuffer.h"
|
||||||
#include "lib-config/iconfig.h"
|
#include "lib-config/iconfig.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
#include "irc-channels.h"
|
#include "irc-channels.h"
|
||||||
#include "irc-nicklist.h"
|
#include "irc-nicklist.h"
|
||||||
|
|
||||||
|
struct _isupport_data { CONFIG_REC *config; CONFIG_NODE *node; };
|
||||||
|
|
||||||
|
static void session_isupport_foreach(char *key, char *value, struct _isupport_data *data)
|
||||||
|
{
|
||||||
|
config_node_set_str(data->config, data->node, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config,
|
static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config,
|
||||||
CONFIG_NODE *node)
|
CONFIG_NODE *node)
|
||||||
{
|
{
|
||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
|
CONFIG_NODE *isupport;
|
||||||
|
struct _isupport_data isupport_data;
|
||||||
|
|
||||||
if (!IS_IRC_SERVER(server))
|
if (!IS_IRC_SERVER(server))
|
||||||
return;
|
return;
|
||||||
@ -54,11 +64,19 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config,
|
|||||||
config_node_set_bool(config, node, "usermode_away", server->usermode_away);
|
config_node_set_bool(config, node, "usermode_away", server->usermode_away);
|
||||||
config_node_set_str(config, node, "away_reason", server->away_reason);
|
config_node_set_str(config, node, "away_reason", server->away_reason);
|
||||||
config_node_set_bool(config, node, "emode_known", server->emode_known);
|
config_node_set_bool(config, node, "emode_known", server->emode_known);
|
||||||
|
|
||||||
|
isupport = config_node_section(node, "isupport", NODE_TYPE_BLOCK);
|
||||||
|
isupport_data.config = config;
|
||||||
|
isupport_data.node = isupport;
|
||||||
|
|
||||||
|
g_hash_table_foreach(server->isupport, (GHFunc) session_isupport_foreach, &isupport_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_session_restore_server(IRC_SERVER_REC *server,
|
static void sig_session_restore_server(IRC_SERVER_REC *server,
|
||||||
CONFIG_NODE *node)
|
CONFIG_NODE *node)
|
||||||
{
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
if (!IS_IRC_SERVER(server))
|
if (!IS_IRC_SERVER(server))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -69,12 +87,33 @@ static void sig_session_restore_server(IRC_SERVER_REC *server,
|
|||||||
server->usermode_away = config_node_get_bool(node, "usermode_away", FALSE);
|
server->usermode_away = config_node_get_bool(node, "usermode_away", FALSE);
|
||||||
server->away_reason = g_strdup(config_node_get_str(node, "away_reason", NULL));
|
server->away_reason = g_strdup(config_node_get_str(node, "away_reason", NULL));
|
||||||
server->emode_known = config_node_get_bool(node, "emode_known", FALSE);
|
server->emode_known = config_node_get_bool(node, "emode_known", FALSE);
|
||||||
|
|
||||||
|
if (server->isupport == NULL) {
|
||||||
|
server->isupport = g_hash_table_new((GHashFunc) g_istr_hash,
|
||||||
|
(GCompareFunc) g_istr_equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
node = config_node_section(node, "isupport", -1);
|
||||||
|
tmp = config_node_first(node->value);
|
||||||
|
if(tmp != NULL)
|
||||||
|
server->isupport_sent = TRUE;
|
||||||
|
|
||||||
|
for (; tmp != NULL; tmp = config_node_next(tmp)) {
|
||||||
|
node = tmp->data;
|
||||||
|
if (node == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
g_hash_table_insert(server->isupport, g_strdup(node->key),
|
||||||
|
g_strdup(node->value));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_session_restore_nick(IRC_CHANNEL_REC *channel,
|
static void sig_session_restore_nick(IRC_CHANNEL_REC *channel,
|
||||||
CONFIG_NODE *node)
|
CONFIG_NODE *node)
|
||||||
{
|
{
|
||||||
const char *nick;
|
const char *nick;
|
||||||
|
char *other;
|
||||||
int op, halfop, voice;
|
int op, halfop, voice;
|
||||||
NICK_REC *nickrec;
|
NICK_REC *nickrec;
|
||||||
|
|
||||||
@ -89,6 +128,8 @@ static void sig_session_restore_nick(IRC_CHANNEL_REC *channel,
|
|||||||
voice = config_node_get_bool(node, "voice", FALSE);
|
voice = config_node_get_bool(node, "voice", FALSE);
|
||||||
halfop = config_node_get_bool(node, "halfop", FALSE);
|
halfop = config_node_get_bool(node, "halfop", FALSE);
|
||||||
nickrec = irc_nicklist_insert(channel, nick, op, halfop, voice, FALSE);
|
nickrec = irc_nicklist_insert(channel, nick, op, halfop, voice, FALSE);
|
||||||
|
other = config_node_get_str(node, "other", FALSE);
|
||||||
|
nickrec->other = other[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void session_restore_channel(IRC_CHANNEL_REC *channel)
|
static void session_restore_channel(IRC_CHANNEL_REC *channel)
|
||||||
|
@ -19,9 +19,8 @@ typedef struct _REDIRECT_REC REDIRECT_REC;
|
|||||||
((a) == '^' || (a) == '~' || \
|
((a) == '^' || (a) == '~' || \
|
||||||
(a) == '+' || (a) == '=' || (a) == '-')
|
(a) == '+' || (a) == '=' || (a) == '-')
|
||||||
|
|
||||||
#define isnickflag(a) \
|
#define isnickflag(server, a) \
|
||||||
((a) == '@' || (a) == '+' || (a) == '%' || /* op / voice */ \
|
(server->prefix[(int)(unsigned char) a] != '\0')
|
||||||
(a) == '%' || (a) == '.' || (a) == '!') /* extensions: half-op / owners */
|
|
||||||
|
|
||||||
#define ischannel(a) \
|
#define ischannel(a) \
|
||||||
((a) == '#' || /* normal */ \
|
((a) == '#' || /* normal */ \
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
/* Change nick's mode in channel */
|
/* Change nick's mode in channel */
|
||||||
static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick,
|
static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick,
|
||||||
const char mode, int type, const char *setby)
|
char mode, int type, const char *setby)
|
||||||
{
|
{
|
||||||
NICK_REC *nickrec;
|
NICK_REC *nickrec;
|
||||||
char modestr[2], typestr[2];
|
char modestr[2], typestr[2];
|
||||||
@ -44,8 +44,10 @@ static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick,
|
|||||||
if (nickrec == NULL) return; /* No /names list got yet */
|
if (nickrec == NULL) return; /* No /names list got yet */
|
||||||
|
|
||||||
if (mode == '@') nickrec->op = type == '+';
|
if (mode == '@') nickrec->op = type == '+';
|
||||||
if (mode == '+') nickrec->voice = type == '+';
|
else if (mode == '+') nickrec->voice = type == '+';
|
||||||
if (mode == '%') nickrec->halfop = type == '+';
|
else if (mode == '%') nickrec->halfop = type == '+';
|
||||||
|
else if (channel->server->prefix[(unsigned char) mode] != '\0')
|
||||||
|
nickrec->other = (type == '+' ? mode : '\0');
|
||||||
|
|
||||||
modestr[0] = mode; modestr[1] = '\0';
|
modestr[0] = mode; modestr[1] = '\0';
|
||||||
typestr[0] = type; typestr[1] = '\0';
|
typestr[0] = type; typestr[1] = '\0';
|
||||||
@ -97,13 +99,15 @@ static void mode_add_arg(GString *str, int pos, int updating, const char *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add mode character to list sorted alphabetically */
|
/* Add mode character to list sorted alphabetically */
|
||||||
static void mode_add_sorted(GString *str, char mode, const char *arg)
|
static void mode_add_sorted(IRC_SERVER_REC *server, GString *str,
|
||||||
|
char mode, const char *arg, int user)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int updating, argpos = 0;
|
int updating, argpos = 0;
|
||||||
|
|
||||||
/* check that mode isn't already set */
|
/* check that mode isn't already set */
|
||||||
if (!HAS_MODE_ARG_SET(mode) && mode_is_set(str->str, mode))
|
if ((!user && !HAS_MODE_ARG_SET(server, mode)) &&
|
||||||
|
mode_is_set(str->str, mode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updating = FALSE;
|
updating = FALSE;
|
||||||
@ -114,7 +118,7 @@ static void mode_add_sorted(GString *str, char mode, const char *arg)
|
|||||||
updating = TRUE;
|
updating = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (HAS_MODE_ARG_SET(*p))
|
if (!user && HAS_MODE_ARG_SET(server, *p))
|
||||||
argpos++;
|
argpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +158,7 @@ static void node_remove_arg(GString *str, int pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* remove mode (and it's argument) from string */
|
/* remove mode (and it's argument) from string */
|
||||||
static void mode_remove(GString *str, char mode)
|
static void mode_remove(IRC_SERVER_REC *server, GString *str, char mode, int user)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int argpos = 0;
|
int argpos = 0;
|
||||||
@ -162,34 +166,91 @@ static void mode_remove(GString *str, char mode)
|
|||||||
for (p = str->str; *p != '\0' && *p != ' '; p++) {
|
for (p = str->str; *p != '\0' && *p != ' '; p++) {
|
||||||
if (mode == *p) {
|
if (mode == *p) {
|
||||||
g_string_erase(str, (int) (p-str->str), 1);
|
g_string_erase(str, (int) (p-str->str), 1);
|
||||||
if (HAS_MODE_ARG_SET(mode))
|
if (!user && HAS_MODE_ARG_SET(server, mode))
|
||||||
node_remove_arg(str, argpos);
|
node_remove_arg(str, argpos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (HAS_MODE_ARG_SET(*p))
|
if (!user && HAS_MODE_ARG_SET(server, *p))
|
||||||
argpos++;
|
argpos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mode_set(GString *str, char type, char mode)
|
static void mode_set(IRC_SERVER_REC *server, GString *str,
|
||||||
|
char type, char mode, int user)
|
||||||
{
|
{
|
||||||
g_return_if_fail(str != NULL);
|
g_return_if_fail(str != NULL);
|
||||||
|
|
||||||
if (type == '-')
|
if (type == '-')
|
||||||
mode_remove(str, mode);
|
mode_remove(server, str, mode, user);
|
||||||
else
|
else
|
||||||
mode_add_sorted(str, mode, NULL);
|
mode_add_sorted(server, str, mode, NULL, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mode_set_arg(GString *str, char type, char mode, const char *arg)
|
static void mode_set_arg(IRC_SERVER_REC *server, GString *str,
|
||||||
|
char type, char mode, const char *arg)
|
||||||
{
|
{
|
||||||
g_return_if_fail(str != NULL);
|
g_return_if_fail(str != NULL);
|
||||||
g_return_if_fail(type == '-' || arg != NULL);
|
g_return_if_fail(type == '-' || arg != NULL);
|
||||||
|
|
||||||
if (type == '-')
|
if (type == '-')
|
||||||
mode_remove(str, mode);
|
mode_remove(server, str, mode, TRUE);
|
||||||
else
|
else
|
||||||
mode_add_sorted(str, mode, arg);
|
mode_add_sorted(server, str, mode, arg, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode that needs a parameter of a mask for both setting and removing (eg: bans) */
|
||||||
|
void modes_type_a(IRC_CHANNEL_REC *channel, const char *setby, char type,
|
||||||
|
char mode, char *arg, GString *newmode)
|
||||||
|
{
|
||||||
|
/* Currently only +b is dealt with */
|
||||||
|
if (mode == 'b') {
|
||||||
|
if (type == '+')
|
||||||
|
banlist_add(channel, arg, setby, time(NULL));
|
||||||
|
else
|
||||||
|
banlist_remove(channel, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
if (mode == 'k') {
|
||||||
|
if (*arg == '\0' && type == '+')
|
||||||
|
arg = channel->key != NULL ? channel->key : "???";
|
||||||
|
mode_set_arg(channel->server, newmode, type, 'k', arg);
|
||||||
|
|
||||||
|
if (arg != channel->key) {
|
||||||
|
g_free_and_null(channel->key);
|
||||||
|
if (type == '+')
|
||||||
|
channel->key = g_strdup(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode that needs parameter only for adding */
|
||||||
|
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);
|
||||||
|
channel->limit = type == '-' ? 0 : atoi(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode that takes no parameter */
|
||||||
|
void modes_type_d(IRC_CHANNEL_REC *channel, const char *setby,
|
||||||
|
char type, char mode, char *arg, GString *newmode)
|
||||||
|
{
|
||||||
|
mode_set(channel->server, newmode, type, mode, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void modes_type_prefix(IRC_CHANNEL_REC *channel, const char *setby,
|
||||||
|
char type, char mode, char *arg, GString *newmode)
|
||||||
|
{
|
||||||
|
int umode = (unsigned char) mode;
|
||||||
|
nick_mode_change(channel, arg, channel->server->modes[umode].prefix,
|
||||||
|
type, setby);
|
||||||
}
|
}
|
||||||
|
|
||||||
int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode)
|
int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode)
|
||||||
@ -204,8 +265,10 @@ int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode)
|
|||||||
void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
|
void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
|
||||||
const char *mode, int update_key)
|
const char *mode, int update_key)
|
||||||
{
|
{
|
||||||
|
IRC_SERVER_REC *server = channel->server;
|
||||||
GString *newmode;
|
GString *newmode;
|
||||||
char *dup, *modestr, *arg, *curmode, type;
|
char *dup, *modestr, *arg, *curmode, type;
|
||||||
|
int umode;
|
||||||
|
|
||||||
g_return_if_fail(IS_IRC_CHANNEL(channel));
|
g_return_if_fail(IS_IRC_CHANNEL(channel));
|
||||||
g_return_if_fail(mode != NULL);
|
g_return_if_fail(mode != NULL);
|
||||||
@ -216,7 +279,7 @@ void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
|
|||||||
dup = modestr = g_strdup(mode);
|
dup = modestr = g_strdup(mode);
|
||||||
curmode = cmd_get_param(&modestr);
|
curmode = cmd_get_param(&modestr);
|
||||||
while (*curmode != '\0') {
|
while (*curmode != '\0') {
|
||||||
if (HAS_MODE_ARG(type, *curmode)) {
|
if (HAS_MODE_ARG(server, type, *curmode)) {
|
||||||
/* get the argument for the mode. NOTE: We don't
|
/* get the argument for the mode. NOTE: We don't
|
||||||
get the +k's argument when joining to channel. */
|
get the +k's argument when joining to channel. */
|
||||||
arg = cmd_get_param(&modestr);
|
arg = cmd_get_param(&modestr);
|
||||||
@ -229,54 +292,17 @@ void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
|
|||||||
case '-':
|
case '-':
|
||||||
type = *curmode;
|
type = *curmode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b':
|
|
||||||
if (type == '+')
|
|
||||||
banlist_add(channel, arg, setby, time(NULL));
|
|
||||||
else
|
|
||||||
banlist_remove(channel, arg);
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
case 'O': /* channel owner in !channels */
|
|
||||||
if (g_strcasecmp(channel->server->nick, arg) == 0)
|
|
||||||
channel->chanop = type == '+';
|
|
||||||
nick_mode_change(channel, arg, '@', type, setby);
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
nick_mode_change(channel, arg, '%', type, setby);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
nick_mode_change(channel, arg, '+', type, setby);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
mode_set_arg(newmode, type, 'l', arg);
|
|
||||||
channel->limit = type == '-' ? 0 : atoi(arg);
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
if ((*arg == '\0' && type == '+') ||
|
|
||||||
(channel->key != NULL && !update_key)) {
|
|
||||||
arg = channel->key != NULL ? channel->key :
|
|
||||||
"???";
|
|
||||||
}
|
|
||||||
mode_set_arg(newmode, type, 'k', arg);
|
|
||||||
|
|
||||||
if (arg != channel->key) {
|
|
||||||
g_free_and_null(channel->key);
|
|
||||||
if (type == '+')
|
|
||||||
channel->key = g_strdup(arg);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
case 'I':
|
|
||||||
case 'q':
|
|
||||||
case 'd':
|
|
||||||
/* Don't set it as channel mode */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mode_set(newmode, type, *curmode);
|
umode = (unsigned char) *curmode;
|
||||||
break;
|
if (server->modes[umode].func != NULL) {
|
||||||
|
server->modes[umode].func(channel, setby,
|
||||||
|
type, *curmode, arg,
|
||||||
|
newmode);
|
||||||
|
} else {
|
||||||
|
/* Treat unknown modes as ones without params */
|
||||||
|
modes_type_d(channel, setby, type, *curmode,
|
||||||
|
arg, newmode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curmode++;
|
curmode++;
|
||||||
@ -305,7 +331,8 @@ void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
|
|||||||
/* add `mode' to `old' - return newly allocated mode.
|
/* add `mode' to `old' - return newly allocated mode.
|
||||||
`channel' specifies if we're parsing channel mode and we should try
|
`channel' specifies if we're parsing channel mode and we should try
|
||||||
to join mode arguments too. */
|
to join mode arguments too. */
|
||||||
char *modes_join(const char *old, const char *mode, int channel)
|
char *modes_join(IRC_SERVER_REC *server, const char *old,
|
||||||
|
const char *mode, int channel)
|
||||||
{
|
{
|
||||||
GString *newmode;
|
GString *newmode;
|
||||||
char *dup, *modestr, *curmode, type;
|
char *dup, *modestr, *curmode, type;
|
||||||
@ -324,10 +351,10 @@ char *modes_join(const char *old, const char *mode, int channel)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel || !HAS_MODE_ARG(type, *curmode))
|
if (!channel || !HAS_MODE_ARG(server, type, *curmode))
|
||||||
mode_set(newmode, type, *curmode);
|
mode_set(server, newmode, type, *curmode, !channel);
|
||||||
else {
|
else {
|
||||||
mode_set_arg(newmode, type, *curmode,
|
mode_set_arg(server, newmode, type, *curmode,
|
||||||
cmd_get_param(&modestr));
|
cmd_get_param(&modestr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +375,7 @@ static void parse_user_mode(IRC_SERVER_REC *server, const char *modestr)
|
|||||||
g_return_if_fail(IS_IRC_SERVER(server));
|
g_return_if_fail(IS_IRC_SERVER(server));
|
||||||
g_return_if_fail(modestr != NULL);
|
g_return_if_fail(modestr != NULL);
|
||||||
|
|
||||||
newmode = modes_join(server->usermode, modestr, FALSE);
|
newmode = modes_join(NULL, server->usermode, modestr, FALSE);
|
||||||
oldmode = server->usermode;
|
oldmode = server->usermode;
|
||||||
server->usermode = newmode;
|
server->usermode = newmode;
|
||||||
server->server_operator = (strchr(newmode, 'o') != NULL);
|
server->server_operator = (strchr(newmode, 'o') != NULL);
|
||||||
@ -430,7 +457,7 @@ static void sig_req_usermode_change(IRC_SERVER_REC *server, const char *data,
|
|||||||
&target, &mode);
|
&target, &mode);
|
||||||
if (!ischannel(*target)) {
|
if (!ischannel(*target)) {
|
||||||
/* we requested a user mode change, save this */
|
/* we requested a user mode change, save this */
|
||||||
mode = modes_join(server->wanted_usermode, mode, FALSE);
|
mode = modes_join(NULL, server->wanted_usermode, mode, FALSE);
|
||||||
g_free_not_null(server->wanted_usermode);
|
g_free_not_null(server->wanted_usermode);
|
||||||
server->wanted_usermode = mode;
|
server->wanted_usermode = mode;
|
||||||
}
|
}
|
||||||
@ -520,7 +547,7 @@ void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count == server->max_modes_in_cmd &&
|
if (count == server->max_modes_in_cmd &&
|
||||||
HAS_MODE_ARG(type, *curmode)) {
|
HAS_MODE_ARG(chanrec->server, type, *curmode)) {
|
||||||
irc_send_cmdv(server, "MODE %s %s%s",
|
irc_send_cmdv(server, "MODE %s %s%s",
|
||||||
channel, tmode->str, targs->str);
|
channel, tmode->str, targs->str);
|
||||||
|
|
||||||
@ -535,7 +562,7 @@ void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
|
|||||||
}
|
}
|
||||||
g_string_append_c(tmode, *curmode);
|
g_string_append_c(tmode, *curmode);
|
||||||
|
|
||||||
if (HAS_MODE_ARG(type, *curmode)) {
|
if (HAS_MODE_ARG(chanrec->server, type, *curmode)) {
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
@ -762,6 +789,29 @@ static void cmd_mode(const char *data, IRC_SERVER_REC *server,
|
|||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void modes_server_init(IRC_SERVER_REC *server)
|
||||||
|
{
|
||||||
|
server->modes['b'].func = modes_type_a;
|
||||||
|
server->modes['e'].func = modes_type_a;
|
||||||
|
server->modes['I'].func = modes_type_a;
|
||||||
|
|
||||||
|
server->modes['h'].func = modes_type_prefix;
|
||||||
|
server->modes['h'].prefix = '%';
|
||||||
|
server->modes['o'].func = modes_type_prefix;
|
||||||
|
server->modes['o'].prefix = '@';
|
||||||
|
server->modes['O'].func = modes_type_prefix;
|
||||||
|
server->modes['O'].prefix = '@';
|
||||||
|
server->modes['v'].func = modes_type_prefix;
|
||||||
|
server->modes['v'].prefix = '+';
|
||||||
|
|
||||||
|
server->prefix['%'] = 'h';
|
||||||
|
server->prefix['@'] = 'o';
|
||||||
|
server->prefix['+'] = 'v';
|
||||||
|
|
||||||
|
server->modes['l'].func = modes_type_b;
|
||||||
|
server->modes['k'].func = modes_type_c;
|
||||||
|
}
|
||||||
|
|
||||||
void modes_init(void)
|
void modes_init(void)
|
||||||
{
|
{
|
||||||
settings_add_str("misc", "opermode", "");
|
settings_add_str("misc", "opermode", "");
|
||||||
|
@ -1,30 +1,43 @@
|
|||||||
#ifndef __MODES_H
|
#ifndef __MODES_H
|
||||||
#define __MODES_H
|
#define __MODES_H
|
||||||
|
|
||||||
|
#include "irc-channels.h"
|
||||||
|
|
||||||
|
typedef void mode_func_t(IRC_CHANNEL_REC *, const char *, char, char,
|
||||||
|
char *, GString *);
|
||||||
|
|
||||||
|
struct modes_type {
|
||||||
|
mode_func_t *func;
|
||||||
|
char prefix;
|
||||||
|
};
|
||||||
|
|
||||||
/* modes that have argument always */
|
/* modes that have argument always */
|
||||||
#define HAS_MODE_ARG_ALWAYS(mode) \
|
#define HAS_MODE_ARG_ALWAYS(server, mode) \
|
||||||
((mode) == 'b' || (mode) == 'e' || (mode) == 'I' || (mode) == 'q' || \
|
(server->modes[(int)(unsigned char) mode].func == modes_type_a || \
|
||||||
(mode) == 'd' || (mode) == 'o' || (mode) == 'h' || (mode) == 'v' || \
|
server->modes[(int)(unsigned char) mode].func == modes_type_b || \
|
||||||
(mode) == 'O' || (mode) == 'k' || (mode) == 'f')
|
server->modes[(int)(unsigned char) mode].func == modes_type_prefix)
|
||||||
|
|
||||||
/* modes that have argument when being set (+) */
|
/* modes that have argument when being set (+) */
|
||||||
#define HAS_MODE_ARG_SET(mode) \
|
#define HAS_MODE_ARG_SET(server, mode) \
|
||||||
(HAS_MODE_ARG_ALWAYS(mode) || (mode) == 'l')
|
(HAS_MODE_ARG_ALWAYS(server, mode) || \
|
||||||
|
server->modes[(int)(unsigned char) mode].func == modes_type_c)
|
||||||
|
|
||||||
/* modes that have argument when being unset (-) */
|
/* modes that have argument when being unset (-) */
|
||||||
#define HAS_MODE_ARG_UNSET(mode) \
|
#define HAS_MODE_ARG_UNSET(server, mode) \
|
||||||
HAS_MODE_ARG_ALWAYS(mode)
|
HAS_MODE_ARG_ALWAYS(server, mode)
|
||||||
|
|
||||||
#define HAS_MODE_ARG(type, mode) \
|
#define HAS_MODE_ARG(server, type, mode) \
|
||||||
((type) == '+' ? HAS_MODE_ARG_SET(mode) : HAS_MODE_ARG_UNSET(mode))
|
((type) == '+' ? HAS_MODE_ARG_SET(server,mode) : \
|
||||||
|
HAS_MODE_ARG_UNSET(server, mode))
|
||||||
|
|
||||||
void modes_init(void);
|
void modes_init(void);
|
||||||
void modes_deinit(void);
|
void modes_deinit(void);
|
||||||
|
void modes_server_init(IRC_SERVER_REC *);
|
||||||
|
|
||||||
/* add `mode' to `old' - return newly allocated mode.
|
/* add `mode' to `old' - return newly allocated mode.
|
||||||
`channel' specifies if we're parsing channel mode and we should try
|
`channel' specifies if we're parsing channel mode and we should try
|
||||||
to join mode arguments too. */
|
to join mode arguments too. */
|
||||||
char *modes_join(const char *old, const char *mode, int channel);
|
char *modes_join(IRC_SERVER_REC *server, const char *old, const char *mode, int channel);
|
||||||
|
|
||||||
int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode);
|
int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode);
|
||||||
|
|
||||||
@ -36,4 +49,10 @@ void channel_set_singlemode(IRC_CHANNEL_REC *channel, const char *nicks,
|
|||||||
void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
|
void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
|
||||||
const char *mode);
|
const char *mode);
|
||||||
|
|
||||||
|
mode_func_t modes_type_a;
|
||||||
|
mode_func_t modes_type_b;
|
||||||
|
mode_func_t modes_type_c;
|
||||||
|
mode_func_t modes_type_d;
|
||||||
|
mode_func_t modes_type_prefix;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,6 +135,7 @@ static NETSPLIT_REC *netsplit_add(IRC_SERVER_REC *server, const char *nick,
|
|||||||
splitchan->op = nickrec->op;
|
splitchan->op = nickrec->op;
|
||||||
splitchan->halfop = nickrec->halfop;
|
splitchan->halfop = nickrec->halfop;
|
||||||
splitchan->voice = nickrec->voice;
|
splitchan->voice = nickrec->voice;
|
||||||
|
splitchan->other = nickrec->other;
|
||||||
|
|
||||||
rec->channels = g_slist_append(rec->channels, splitchan);
|
rec->channels = g_slist_append(rec->channels, splitchan);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ typedef struct {
|
|||||||
unsigned int op:1;
|
unsigned int op:1;
|
||||||
unsigned int halfop:1;
|
unsigned int halfop:1;
|
||||||
unsigned int voice:1;
|
unsigned int voice:1;
|
||||||
|
unsigned int other:7;
|
||||||
} NETSPLIT_CHAN_REC;
|
} NETSPLIT_CHAN_REC;
|
||||||
|
|
||||||
void netsplit_init(void);
|
void netsplit_init(void);
|
||||||
|
@ -177,7 +177,9 @@ static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client)
|
|||||||
else
|
else
|
||||||
g_string_append_c(str, ' ');
|
g_string_append_c(str, ' ');
|
||||||
|
|
||||||
if (nick->op)
|
if (nick->other)
|
||||||
|
g_string_append_c(str, nick->other);
|
||||||
|
else if (nick->op)
|
||||||
g_string_append_c(str, '@');
|
g_string_append_c(str, '@');
|
||||||
else if (nick->halfop)
|
else if (nick->halfop)
|
||||||
g_string_append_c(str, '%');
|
g_string_append_c(str, '%');
|
||||||
@ -213,8 +215,15 @@ void proxy_client_reset_nick(CLIENT_REC *client)
|
|||||||
client->nick = g_strdup(client->server->nick);
|
client->nick = g_strdup(client->server->nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void proxy_dump_data_005(char *key, char *value, GString *output)
|
||||||
|
{
|
||||||
|
g_string_sprintfa(output, "%s=%s ", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
void proxy_dump_data(CLIENT_REC *client)
|
void proxy_dump_data(CLIENT_REC *client)
|
||||||
{
|
{
|
||||||
|
GString *isupport_out;
|
||||||
|
|
||||||
proxy_client_reset_nick(client);
|
proxy_client_reset_nick(client);
|
||||||
|
|
||||||
/* welcome info */
|
/* welcome info */
|
||||||
@ -225,6 +234,17 @@ void proxy_dump_data(CLIENT_REC *client)
|
|||||||
proxy_outdata(client, ":%s 004 %s %s %s oirw abiklmnopqstv\n", client->proxy_address, client->nick, client->proxy_address, IRSSI_VERSION);
|
proxy_outdata(client, ":%s 004 %s %s %s oirw abiklmnopqstv\n", client->proxy_address, client->nick, client->proxy_address, IRSSI_VERSION);
|
||||||
else
|
else
|
||||||
proxy_outdata(client, ":%s 004 %s %s %s oirw abeIiklmnopqstv\n", client->proxy_address, client->nick, client->proxy_address, IRSSI_VERSION);
|
proxy_outdata(client, ":%s 004 %s %s %s oirw abeIiklmnopqstv\n", client->proxy_address, client->nick, client->proxy_address, IRSSI_VERSION);
|
||||||
|
|
||||||
|
if (client->server->isupport_sent) {
|
||||||
|
isupport_out = g_string_new(NULL);
|
||||||
|
g_string_sprintf(isupport_out, ":%s 005 %s ", client->proxy_address, client->nick);
|
||||||
|
/* FIXME: should be limited to 15 params */
|
||||||
|
g_hash_table_foreach(client->server->isupport, proxy_dump_data_005, isupport_out);
|
||||||
|
g_string_sprintfa(isupport_out, ":are supported by this server\n");
|
||||||
|
proxy_outdata(client, "%s", isupport_out->str);
|
||||||
|
g_string_free(isupport_out, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
proxy_outdata(client, ":%s 251 %s :There are 0 users and 0 invisible on 1 servers\n", client->proxy_address, client->nick);
|
proxy_outdata(client, ":%s 251 %s :There are 0 users and 0 invisible on 1 servers\n", client->proxy_address, client->nick);
|
||||||
proxy_outdata(client, ":%s 255 %s :I have 0 clients, 0 services and 0 servers\n", client->proxy_address, client->nick);
|
proxy_outdata(client, ":%s 255 %s :I have 0 clients, 0 services and 0 servers\n", client->proxy_address, client->nick);
|
||||||
proxy_outdata(client, ":%s 422 %s :MOTD File is missing\n", client->proxy_address, client->nick);
|
proxy_outdata(client, ":%s 422 %s :MOTD File is missing\n", client->proxy_address, client->nick);
|
||||||
|
@ -72,7 +72,7 @@ isnickflag(server, flag)
|
|||||||
Irssi::Server server
|
Irssi::Server server
|
||||||
char flag
|
char flag
|
||||||
CODE:
|
CODE:
|
||||||
RETVAL = server->isnickflag(flag);
|
RETVAL = server->isnickflag(server, flag);
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ char *
|
|||||||
get_nick_flags(server)
|
get_nick_flags(server)
|
||||||
Irssi::Server server
|
Irssi::Server server
|
||||||
CODE:
|
CODE:
|
||||||
RETVAL = (char *) server->get_nick_flags();
|
RETVAL = (char *) server->get_nick_flags(server);
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server)
|
|||||||
hv_store(hv, "max_msgs_in_cmd", 15, newSViv(server->max_msgs_in_cmd), 0);
|
hv_store(hv, "max_msgs_in_cmd", 15, newSViv(server->max_msgs_in_cmd), 0);
|
||||||
hv_store(hv, "max_modes_in_cmd", 16, newSViv(server->max_modes_in_cmd), 0);
|
hv_store(hv, "max_modes_in_cmd", 16, newSViv(server->max_modes_in_cmd), 0);
|
||||||
hv_store(hv, "max_whois_in_cmd", 16, newSViv(server->max_whois_in_cmd), 0);
|
hv_store(hv, "max_whois_in_cmd", 16, newSViv(server->max_whois_in_cmd), 0);
|
||||||
|
hv_store(hv, "isupport_sent", 13, newSViv(server->isupport_sent), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void perl_ban_fill_hash(HV *hv, BAN_REC *ban)
|
static void perl_ban_fill_hash(HV *hv, BAN_REC *ban)
|
||||||
|
@ -4,14 +4,15 @@ MODULE = Irssi::Irc::Modes PACKAGE = Irssi::Irc
|
|||||||
PROTOTYPES: ENABLE
|
PROTOTYPES: ENABLE
|
||||||
|
|
||||||
void
|
void
|
||||||
modes_join(old, mode, channel)
|
modes_join(server, old, mode, channel)
|
||||||
|
Irssi::Irc::Server server
|
||||||
char *old
|
char *old
|
||||||
char *mode
|
char *mode
|
||||||
int channel
|
int channel
|
||||||
PREINIT:
|
PREINIT:
|
||||||
char *ret;
|
char *ret;
|
||||||
PPCODE:
|
PPCODE:
|
||||||
ret = modes_join(old, mode, channel);
|
ret = modes_join(server, old, mode, channel);
|
||||||
XPUSHs(sv_2mortal(new_pv(ret)));
|
XPUSHs(sv_2mortal(new_pv(ret)));
|
||||||
g_free(ret);
|
g_free(ret);
|
||||||
|
|
||||||
|
@ -129,3 +129,13 @@ CODE:
|
|||||||
RETVAL = (char *) server_redirect_peek_signal(server, event, args, &redirection);
|
RETVAL = (char *) server_redirect_peek_signal(server, event, args, &redirection);
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
|
char *
|
||||||
|
server_isupport(server, name)
|
||||||
|
Irssi::Irc::Server server
|
||||||
|
char *name
|
||||||
|
CODE:
|
||||||
|
RETVAL = (char *) g_hash_table_lookup(server->isupport, name);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
@ -436,6 +436,7 @@ void perl_nick_fill_hash(HV *hv, NICK_REC *nick)
|
|||||||
hv_store(hv, "op", 2, newSViv(nick->op), 0);
|
hv_store(hv, "op", 2, newSViv(nick->op), 0);
|
||||||
hv_store(hv, "halfop", 6, newSViv(nick->halfop), 0);
|
hv_store(hv, "halfop", 6, newSViv(nick->halfop), 0);
|
||||||
hv_store(hv, "voice", 5, newSViv(nick->voice), 0);
|
hv_store(hv, "voice", 5, newSViv(nick->voice), 0);
|
||||||
|
hv_store(hv, "other", 5, newSViv(nick->other), 0);
|
||||||
|
|
||||||
hv_store(hv, "last_check", 10, newSViv(nick->last_check), 0);
|
hv_store(hv, "last_check", 10, newSViv(nick->last_check), 0);
|
||||||
hv_store(hv, "send_massjoin", 13, newSViv(nick->send_massjoin), 0);
|
hv_store(hv, "send_massjoin", 13, newSViv(nick->send_massjoin), 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user