diff --git a/lib/channel.h b/lib/channel.h index b630d65..e3dabfe 100755 --- a/lib/channel.h +++ b/lib/channel.h @@ -33,12 +33,16 @@ struct user BOOL is_voice; BOOL is_owner; BOOL is_admin; + + BOOL is_botadmin; #else bool is_op; bool is_halfop; bool is_voice; bool is_owner; bool is_admin; + + bool is_botadmin; #endif }; @@ -75,6 +79,7 @@ MY_API BOOL is_voice(char *chan, char *nick); MY_API BOOL channel_exists(char *chan); MY_API BOOL user_exists(char *chan, char *nick); MY_API BOOL is_on_channel(char *nick, char *chan); +MY_API BOOL is_botadmin(char *nick); #else MY_API bool is_op(char *chan, char *nick); MY_API bool is_halfop(char *chan, char *nick); @@ -84,6 +89,7 @@ MY_API bool is_admin(char *chan, char *nick); MY_API bool channel_exists(char *chan); MY_API bool user_exists(char *chan, char *nick); MY_API bool is_on_channel(char *nick, char *chan); +MY_API bool is_botadmin(char *nick); #endif #endif diff --git a/lib/irc.h b/lib/irc.h index d68d085..dad7d71 100755 --- a/lib/irc.h +++ b/lib/irc.h @@ -14,6 +14,8 @@ #ifdef _WIN32 #include +#else +#include #endif #define OUTBUF_SIZE 60000 @@ -28,7 +30,7 @@ struct irc_conn #endif char nick[32]; - char admin[64]; + char admin[256]; char host[256]; char port[5]; char real_name[512]; @@ -58,4 +60,11 @@ MY_API void irc_ctcp(struct irc_conn *bot, char *to, char *fmt, ...); void irc_parse_raw(struct irc_conn *bot, char *raw); +#ifdef _WIN32 +MY_API BOOL check_hostmask_match(char *mask, char *host); +#else +MY_API bool check_hostmask_match(char *mask, char *host); +#endif + + #endif diff --git a/src/channel.c b/src/channel.c index 8f2efe1..f2ec150 100755 --- a/src/channel.c +++ b/src/channel.c @@ -83,6 +83,8 @@ void add_user_to_channel(char *user, char *host, char *chan) is_halfop = false; is_owner = false; is_admin = false; + struct irc_conn *bot = get_bot(); + char buf[512]; if (!strcmp(chan, "")) @@ -135,6 +137,12 @@ void add_user_to_channel(char *user, char *host, char *chan) u->is_owner = is_owner; u->is_admin = is_admin; + sprintf(buf, "%s!%s", u->nick, u->host); + if (check_hostmask_match(bot->admin, buf) == true) + { + u->is_botadmin = true; + } + channels[i]->users[channels[i]->user_count] = *u; channels[i]->user_count++; @@ -143,6 +151,7 @@ void add_user_to_channel(char *user, char *host, char *chan) strlcpy(channels[i]->users[channels[i]->user_count].nick, user, 50); strlcpy(channels[i]->users[channels[i]->user_count].host, host, 256); + sprintf(buf, "%s!%s", user, host); channels[i]->users[channels[i]->user_count].is_op = is_op | is_owner | is_admin; channels[i]->users[channels[i]->user_count].is_voice = is_voice | is_halfop | is_op | is_owner | is_admin; @@ -150,6 +159,11 @@ void add_user_to_channel(char *user, char *host, char *chan) channels[i]->users[channels[i]->user_count].is_owner = is_owner; channels[i]->users[channels[i]->user_count].is_admin = is_admin; + if (check_hostmask_match(bot->admin, buf) == true) + { + channels[i]->users[channels[i]->user_count].is_botadmin = true; + } + channels[i]->user_count++; } } @@ -546,3 +560,25 @@ MY_API bool is_on_channel(char *nick, char *chan) return 0; } +#ifdef _WIN32 +MY_API BOOL is_botadmin(char *nick) +#else +MY_API bool is_botadmin(char *nick) +#endif +{ + int i, j; + struct irc_conn *bot = get_bot(); + + for (i = 0; i < chan_count; i++) + { + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return channels[i]->users[j].is_botadmin; + } + } + } + + return 0; +} diff --git a/src/events.c b/src/events.c index 2e31abd..3c71c3b 100755 --- a/src/events.c +++ b/src/events.c @@ -1,6 +1,7 @@ #include "irc.h" #include "util.h" #include "events.h" +#include "channel.h" #include "module.h" #include #include @@ -112,7 +113,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) if (!strcmp("JOIN", cmd)) { - if (!strcmp(bot->admin, usr)) + if (is_botadmin(usr) == true) { irc_raw(bot, "JOIN :%s", arg); } @@ -123,7 +124,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) } else if (!strcmp("PART", cmd)) { - if (!strcmp(bot->admin, usr)) + if (is_botadmin(usr) == true) { irc_raw(bot, "PART %s :Admin made me leave.", arg); } @@ -134,7 +135,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) } else if (!strcmp("HANDLERS", cmd)) { - if (!strcmp(bot->admin, usr)) + if (is_botadmin(usr) == true) { for (i = 0; i < handlers_count; i++) { @@ -152,7 +153,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) } else if (!strcmp("LOADMOD", cmd)) { - if (!strcmp(bot->admin, usr)) + if (is_botadmin(usr) == true) { #ifdef _WIN32 irc_notice(bot, usr, "Loading module: mods/%s.dll", arg); @@ -170,7 +171,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) } else if (!strcmp("UNLOADMOD", cmd)) { - if (!strcmp(bot->admin, usr)) + if (is_botadmin(usr) == true) { #ifdef _WIN32 irc_notice(bot, usr, "Unloading module: mods/%s.dll", arg); @@ -188,7 +189,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) } else if (!strcmp("MODLIST", cmd)) { - if (!strcmp(bot->admin, usr)) + if (is_botadmin(usr) == true) { list_modules(bot, usr); } diff --git a/src/irc.c b/src/irc.c index c4c69a3..5be8908 100755 --- a/src/irc.c +++ b/src/irc.c @@ -10,6 +10,7 @@ #include "events.h" #include "channel.h" +#include #include #include #include @@ -406,3 +407,41 @@ void irc_parse_raw(struct irc_conn *bot, char *raw) } } + +#ifdef _WIN32 +BOOL check_hostmask_match(char *mask, char *host) +#else +bool check_hostmask_match(char *mask, char *host) +#endif +{ + char *m = mask; + char *h = host; + + while (*m && *h) + { + if (*m == '*') + { + m++; + if (!*m) + { + return 1; + } + + while (*h && *h != *m) + { + h++; + } + } + else if (*m == *h) + { + m++; + h++; + } + else + { + return false; + } + } + + return true; +} diff --git a/xbot.cfg b/xbot.cfg index 9c1a975..da308d6 100755 --- a/xbot.cfg +++ b/xbot.cfg @@ -5,8 +5,11 @@ bot: verbose = 1; nick = "xbot"; user = "xbot"; - admin = "ab3800"; + # owner of the bot (nick!user@host) + admin = "ab3800!*@owner.ephasic.org"; + + # database file name db = "xbot.db"; };