From c8e7ce1c57afaebf3996a6712c45f4c89c34ba44 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 12 Aug 2012 15:15:16 +0200 Subject: [PATCH] rewrote IRC cache parser to be (hopefully) more stable --- src/ChanNode.c | 5 +- src/ChanNode.h | 1 - src/ChanUser.c | 2 + src/ChanUser.h | 2 + src/DBHelper.c | 33 +- src/IRCEvents.c | 18 +- src/IRCEvents.h | 15 +- src/IRCParser.c | 435 ++++++++---------- src/IRCParser.h | 2 +- src/UserNode.h | 3 +- src/modules.c | 4 +- src/modules/NeonFun.mod/bot_NeonFun.c | 8 +- src/modules/NeonFun.mod/game_4wins.c | 23 - src/modules/NeonFun.mod/game_4wins.h | 1 - src/modules/NeonFun.mod/game_uno.c | 13 - src/modules/NeonFun.mod/game_uno.h | 1 - src/modules/NeonHelp.mod/bot_NeonHelp.c | 30 +- src/modules/NeonServ.mod/bot_NeonServ.c | 2 - .../NeonServ.mod/event_neonserv_join.c | 15 +- .../NeonServ.mod/event_neonserv_part.c | 2 +- .../NeonServ.mod/event_neonserv_quit.c | 30 -- .../NeonSpam.mod/event_neonspam_join.c | 1 - src/modules/module.h | 4 +- src/tools.c | 2 +- src/version.h | 2 +- 25 files changed, 235 insertions(+), 419 deletions(-) delete mode 100644 src/modules/NeonServ.mod/event_neonserv_quit.c diff --git a/src/ChanNode.c b/src/ChanNode.c index fddde4c..23543c4 100644 --- a/src/ChanNode.c +++ b/src/ChanNode.c @@ -138,7 +138,6 @@ struct ChanNode* addChannel(const char *name) { chan->bans = NULL; chan->spam_settings = NULL; chan->usercount = 0; - chan->chanbot = NULL; chan->topic[0] = 0; chan->flags = 0; /* mode lists */ @@ -236,10 +235,8 @@ void freeChanNode(struct ChanNode* chan) { int checkChannelVisibility(struct ChanNode* chan) { struct ChanUser *chanuser, *next; for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { - if(chanuser->user->flags & USERFLAG_ISBOT) { - chan->chanbot = chanuser->user; + if(chanuser->user->flags & USERFLAG_ISBOT) return 1; - } } //free the channel... SYNCHRONIZE(cache_sync); diff --git a/src/ChanNode.h b/src/ChanNode.h index 756a6b4..4d7a348 100644 --- a/src/ChanNode.h +++ b/src/ChanNode.h @@ -40,7 +40,6 @@ struct ChanNode { struct ModeNode *modes; struct BanNode *bans; - struct UserNode *chanbot; struct trigger_cache *trigger; int channel_id; diff --git a/src/ChanUser.c b/src/ChanUser.c index ff29b70..0d370c1 100644 --- a/src/ChanUser.c +++ b/src/ChanUser.c @@ -30,6 +30,7 @@ struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user) { chanuser->flags = 0; chanuser->user = user; chanuser->chan = chan; + chanuser->visCount = 0; chanuser->changeTime = 0; chanuser->spamnode = NULL; @@ -58,6 +59,7 @@ struct ChanUser* addInvisibleChanUser(struct ChanNode *chan, struct UserNode *us chanuser->flags = CHANUSERFLAG_INVISIBLE; chanuser->user = user; chanuser->chan = chan; + chanuser->visCount = 0; chanuser->changeTime = 0; chanuser->spamnode = NULL; diff --git a/src/ChanUser.h b/src/ChanUser.h index f9f7163..43a6b7d 100644 --- a/src/ChanUser.h +++ b/src/ChanUser.h @@ -34,6 +34,8 @@ struct ChanUser { struct ChanNode *chan; struct UserNode *user; + int visCount; //visible counter - if this is 0, the ChanUser gets removed + int chageEvents; time_t changeTime; diff --git a/src/DBHelper.c b/src/DBHelper.c index 787b336..40d3be3 100644 --- a/src/DBHelper.c +++ b/src/DBHelper.c @@ -262,28 +262,35 @@ int renameAccount(char *oldauth, char *newauth) { static AUTHLOOKUP_CALLBACK(event_user_registered_auth_lookup); struct event_user_registered_cache { - struct UserNode *new_user; + struct UserNode *user; char *oldauth; }; -static int event_user_registered(struct UserNode *old_user, struct UserNode *new_user) { +static void event_user_registered(struct UserNode *user, char *new_mask) { //check if there is a fakehost on both sides... - if(!isFakeHost(old_user->host) || !isFakeHost(new_user->host)) return 0; + //extract host from new_mask + char *new_host = strchr(new_mask, '@'); + if(new_host) + new_host++; + else + return; + if(!isFakeHost(user->host) || !isFakeHost(new_host)) + return; //extract user names char oldauth[AUTHLEN], newauth[AUTHLEN]; char *p; - if((p = strstr(old_user->host, "."))) { + if((p = strstr(user->host, "."))) { *p = '\0'; - strcpy(oldauth, old_user->host); + strcpy(oldauth, user->host); *p = '.'; } - if((p = strstr(new_user->host, "."))) { + if((p = strstr(new_host, "."))) { *p = '\0'; - strcpy(newauth, new_user->host); + strcpy(newauth, new_host); *p = '.'; } if(!stricmp(oldauth, newauth)) - return 0; + return; //check if we know this user; then check the new auth MYSQL_RES *res; MYSQL_ROW row; @@ -293,21 +300,21 @@ static int event_user_registered(struct UserNode *old_user, struct UserNode *new struct event_user_registered_cache *cache = malloc(sizeof(*cache)); if (!cache) { perror("malloc() failed"); - return 1; + return; } - cache->new_user = new_user; + cache->user = user; cache->oldauth = strdup(oldauth); lookup_authname(newauth, 0, event_user_registered_auth_lookup, cache); } - return 1; + return; } static AUTHLOOKUP_CALLBACK(event_user_registered_auth_lookup) { struct event_user_registered_cache *cache = data; if(exists) { renameAccount(cache->oldauth, auth); - strcpy(cache->new_user->auth, auth); - cache->new_user->flags |= USERFLAG_ISAUTHED; + strcpy(cache->user->auth, auth); + cache->user->flags |= USERFLAG_ISAUTHED; } free(cache->oldauth); free(cache); diff --git a/src/IRCEvents.c b/src/IRCEvents.c index 7d41de5..56bc57e 100644 --- a/src/IRCEvents.c +++ b/src/IRCEvents.c @@ -160,11 +160,7 @@ FUNC_EVENT(nick, nick_func_t, BIND_TYPE_NICK, (struct UserNode *user, char *new_ FUNC_BIND(part, part_func_t, BIND_TYPE_PART) FUNC_UNBIND(part, part_func_t, BIND_TYPE_PART) -FUNC_EVENT(part, part_func_t, BIND_TYPE_PART, (struct ChanUser *chanuser, char *reason), (chanuser, reason)) - -FUNC_BIND(quit, quit_func_t, BIND_TYPE_QUIT) -FUNC_UNBIND(quit, quit_func_t, BIND_TYPE_QUIT) -FUNC_EVENT(quit, quit_func_t, BIND_TYPE_QUIT, (struct UserNode *user, char *reason), (user, reason)) +FUNC_EVENT(part, part_func_t, BIND_TYPE_PART, (struct ChanUser *chanuser, int quit, char *reason), (chanuser, quit, reason)) FUNC_BIND(kick, kick_func_t, BIND_TYPE_KICK) FUNC_UNBIND(kick, kick_func_t, BIND_TYPE_KICK) @@ -216,17 +212,7 @@ FUNC_EVENT(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY, (struct ClientSocke FUNC_BIND(registered, registered_func_t, BIND_TYPE_REGISTERED) FUNC_UNBIND(registered, registered_func_t, BIND_TYPE_REGISTERED) -int event_registered(struct UserNode *old_user, struct UserNode *new_user) { - struct binding *cbind; - int ret = 0; - pre_event(BIND_TYPE_REGISTERED); - for(cbind = binds[BIND_TYPE_REGISTERED]; cbind; cbind = cbind->next) { - registered_func_t *func = cbind->func; - ret |= func(old_user, new_user); - } - post_event(BIND_TYPE_REGISTERED); - return ret; -} +FUNC_EVENT(registered, registered_func_t, BIND_TYPE_REGISTERED, (struct UserNode *user, char *new_mask), (user, new_mask)) FUNC_BIND(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER) FUNC_UNBIND(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER) diff --git a/src/IRCEvents.h b/src/IRCEvents.h index f7b6ce0..5c77834 100644 --- a/src/IRCEvents.h +++ b/src/IRCEvents.h @@ -44,18 +44,11 @@ typedef void nick_func_t(struct UserNode *user, char *new_nick); int event_nick(struct UserNode *user, char *new_nick); #endif -typedef void part_func_t(struct ChanUser *chanuser, char *reason); +typedef void part_func_t(struct ChanUser *chanuser, int quit, char *reason); #ifndef DND_FUNCTIONS /* MODULAR ACCESSIBLE */ int bind_part(part_func_t *func, int module_id); /* MODULAR ACCESSIBLE */ void unbind_part(part_func_t *func); -int event_part(struct ChanUser *chanuser, char *reason); -#endif - -typedef void quit_func_t(struct UserNode *user, char *reason); -#ifndef DND_FUNCTIONS -/* MODULAR ACCESSIBLE */ int bind_quit(quit_func_t *func, int module_id); -/* MODULAR ACCESSIBLE */ void unbind_quit(quit_func_t *func); -int event_quit(struct UserNode *user, char *reason); +int event_part(struct ChanUser *chanuser, int quit, char *reason); #endif typedef void kick_func_t(struct UserNode *user, struct ChanUser *target, char *reason); @@ -142,11 +135,11 @@ typedef void bot_ready_func_t(struct ClientSocket *client); int event_bot_ready(struct ClientSocket *client); #endif -typedef int registered_func_t(struct UserNode *old_user, struct UserNode *new_user); +typedef void registered_func_t(struct UserNode *user, char *new_mask); #ifndef DND_FUNCTIONS /* MODULAR ACCESSIBLE */ int bind_registered(registered_func_t *func, int module_id); /* MODULAR ACCESSIBLE */ void unbind_registered(registered_func_t *func); -int event_registered(struct UserNode *old_user, struct UserNode *new_user); +int event_registered(struct UserNode *user, char *new_mask); #endif typedef int freeuser_func_t(struct UserNode *user); diff --git a/src/IRCParser.c b/src/IRCParser.c index 2c30d69..3d410a4 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -30,7 +30,7 @@ #include "bots.h" struct irc_cmd *irc_commands = NULL; -static struct UserNode *registering_users = NULL; +//static struct UserNode *registering_users = NULL; int statistics_privmsg = 0; int statistics_network_users = 0; int statistics_network_channels = 0; @@ -132,105 +132,46 @@ static IRC_CMD(raw_002) { //fixed: ZNC fakes a 001 raw even if we're not connect return 1; } -static int is_firstBotSeeUser(struct ClientSocket *client, struct UserNode *user) { - struct ClientSocket *bot, *pref_bot = NULL, *unpref_bot = NULL; - struct ChanUser *chanuser; - int found; - for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { - found = 0; - for(chanuser = getUserChannels(bot->user, NULL); chanuser; chanuser = getUserChannels(bot->user, chanuser)) { - if(isUserOnChan(user, chanuser->chan)) { - found = 1; - break; - } - } - if(!found) continue; - if(bot->flags & SOCKET_FLAG_PREFERRED) { - pref_bot = bot; - break; - } else - unpref_bot = bot; - } - bot = (pref_bot ? pref_bot : unpref_bot); - if(client == bot) - return 1; - else - return 0; -} - -static int is_onlyBotSeeUser(struct ClientSocket *client, struct UserNode *user) { - struct ClientSocket *bot; - struct ChanUser *chanuser; - for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { - if(bot == client) continue; - for(chanuser = getUserChannels(bot->user, NULL); chanuser; chanuser = getUserChannels(bot->user, chanuser)) { - if(isUserOnChan(user, chanuser->chan)) { - return 0; - } - } - } - return 1; -} - static IRC_CMD(raw_join) { if(from == NULL || argc < 1) return 0; SYNCHRONIZE(cache_sync); struct UserNode *user = getUserByMask(from); struct ChanNode *chan = getChanByName(argv[0]); + struct ChanUser *chanuser; if(!chan && (!user || !(user->flags & USERFLAG_ISBOT))) { + //parse error if the channel is not known, yet and it's not a bot joining DESYNCHRONIZE(cache_sync); return 0; } - if(chan && (((!user || !isBot(user)) && chan->chanbot != client->user) || ((user && isBot(user)) && client->user != user))) { - DESYNCHRONIZE(cache_sync); - return 1; //we ignore it - but it's not a parse error - } - //let Bots always add themselves! (maybe they join invisible) - if(user == NULL) { + if(user == NULL) user = addUserMask(from); - } - struct UserNode *registering, *last_registering = NULL, *next_registering; - int noEvent = 0, wasRegistering = 0; - for(registering = registering_users; registering; registering = next_registering) { - next_registering = registering->next; - if(!strcmp(registering->nick, user->nick)) { - noEvent = event_registered(registering, user); - wasRegistering = 1; - if(last_registering) - last_registering->next = registering->next; - else - registering_users = registering->next; - delUser(registering, 1); - } else if(time(0) - registering->created > 2) { - if(last_registering) - last_registering->next = registering->next; - else - registering_users = registering->next; - delUser(registering, 1); - } else - last_registering = registering; - } if(chan == NULL) { + //new channel chan = addChannel(argv[0]); - //request member list - chan->chanbot = user; - struct ChanUser *chanuser = addChanUser(chan, user); //it must be a bot + chanuser = addChanUser(chan, user); + chanuser->visCount = 1; get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser); putsock(client, "MODE %s", chan->name); putsock(client, "MODE %s +b", chan->name); - } else if(!isUserOnChan(user, chan) && ((chan->flags & CHANFLAG_RECEIVED_USERLIST) || isBot(user))) { - struct ChanUser *chanuser = addChanUser(chan, user); + } else if((user->flags & USERFLAG_WAS_REGISTERING)) { + //user rejoined after registering (should still be present in the channel) + if(!(chanuser = getChanUser(user, chan))) + chanuser = addChanUser(chan, user); + chanuser->visCount++; + + event_registered(user, from); + user->flags &= ~USERFLAG_WAS_REGISTERING; + } else if(!isUserOnChan(user, chan)) { + //join user to an existing channel + chanuser = addChanUser(chan, user); + chanuser->visCount = 1; if(isBot(user) && isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible chanuser->flags |= CHANUSERFLAG_INVISIBLE; - if(!noEvent) { - if(wasRegistering) - user->flags |= USERFLAG_WAS_REGISTRING; - event_join(chanuser); - if(wasRegistering) - user->flags &= ~USERFLAG_WAS_REGISTRING; - } + + event_join(chanuser); + if(!(user->flags & USERFLAG_ISBOT) && (chan->flags & CHANFLAG_REJOINING)) { - //ABORT REJOIN (security break) + //ABORT AUTOMATIC REJOIN (security break) struct ClientSocket **clients = chan->rejoin_array; while(*clients) { putsock(*clients, "JOIN %s", chan->name); @@ -239,11 +180,12 @@ static IRC_CMD(raw_join) { free(chan->rejoin_array); chan->flags &= ~CHANFLAG_REJOINING; } - } else if(isUserOnChan(user, chan)) { //user is already in the channel? ^^ - //first bot rejoined - chan->flags &= ~CHANFLAG_RECEIVED_USERLIST; - struct ChanUser *chanuser = getChanUser(user, chan); - get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser); + } else { + //user is already in the channel + chanuser = getChanUser(user, chan); + chanuser->visCount++; + //if multiple bots see the user, it can't be invisible + chanuser->flags &= ~CHANUSERFLAG_INVISIBLE; } DESYNCHRONIZE(cache_sync); return 1; @@ -263,21 +205,26 @@ static void check_full_rejoin(struct ChanNode *chan) { } if(do_rejoin) { struct ClientSocket **clients = calloc(botcount, sizeof(*clients)); - struct ClientSocket *bot, *chanbot; + struct ClientSocket *bot, *chanbot = NULL; int i = 0; for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { - if(bot->user != chan->chanbot && isUserOnChan(bot->user, chan)) { + if(!isUserOnChan(bot->user, chan)) + continue; + if(!chanbot && ((bot->flags & SOCKET_FLAG_PREFERRED) || !getBots(SOCKET_FLAG_READY, bot))) + chanbot = bot; + else { clients[i++] = bot; putsock(bot, "PART %s :rejoining", chan->name); - } else if(bot->user == chan->chanbot) - chanbot = bot; + } } - chan->flags |= CHANFLAG_REJOINING; - chan->rejoin_array = clients; if(botcount == 1) { //we're alone + free(clients); putsock(chanbot, "PART %s :magic hop", chan->name); putsock(chanbot, "JOIN %s", chan->name); + } else { + chan->flags |= CHANFLAG_REJOINING; + chan->rejoin_array = clients; } } } @@ -286,53 +233,104 @@ static IRC_CMD(raw_part) { if(from == NULL || argc < 1) return 0; SYNCHRONIZE(cache_sync); struct UserNode *user = getUserByMask(from); - if(user == NULL) { - DESYNCHRONIZE(cache_sync); - return 0; - } struct ChanNode *chan = getChanByName(argv[0]); - if(chan == NULL) { + struct ChanUser *chanuser; + if(user == NULL || chan == NULL || !(chanuser = getChanUser(user, chan))) { DESYNCHRONIZE(cache_sync); return 0; } - if((!isBot(user) && chan->chanbot != client->user) || (isBot(user) && client->user != user)) { - DESYNCHRONIZE(cache_sync); - return 1; //we ignore it - but it's not a parse error + chanuser->visCount--; + if(chanuser->visCount == 0) { + delChanUser(chanuser, 0); //not free, yet! + event_part(chanuser, 0, (argc > 1 ? argv[1] : NULL)); + freeChanUser(chanuser); } + + //check if channel is still present int keep_channel = 1; - if(chan->chanbot == user && (chan->flags & CHANFLAG_REJOINING)) { - struct ClientSocket **clients = chan->rejoin_array; - while(*clients) { - putsock(*clients, "JOIN %s", chan->name); - clients++; + if(chan->usercount == 0) { + if((chan->flags & CHANFLAG_REJOINING)) { + struct ClientSocket **clients = chan->rejoin_array; + while(*clients) { + putsock(*clients, "JOIN %s", chan->name); + clients++; + } + free(chan->rejoin_array); + chan->flags &= ~CHANFLAG_REJOINING; } - free(chan->rejoin_array); - chan->flags &= ~CHANFLAG_REJOINING; + delChannel(chan, 1); + keep_channel = 0; + } else if(isBot(user)) //bot parted - check if theres another bot in the channel + keep_channel = checkChannelVisibility(chan); + + // free user if he/she is in no other channel + if(user->channel == NULL && !(user->flags & USERFLAG_ISBOT)) + delUser(user, 1); + + if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) + check_full_rejoin(chan); + else if(keep_channel && (chan->flags & CHANFLAG_REJOINING) && chan->usercount == 1) { + //bot is alone... rejoin! + struct ClientSocket *bot; + //find the last bot in the channel + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(isUserOnChan(bot->user, chan)) { + putsock(bot, "PART %s :magic hop", chan->name); + putsock(bot, "JOIN %s", chan->name); + } + } + } + DESYNCHRONIZE(cache_sync); + return 1; +} + +static IRC_CMD(raw_kick) { + if(from == NULL || argc < 3) return 0; + SYNCHRONIZE(cache_sync); + struct UserNode *user = getUserByMask(from); + struct UserNode *target = getUserByNick(argv[1]); + struct ChanNode *chan = getChanByName(argv[0]); + struct ChanUser *chanuser; + if(chan == NULL || target == NULL || !(chanuser = getChanUser(target, chan))) { DESYNCHRONIZE(cache_sync); return 0; - } else if(isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { - struct ChanUser *chanuser = getChanUser(user, chan); - delChanUser(chanuser, 0); //we need to free the chanuser manually! - event_part(chanuser, (argc > 1 ? argv[1] : NULL)); - freeChanUser(chanuser); - if(chan->chanbot == user) { - //check if theres another bot in the channel - otherwise free it - keep_channel = checkChannelVisibility(chan); - } } - if(user->channel == NULL && !(user->flags & USERFLAG_ISBOT)) { - //remove the user - delUser(user, 1); + chanuser->visCount--; + if(chanuser->visCount == 0) { + delChanUser(chanuser, 0); //not free, yet! + event_kick(user, chanuser, argv[2]); + freeChanUser(chanuser); } - if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) { + + //check if channel is still present + int keep_channel = 1; + if(chan->usercount == 0) { + if((chan->flags & CHANFLAG_REJOINING)) { + struct ClientSocket **clients = chan->rejoin_array; + while(*clients) { + putsock(*clients, "JOIN %s", chan->name); + clients++; + } + free(chan->rejoin_array); + chan->flags &= ~CHANFLAG_REJOINING; + } + delChannel(chan, 1); + keep_channel = 0; + } else if(isBot(target)) //bot parted - check if theres another bot in the channel + keep_channel = checkChannelVisibility(chan); + + // free user if he/she is in no other channel + if(target->channel == NULL && !(target->flags & USERFLAG_ISBOT)) + delUser(target, 1); + + if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) check_full_rejoin(chan); - } else if(keep_channel && (chan->flags & CHANFLAG_REJOINING) && chan->usercount == 1) { //bot is alone... rejoin! struct ClientSocket *bot; //find the last bot in the channel for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { - if(bot->user == chan->chanbot) { + if(isUserOnChan(bot->user, chan)) { putsock(bot, "PART %s :magic hop", chan->name); putsock(bot, "JOIN %s", chan->name); } @@ -350,125 +348,82 @@ static IRC_CMD(raw_quit) { DESYNCHRONIZE(cache_sync); return 0; } - if(!is_firstBotSeeUser(client, user)) { + + if(client->user == user) { DESYNCHRONIZE(cache_sync); - return 1; //we ignore it - but it's not a parse error + return 0; } - int registering = !stricmp(argv[0], "Registered"); - if((registering && (user->flags & USERFLAG_ISBOT))) { - DESYNCHRONIZE(cache_sync); - return 1; //bot is registering - just ignore it - } - delUser(user, 0); //a little bit crazy, but we want to delete the user on the channel's userlists - but not the users channel list - event_quit(user, argv[0]); - if(user->flags & USERFLAG_ISBOT) { - //check if there are other bots in the users channel - otherwise free them - struct ChanUser *chanuser, *next; - for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) { - next = getUserChannels(user, chanuser); - if(chanuser->chan->chanbot == user) - checkChannelVisibility(chanuser->chan); - } - //search the user representing the bot in the world of IRC - struct ClientSocket *bot; - for(bot = getBots(0, NULL); bot; bot = getBots(0, bot)) { - if(bot->user == user) { - bot->flags &= ~SOCKET_FLAG_READY; - bot->user = NULL; - break; - } - } - } else if(!registering) { - struct ChanUser *chanuser; - struct ChanNode *chan; - for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) { - chan = chanuser->chan; - if((chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) - check_full_rejoin(chan); + + //check if user is just registering + if(!stricmp(argv[0], "Registered")) + user->flags |= USERFLAG_WAS_REGISTERING; + + //decrease visCount counter + struct ChanUser *chanuser, *next_chanuser; + for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) { + next_chanuser = getUserChannels(user, chanuser); + chanuser->visCount--; + if(chanuser->visCount == 0) { + delChanUser(chanuser, 0); //not free, yet! + event_part(chanuser, 1, argv[0]); + if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING)) + check_full_rejoin(chanuser->chan); + freeChanUser(chanuser); + } + } + + if(user->channel == NULL) { + if(isBot(user)) { + //ASSERT + return 0; } + if((user->flags & USERFLAG_WAS_REGISTERING)) { + //TODO: set a timeout or sth like that? + } else + delUser(user, 1); } - if(registering && !(user->flags & USERFLAG_ISBOT)) { - user->next = registering_users; - user->created = time(0); - registering_users = user; - } else - delUser(user, 1); //now we fully free the user + DESYNCHRONIZE(cache_sync); return 1; } void bot_disconnect(struct ClientSocket *client) { struct UserNode *user = client->user; - struct ChanUser *chanuser, *next; if(user) { - if(is_onlyBotSeeUser(client, user)) { - //ok the bot-user is not seen by any other bots so we can simply free it. - delUser(user, 0); - event_quit(user, "disconnected"); - for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) { - next = getUserChannels(user, chanuser); - if(chanuser->chan->chanbot == user) - checkChannelVisibility(chanuser->chan); + //just remove the bot mark from the user and handle a normal quit :) + user->flags &= ~USERFLAG_ISBOT; + client->user = NULL; + client->flags &= ~SOCKET_FLAG_READY; + + //decrease visCount counter + struct ChanUser *chanuser, *next_chanuser; + for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) { + next_chanuser = getUserChannels(user, chanuser); + chanuser->visCount--; + if(chanuser->visCount == 0) { + delChanUser(chanuser, 0); //not free, yet! + event_part(chanuser, 1, "QUIT"); + if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING)) + check_full_rejoin(chanuser->chan); freeChanUser(chanuser); } - user->channel = NULL; - delUser(user, 1); //now we fully free the user - } else { - //we need to transform the bot-user back to a normal user (BNC FIX) - user->flags &= ~USERFLAG_ISBOT; - for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) { - next = getUserChannels(user, chanuser); - if(chanuser->chan->chanbot == user) - checkChannelVisibility(chanuser->chan); - } } - client->user = NULL; - client->flags &= ~SOCKET_FLAG_READY; + + if(user->channel == NULL) + delUser(user, 1); } } -static IRC_CMD(raw_kick) { - if(from == NULL || argc < 3) return 0; - SYNCHRONIZE(cache_sync); - struct UserNode *user = getUserByMask(from); - struct UserNode *target = getUserByNick(argv[1]); - struct ChanNode *chan = getChanByName(argv[0]); - if(chan == NULL || target == NULL) { - DESYNCHRONIZE(cache_sync); - return 0; - } - if(((!isBot(target) && chan->chanbot != client->user) || (isBot(target) && client->user != target))) { - DESYNCHRONIZE(cache_sync); - return 1; //we ignore it - but it's not a parse error - } - int keep_channel = 1; - if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { - if(user == NULL) { - user = createTempUserMask(from); - if(!user) { - DESYNCHRONIZE(cache_sync); - return 0; - } - user->flags |= USERFLAG_ISTMPUSER; - } - struct ChanUser *chanuser = getChanUser(target, chan); - delChanUser(chanuser, 0); //we need to free the chanuser manually! - event_kick(user, chanuser, argv[1]); - if(chanuser->chan->chanbot == user) { - //check if theres another bot in the channel - otherwise free it - keep_channel = checkChannelVisibility(chan); - } - freeChanUser(chanuser); - } - if(target->channel == NULL && !(target->flags & USERFLAG_ISBOT)) { - //remove the user - delUser(target, 1); - } - if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) { - check_full_rejoin(chan); +static struct ClientSocket *get_first_prefered_bot_in_channel(struct ChanNode *chan) { + struct ClientSocket *bot, *chanbot = NULL; + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(!isUserOnChan(bot->user, chan)) + continue; + if(bot->flags & SOCKET_FLAG_PREFERRED) + return bot; + chanbot = bot; } - DESYNCHRONIZE(cache_sync); - return 1; + return chanbot; } static IRC_CMD(raw_topic) { @@ -480,7 +435,7 @@ static IRC_CMD(raw_topic) { DESYNCHRONIZE(cache_sync); return 0; } - if(chan->chanbot != client->user) { + if(client != get_first_prefered_bot_in_channel(chan)) { DESYNCHRONIZE(cache_sync); return 1; //just ignore it to prevent event duplicates } @@ -500,24 +455,6 @@ static IRC_CMD(raw_topic) { static IRC_CMD(raw_privmsg) { if(from == NULL || argc < 2) return 0; - if(!stricmplen(from, "*status", 7) || !stricmplen(from, "-sBNC", 5)) { - #ifdef HAVE_THREADS - unsigned int tid = (unsigned int) pthread_self_tid(); - while(!clientsocket_parseorder_top(tid)) { - usleep(1000); //1ms - } - #endif - if(!match("Disconnected from IRC.*", argv[1])) { - //ZNC DISCONNECT - bot_disconnect(client); - return 1; - } - if(!match("* disconnected from the server.", argv[1])) { - //sBNC DISCONNECT - bot_disconnect(client); - return 1; - } - } struct UserNode *user = getUserByMask(from); if(user == NULL) { user = createTempUserMask(from); @@ -526,7 +463,7 @@ static IRC_CMD(raw_privmsg) { } if(argv[0][0] == '#') { //Channel message struct ChanNode *chan = getChanByName(argv[0]); - if(chan && chan->chanbot == client->user) { + if(chan && client == get_first_prefered_bot_in_channel(chan)) { if(statistics_enabled) statistics_privmsg++; if(argv[1][0] == '\001') { @@ -574,7 +511,7 @@ static IRC_CMD(raw_notice) { } if(argv[0][0] == '#') { //Channel notice struct ChanNode *chan = getChanByName(argv[0]); - if(chan && chan->chanbot == client->user) + if(chan && client == get_first_prefered_bot_in_channel(chan)) event_channotice(user, chan, argv[1]); } else { struct UserNode *target = getUserByNick(argv[0]); @@ -592,7 +529,7 @@ static IRC_CMD(raw_nick) { struct UserNode *user = getUserByMask(from); if(user == NULL) { DESYNCHRONIZE(cache_sync); - return 0; + return 1; //maybe already renamed - no parse error } if(isBot(user)) { if(client->user != user) { @@ -601,9 +538,9 @@ static IRC_CMD(raw_nick) { } client_renamed(client); } - else if(!is_firstBotSeeUser(client, user)) { + else if(!strcmp(user->nick, argv[0])) { DESYNCHRONIZE(cache_sync); - return 1; //we ignore it - but it's not a parse error + return 1; //user has already this nick (case sensitive) } event_nick(user, argv[0]); renameUser(user, argv[0]); @@ -667,7 +604,7 @@ static IRC_CMD(raw_mode) { DESYNCHRONIZE(cache_sync); return 0; } - if(chan->chanbot != client->user) { + if(client != get_first_prefered_bot_in_channel(chan)) { DESYNCHRONIZE(cache_sync); return 1; } diff --git a/src/IRCParser.h b/src/IRCParser.h index 07d904f..e9cd432 100644 --- a/src/IRCParser.h +++ b/src/IRCParser.h @@ -22,7 +22,7 @@ struct ClientSocket; struct UserNode; -#define IRC_CMD(NAME) int NAME(struct ClientSocket *client, UNUSED_ARG(const char *from), UNUSED_ARG(char **argv), UNUSED_ARG(unsigned int argc)) +#define IRC_CMD(NAME) int NAME(struct ClientSocket *client, UNUSED_ARG(char *from), UNUSED_ARG(char **argv), UNUSED_ARG(unsigned int argc)) typedef IRC_CMD(irc_cmd_t); struct irc_cmd { diff --git a/src/UserNode.h b/src/UserNode.h index 992ef07..52380d4 100644 --- a/src/UserNode.h +++ b/src/UserNode.h @@ -30,8 +30,9 @@ #define USERFLAG_HAS_USERID 0x0200 #define USERFLAG_IS_ON_WHO_QUEUE 0x0400 /* prevents the user struct from beeing freed too early */ #define USERFLAG_FREE_AFTER_WHO 0x0800 /* user struct is no more referenced - free it after WHO */ +#define USERFLAG_QUITTING 0x1000 /* user is currently quitting... */ -#define USERFLAG_WAS_REGISTRING 0x20000000 /* only set for event_join if the quit reason was Registered */ +#define USERFLAG_WAS_REGISTERING 0x20000000 /* only set for event_join if the quit reason was Registered */ #define USERFLAG_SCRIPTFLAG1 0x40000000 #define USERFLAG_SCRIPTFLAG2 0x80000000 diff --git a/src/modules.c b/src/modules.c index db3a291..4de2468 100644 --- a/src/modules.c +++ b/src/modules.c @@ -113,8 +113,8 @@ void *global_functions[] = { /* 054 */ (Function) unbind_nick, /* 055 */ (Function) bind_part, /* 056 */ (Function) unbind_part, -/* 057 */ (Function) bind_quit, -/* 058 */ (Function) unbind_quit, +/* 057 */ (Function) NULL, /* deprecated */ +/* 058 */ (Function) NULL, /* deprecated */ /* 059 */ (Function) bind_kick, /* 060 */ (Function) unbind_kick, /* 061 */ (Function) bind_topic, diff --git a/src/modules/NeonFun.mod/bot_NeonFun.c b/src/modules/NeonFun.mod/bot_NeonFun.c index 3679234..6fad256 100644 --- a/src/modules/NeonFun.mod/bot_NeonFun.c +++ b/src/modules/NeonFun.mod/bot_NeonFun.c @@ -128,16 +128,11 @@ static void start_bots(int type) { bind_unbound_required_functions(BOTID); } -static void neonfun_parted(struct ChanUser *chanuser, char *reason) { +static void neonfun_parted(struct ChanUser *chanuser, int quit, char *reason) { uno_event_part(chanuser); fourwins_event_part(chanuser); } -static void neonfun_quitted(struct UserNode *user, char *reason) { - uno_event_quit(user); - fourwins_event_quit(user); -} - static int neonfun_freechan(struct ChanNode *chan) { uno_event_freechan(chan); fourwins_event_freechan(chan); @@ -183,7 +178,6 @@ void init_NeonFun(int type) { //register events bind_bot_ready(neonfun_bot_ready, module_id); bind_part(neonfun_parted, module_id); - bind_quit(neonfun_quitted, module_id); bind_freechan(neonfun_freechan, module_id); bind_invite(neonfun_event_invite, module_id); diff --git a/src/modules/NeonFun.mod/game_4wins.c b/src/modules/NeonFun.mod/game_4wins.c index 6698eae..3b55d14 100644 --- a/src/modules/NeonFun.mod/game_4wins.c +++ b/src/modules/NeonFun.mod/game_4wins.c @@ -179,29 +179,6 @@ void fourwins_event_part(struct ChanUser *chanuser) { } } -void fourwins_event_quit(struct UserNode *user) { - struct fourwins_game *game; - for(game = fourwins_active_games; game; game = game->next) { - if(game->player[0]->user == user || game->player[1]->user == user) { - fourwins_reply(game, "NF_4WINS_GAME_CLOSED"); - fourwins_free_game(game); - return; - } - struct fourwins_guest *guest, *prev_guest = NULL; - for(guest = game->guests; guest; guest = guest->next) { - if(guest->chanuser->user == user) { - if(prev_guest) - prev_guest->next = guest->next; - else - game->guests = guest->next; - free(guest); - break; - } else - prev_guest = guest; - } - } -} - void fourwins_event_freechan(struct ChanNode *chan) { struct fourwins_game *game; for(game = fourwins_active_games; game; game = game->next) { diff --git a/src/modules/NeonFun.mod/game_4wins.h b/src/modules/NeonFun.mod/game_4wins.h index 7e404b6..c21fe31 100644 --- a/src/modules/NeonFun.mod/game_4wins.h +++ b/src/modules/NeonFun.mod/game_4wins.h @@ -57,7 +57,6 @@ void fourwins_show_matrix(struct fourwins_game *game); TIMEQ_CALLBACK(fourwins_timeout); void fourwins_free_game(struct fourwins_game *game); void fourwins_event_part(struct ChanUser *chanuser); -void fourwins_event_quit(struct UserNode *user); void fourwins_event_freechan(struct ChanNode *chan); #endif diff --git a/src/modules/NeonFun.mod/game_uno.c b/src/modules/NeonFun.mod/game_uno.c index 0e2c028..96f5792 100644 --- a/src/modules/NeonFun.mod/game_uno.c +++ b/src/modules/NeonFun.mod/game_uno.c @@ -636,19 +636,6 @@ void uno_event_part(struct ChanUser *chanuser) { } } -void uno_event_quit(struct UserNode *user) { - struct uno_game *game; - for(game = uno_active_games; game; game = game->next) { - struct uno_player *player; - for(player = game->player; player; player = player->next) { - if(player->chanuser->user == user) { - uno_free_player(player, game->deck); - break; - } - } - } -} - void uno_event_freechan(struct ChanNode *chan) { struct uno_game *game; for(game = uno_active_games; game; game = game->next) { diff --git a/src/modules/NeonFun.mod/game_uno.h b/src/modules/NeonFun.mod/game_uno.h index 356fc00..0acbced 100644 --- a/src/modules/NeonFun.mod/game_uno.h +++ b/src/modules/NeonFun.mod/game_uno.h @@ -106,7 +106,6 @@ int uno_check_card_valid(struct uno_game *game, struct uno_card *card); void uno_play_card(struct uno_game *game, struct uno_player *player, struct uno_card *card); void uno_event_part(struct ChanUser *chanuser); -void uno_event_quit(struct UserNode *user); void uno_event_freechan(struct ChanNode *chan); #endif diff --git a/src/modules/NeonHelp.mod/bot_NeonHelp.c b/src/modules/NeonHelp.mod/bot_NeonHelp.c index 9e3ba72..9d29a50 100644 --- a/src/modules/NeonHelp.mod/bot_NeonHelp.c +++ b/src/modules/NeonHelp.mod/bot_NeonHelp.c @@ -475,7 +475,7 @@ static void neonhelp_event_kick(struct UserNode *user, struct ChanUser *target, } } -static void neonhelp_event_part(struct ChanUser *target, char *reason) { +static void neonhelp_event_part(struct ChanUser *target, int quit, char *reason) { struct ClientSocket *client; MYSQL_RES *res; MYSQL_ROW row; @@ -518,33 +518,6 @@ static void neonhelp_event_part(struct ChanUser *target, char *reason) { } } -static void neonhelp_event_quit(struct UserNode *target, char *reason) { - struct ClientSocket *client; - int userHasRequest; - for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) { - if(client->botid == BOTID) { - userHasRequest = 0; - struct NeonHelpNode *helpnode, *prev_helpnode = NULL; - if(client->flags & SOCKET_HAVE_HELPNODE) { - for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) { - if(helpnode->user == target) { - userHasRequest = 1; - break; - } else - prev_helpnode = helpnode; - } - } - if(!userHasRequest) continue; - //free the user's support request - if(prev_helpnode) - prev_helpnode->next = helpnode->next; - else - client->botclass_helpnode = helpnode->next; - neonhelp_destroy_support_request(client, helpnode, 0); - } - } -} - static void neonhelp_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) { if(client->botid != BOTID) return; @@ -587,7 +560,6 @@ void init_NeonHelp(int type) { bind_chanmsg(neonhelp_event_chanmsg, module_id); bind_part(neonhelp_event_part, module_id); bind_kick(neonhelp_event_kick, module_id); - bind_quit(neonhelp_event_quit, module_id); bind_invite(neonhelp_event_invite, module_id); set_trigger_callback(BOTID, module_id, neonhelp_trigger_callback); diff --git a/src/modules/NeonServ.mod/bot_NeonServ.c b/src/modules/NeonServ.mod/bot_NeonServ.c index 89f298b..0233a05 100644 --- a/src/modules/NeonServ.mod/bot_NeonServ.c +++ b/src/modules/NeonServ.mod/bot_NeonServ.c @@ -404,7 +404,6 @@ cmd_neonserv_calc.c //EVENTS #include "event_neonserv_join.c" #include "event_neonserv_part.c" -#include "event_neonserv_quit.c" #include "event_neonserv_kick.c" #include "event_neonserv_mode.c" #include "event_neonserv_ctcp.c" @@ -510,7 +509,6 @@ void init_NeonServ(int type) { bind_bot_ready(neonserv_bot_ready, module_id); bind_join(neonserv_event_join, module_id); bind_part(neonserv_event_part, module_id); - bind_quit(neonserv_event_quit, module_id); bind_chanctcp(neonserv_event_chanctcp, module_id); bind_privctcp(general_event_privctcp, module_id); bind_channotice(neonserv_event_channotice, module_id); diff --git a/src/modules/NeonServ.mod/event_neonserv_join.c b/src/modules/NeonServ.mod/event_neonserv_join.c index 5f8d144..ea0ce3f 100644 --- a/src/modules/NeonServ.mod/event_neonserv_join.c +++ b/src/modules/NeonServ.mod/event_neonserv_join.c @@ -18,11 +18,10 @@ struct neonserv_event_join_cache { struct ClientSocket *client; struct ChanUser *chanuser; - int was_registering; }; static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup); -static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering); +static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser); static TIMEQ_CALLBACK(neonserv_event_join_dynlimit); static void neonserv_event_join(struct ChanUser *chanuser) { @@ -59,21 +58,19 @@ static void neonserv_event_join(struct ChanUser *chanuser) { } cache->client = client; cache->chanuser = chanuser; - cache->was_registering = (user->flags & USERFLAG_WAS_REGISTRING); get_userauth(user, module_id, neonserv_event_join_nick_lookup, cache); } else - neonserv_event_join_async1(client, chanuser, (user->flags & USERFLAG_WAS_REGISTRING)); + neonserv_event_join_async1(client, chanuser); } static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup) { struct neonserv_event_join_cache *cache = data; - if(user) { - neonserv_event_join_async1(cache->client, cache->chanuser, cache->was_registering); - } + if(user) + neonserv_event_join_async1(cache->client, cache->chanuser); free(cache); } -static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering) { +static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser) { struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid)); struct ChanNode *chan = chanuser->chan; struct UserNode *user = chanuser->user; @@ -140,7 +137,7 @@ static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanU if(a) b = a+2; } while(a); - if(greetingPos && (!was_registering || *row[2])) + if(greetingPos && *row[2]) reply(textclient, user, "[%s] %s", chan->name, greeting); //USER RIGHTS if(!(userflags & DB_CHANUSER_NOAUTOOP)) { diff --git a/src/modules/NeonServ.mod/event_neonserv_part.c b/src/modules/NeonServ.mod/event_neonserv_part.c index 7b4846c..b4565c0 100644 --- a/src/modules/NeonServ.mod/event_neonserv_part.c +++ b/src/modules/NeonServ.mod/event_neonserv_part.c @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -static void neonserv_event_part(struct ChanUser *chanuser, char *reason) { +static void neonserv_event_part(struct ChanUser *chanuser, int quit, char *reason) { struct ChanNode *chan = chanuser->chan; struct UserNode *user = chanuser->user; MYSQL_RES *res; diff --git a/src/modules/NeonServ.mod/event_neonserv_quit.c b/src/modules/NeonServ.mod/event_neonserv_quit.c deleted file mode 100644 index 2d1e8ca..0000000 --- a/src/modules/NeonServ.mod/event_neonserv_quit.c +++ /dev/null @@ -1,30 +0,0 @@ -/* event_neonserv_quit.c - NeonServ v5.4 - * Copyright (C) 2011-2012 Philipp Kreil (pk910) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -static void neonserv_event_quit(struct UserNode *user, char *reason) { - MYSQL_RES *res; - MYSQL_ROW chanuserrow; - struct ChanUser *chanuser; - if((user->flags & USERFLAG_ISAUTHED)) { - for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = getUserChannels(user, chanuser)) { - printf_mysql_query("SELECT `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `channel_name` = '%s' AND `user_user` = '%s'", escape_string(chanuser->chan->name), escape_string(user->auth)); - res = mysql_use(); - if((chanuserrow = mysql_fetch_row(res)) != NULL) - printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[0]); - } - } -} diff --git a/src/modules/NeonSpam.mod/event_neonspam_join.c b/src/modules/NeonSpam.mod/event_neonspam_join.c index 425ad08..497cc2f 100644 --- a/src/modules/NeonSpam.mod/event_neonspam_join.c +++ b/src/modules/NeonSpam.mod/event_neonspam_join.c @@ -27,7 +27,6 @@ struct neonspam_event_join_cache { }; static void neonspam_event_join(struct ChanUser *chanuser) { - if(chanuser->user->flags & USERFLAG_WAS_REGISTRING) return; struct ClientSocket *client = getChannelBot(chanuser->chan, BOTID); if(!client) return; //we can't "see" this event if(chanuser->user == client->user) { diff --git a/src/modules/module.h b/src/modules/module.h index bf8958c..7cc075f 100644 --- a/src/modules/module.h +++ b/src/modules/module.h @@ -84,8 +84,8 @@ extern int module_id; /* 054 */ #define unbind_nick ((void (*)(nick_func_t *))global[54]) /* 055 */ #define bind_part ((int (*)(part_func_t *, int))global[55]) /* 056 */ #define unbind_part ((void (*)(part_func_t *))global[56]) -/* 057 */ #define bind_quit ((int (*)(quit_func_t *, int))global[57]) -/* 058 */ #define unbind_quit ((void (*)(quit_func_t *))global[58]) +/* 057 */ /* deprecated */ +/* 058 */ /* deprecated */ /* 059 */ #define bind_kick ((int (*)(kick_func_t *, int))global[59]) /* 060 */ #define unbind_kick ((void (*)(kick_func_t *))global[60]) /* 061 */ #define bind_topic ((int (*)(topic_func_t *, int))global[61]) diff --git a/src/tools.c b/src/tools.c index 985362d..093ed80 100644 --- a/src/tools.c +++ b/src/tools.c @@ -522,7 +522,7 @@ int isFakeHost(char *host) { char *p1, *p2 = host; //find the last dot to identify if the hostmask is a fake host - while((p1 = strstr(p2, "."))) { + while((p1 = strchr(p2, '.'))) { p2 = p1 + 1; } //TLD database: http://www.iana.org/domains/root/db/ diff --git a/src/version.h b/src/version.h index e4dc9ea..38eea8b 100644 --- a/src/version.h +++ b/src/version.h @@ -19,7 +19,7 @@ #include "main.h" -#define MODULE_VERSION 4 +#define MODULE_VERSION 5 #ifndef DND_FUNCTIONS extern const char *compilation; -- 2.20.1