diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/bs_bot.c | 527 |
1 files changed, 290 insertions, 237 deletions
diff --git a/src/core/bs_bot.c b/src/core/bs_bot.c index 93dfc89da..69f7e23a7 100644 --- a/src/core/bs_bot.c +++ b/src/core/bs_bot.c @@ -55,258 +55,310 @@ void myBotServHelp(User * u) **/ int do_bot(User * u) { - BotInfo *bi; - char *cmd = strtok(NULL, " "); - char *ch = NULL; - - if (!cmd) - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); - else if (!stricmp(cmd, "ADD")) { - char *nick = strtok(NULL, " "); - char *user = strtok(NULL, " "); - char *host = strtok(NULL, " "); - char *real = strtok(NULL, ""); - - if (!nick || !user || !host || !real) - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); - else if (readonly) - notice_lang(s_BotServ, u, BOT_BOT_READONLY); - else if (findbot(nick)) - notice_lang(s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick); - else if (strlen(nick) > NickLen) - notice_lang(s_BotServ, u, BOT_BAD_NICK); - else if (strlen(user) >= USERMAX) - notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); - else if (strlen(user) > HOSTMAX) - notice_lang(s_BotServ, u, BOT_LONG_HOST, HOSTMAX); - else { - NickAlias *na; - - /** - * Check the nick is valid re RFC 2812 - **/ - if (isdigit(nick[0]) || nick[0] == '-') { - notice_lang(s_BotServ, u, BOT_BAD_NICK); - return MOD_CONT; - } - for (ch = nick; *ch && (ch - nick) < NICKMAX; ch++) { - if (!isvalidnick(*ch)) { - notice_lang(s_BotServ, u, BOT_BAD_NICK); - return MOD_CONT; - } - } - - /* check for hardcored ircd forbidden nicks */ - if (!ircdproto->IsNickValid(nick)) { - notice_lang(s_BotServ, u, BOT_BAD_NICK); - return MOD_CONT; - } - - if (!isValidHost(host, 3)) { - notice_lang(s_BotServ, u, BOT_BAD_HOST); - return MOD_CONT; - } - for (ch = user; *ch && (ch - user) < USERMAX; ch++) { - if (!isalnum(*ch)) { - notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); - return MOD_CONT; - } - } - - /** - * Check the host is valid re RFC 2812 - **/ - - /* Check whether it's a services client's nick and return if so - Certus */ - /* use nickIsServices reduce the total number lines of code - TSL */ - - if (nickIsServices(nick, 0)) { - notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED); - return MOD_CONT; - } - - /* We check whether the nick is registered, and inform the user - * if so. You need to drop the nick manually before you can use - * it as a bot nick from now on -GD - */ - if ((na = findnick(nick))) { - notice_lang(s_BotServ, u, NICK_ALREADY_REGISTERED, nick); - return MOD_CONT; - } - - bi = new BotInfo(nick); - if (!bi) { - notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED); - return MOD_CONT; - } - - bi->user = sstrdup(user); - bi->host = sstrdup(host); - bi->real = sstrdup(real); - bi->created = time(NULL); - bi->chancount = 0; - - /* We check whether user with this nick is online, and kill it if so */ - EnforceQlinedNick(nick, s_BotServ); - - /* We make the bot online, ready to serve */ - ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, - ircd->pseudoclient_mode, bi->uid.c_str()); - - notice_lang(s_BotServ, u, BOT_BOT_ADDED, bi->nick, bi->user, - bi->host, bi->real); - - send_event(EVENT_BOT_CREATE, 1, bi->nick); - } - } else if (!stricmp(cmd, "CHANGE")) { - char *oldnick = strtok(NULL, " "); - char *nick = strtok(NULL, " "); - char *user = strtok(NULL, " "); - char *host = strtok(NULL, " "); - char *real = strtok(NULL, ""); - - if (!oldnick || !nick) - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); - else if (readonly) - notice_lang(s_BotServ, u, BOT_BOT_READONLY); - else if (!(bi = findbot(oldnick))) - notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, oldnick); - else if (strlen(nick) > NickLen) - notice_lang(s_BotServ, u, BOT_BAD_NICK); - else if (user && strlen(user) >= USERMAX) - notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); - else if (host && strlen(host) > HOSTMAX) - notice_lang(s_BotServ, u, BOT_LONG_HOST, HOSTMAX); - else { - NickAlias *na; + BotInfo *bi; + char *cmd = strtok(NULL, " "); + char *ch = NULL; + + if (!cmd) + { + syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + return MOD_CONT; + } - /* Checks whether there *are* changes. - * Case sensitive because we may want to change just the case. - * And we must finally check that the nick is not already - * taken by another bot. - */ - if (!strcmp(bi->nick, nick) - && ((user) ? !strcmp(bi->user, user) : 1) - && ((host) ? !strcmp(bi->host, host) : 1) - && ((real) ? !strcmp(bi->real, real) : 1)) { - notice_lang(s_BotServ, u, BOT_BOT_ANY_CHANGES); - return MOD_CONT; - } + if (readonly) + { + notice_lang(s_BotServ, u, BOT_BOT_READONLY); + return MOD_CONT; + } - /* Check whether it's a services client's nick and return if so - Certus */ - /* use nickIsServices() to reduce the number of lines of code - TSL */ - if (nickIsServices(nick, 0)) { - notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED); - return MOD_CONT; - } + if (!stricmp(cmd, "ADD")) + { + char *nick = strtok(NULL, " "); + char *user = strtok(NULL, " "); + char *host = strtok(NULL, " "); + char *real = strtok(NULL, ""); + + if (!nick || !user || !host || !real) + { + syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + return MOD_CONT; + } - /** - * Check the nick is valid re RFC 2812 - **/ - if (isdigit(nick[0]) || nick[0] == '-') { - notice_lang(s_BotServ, u, BOT_BAD_NICK); - return MOD_CONT; - } - for (ch = nick; *ch && (ch - nick) < NICKMAX; ch++) { - if (!isvalidnick(*ch)) { - notice_lang(s_BotServ, u, BOT_BAD_NICK); - return MOD_CONT; - } - } + if (findbot(nick)) + { + notice_lang(s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick); + return MOD_CONT; + } + + if (strlen(nick) > NickLen) + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } - /* check for hardcored ircd forbidden nicks */ - if (!ircdproto->IsNickValid(nick)) { - notice_lang(s_BotServ, u, BOT_BAD_NICK); - return MOD_CONT; - } + if (strlen(user) >= USERMAX) + { + notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); + return MOD_CONT; + } - if (host && !isValidHost(host, 3)) { - notice_lang(s_BotServ, u, BOT_BAD_HOST); - return MOD_CONT; - } + if (strlen(user) > HOSTMAX) + { + notice_lang(s_BotServ, u, BOT_LONG_HOST, HOSTMAX); + return MOD_CONT; + } - if (user) { - for (ch = user; *ch && (ch - user) < USERMAX; ch++) { - if (!isalnum(*ch)) { - notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); - return MOD_CONT; - } - } - } + /* Check the nick is valid re RFC 2812 */ + if (isdigit(nick[0]) || nick[0] == '-') + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } - if (stricmp(bi->nick, nick) && findbot(nick)) { - notice_lang(s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick); - return MOD_CONT; - } + for (ch = nick; *ch && (ch - nick) < NICKMAX; ch++) + { + if (!isvalidnick(*ch)) + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + } - if (stricmp(bi->nick, nick)) { - /* We check whether the nick is registered, and inform the user - * if so. You need to drop the nick manually before you can use - * it as a bot nick from now on -GD - */ - if ((na = findnick(nick))) { - notice_lang(s_BotServ, u, NICK_ALREADY_REGISTERED, - nick); - return MOD_CONT; - } + /* check for hardcored ircd forbidden nicks */ + if (!ircdproto->IsNickValid(nick)) + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + /* Check the host is valid re RFC 2812 */ + if (!isValidHost(host, 3)) + { + notice_lang(s_BotServ, u, BOT_BAD_HOST); + return MOD_CONT; + } - /* The new nick is really different, so we remove the Q line for - the old nick. */ - if (ircd->sqline) { - ircdproto->SendSQLineDel(bi->nick); - } + for (ch = user; *ch && (ch - user) < USERMAX; ch++) + { + if (!isalnum(*ch)) + { + notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); + return MOD_CONT; + } + } + - /* We check whether user with this nick is online, and kill it if so */ - EnforceQlinedNick(nick, s_BotServ); - } + /* We check whether the nick is registered, and inform the user + * if so. You need to drop the nick manually before you can use + * it as a bot nick from now on -GD + */ + if (findnick(nick)) + { + notice_lang(s_BotServ, u, NICK_ALREADY_REGISTERED, nick); + return MOD_CONT; + } + + bi = new BotInfo(nick); + if (!bi) + { + notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED); + return MOD_CONT; + } + + bi->user = sstrdup(user); + bi->host = sstrdup(host); + bi->real = sstrdup(real); + bi->created = time(NULL); + bi->chancount = 0; + + /* We check whether user with this nick is online, and kill it if so */ + EnforceQlinedNick(nick, s_BotServ); + + /* We make the bot online, ready to serve */ + ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, + ircd->pseudoclient_mode, bi->uid.c_str()); + + notice_lang(s_BotServ, u, BOT_BOT_ADDED, bi->nick, bi->user, + bi->host, bi->real); + + send_event(EVENT_BOT_CREATE, 1, bi->nick); + } + else if (!stricmp(cmd, "CHANGE")) + { + char *oldnick = strtok(NULL, " "); + char *nick = strtok(NULL, " "); + char *user = strtok(NULL, " "); + char *host = strtok(NULL, " "); + char *real = strtok(NULL, ""); + + if (!oldnick || !nick) + { + syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + return MOD_CONT; + } - if (strcmp(nick, bi->nick)) - bi->ChangeNick(nick); + if (!(bi = findbot(oldnick))) + { + notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, oldnick); + return MOD_CONT; + } - if (user && strcmp(user, bi->user)) { - free(bi->user); - bi->user = sstrdup(user); - } - if (host && strcmp(host, bi->host)) { - free(bi->host); - bi->host = sstrdup(host); - } - if (real && strcmp(real, bi->real)) { - free(bi->real); - bi->real = sstrdup(real); - } + if (strlen(nick) > NickLen) + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } - /* If only the nick changes, we just make the bot change his nick, - else we must make it quit and rejoin. We must not forget to set - the Q:Line either (it's otherwise set in SendClientIntroduction) */ - if (!user) { - ircdproto->SendChangeBotNick(bi, bi->nick); - ircdproto->SendSQLine(bi->nick, "Reserved for services"); - } else { - ircdproto->SendQuit(bi, "Quit: Be right back"); + if (user && strlen(user) >= USERMAX) + { + notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); + return MOD_CONT; + } - ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, - ircd->pseudoclient_mode, bi->uid.c_str()); - bi->RejoinAll(); - } + if (host && strlen(host) > HOSTMAX) + { + notice_lang(s_BotServ, u, BOT_LONG_HOST, HOSTMAX); + return MOD_CONT; + } - notice_lang(s_BotServ, u, BOT_BOT_CHANGED, oldnick, bi->nick, - bi->user, bi->host, bi->real); + if (nickIsServices(nick, 0)) + { + notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST); + return MOD_CONT; + } - send_event(EVENT_BOT_CHANGE, 1, bi->nick); - } - } else if (!stricmp(cmd, "DEL")) { - char *nick = strtok(NULL, " "); + /* Checks whether there *are* changes. + * Case sensitive because we may want to change just the case. + * And we must finally check that the nick is not already + * taken by another bot. + */ + if (!strcmp(bi->nick, nick) + && ((user) ? !strcmp(bi->user, user) : 1) + && ((host) ? !strcmp(bi->host, host) : 1) + && ((real) ? !strcmp(bi->real, real) : 1)) + { + notice_lang(s_BotServ, u, BOT_BOT_ANY_CHANGES); + return MOD_CONT; + } + + /* Check the nick is valid re RFC 2812 */ + if (isdigit(nick[0]) || nick[0] == '-') + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } - if (!nick) + for (ch = nick; *ch && (ch - nick) < NICKMAX; ch++) { - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + if (!isvalidnick(*ch)) + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + } + + /* check for hardcored ircd forbidden nicks */ + if (!ircdproto->IsNickValid(nick)) + { + notice_lang(s_BotServ, u, BOT_BAD_NICK); return MOD_CONT; } - - if (readonly) + + if (host && !isValidHost(host, 3)) + { + notice_lang(s_BotServ, u, BOT_BAD_HOST); + return MOD_CONT; + } + + if (user) { - notice_lang(s_BotServ, u, BOT_BOT_READONLY); + for (ch = user; *ch && (ch - user) < USERMAX; ch++) + { + if (!isalnum(*ch)) + { + notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1); + return MOD_CONT; + } + } + } + + if (stricmp(bi->nick, nick) && findbot(nick)) + { + notice_lang(s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick); + return MOD_CONT; + } + + if (stricmp(bi->nick, nick)) + { + /* We check whether the nick is registered, and inform the user + * if so. You need to drop the nick manually before you can use + * it as a bot nick from now on -GD + */ + if (findnick(nick)) + { + notice_lang(s_BotServ, u, NICK_ALREADY_REGISTERED, nick); + return MOD_CONT; + } + + /* The new nick is really different, so we remove the Q line for + the old nick. */ + if (ircd->sqline) + { + ircdproto->SendSQLineDel(bi->nick); + } + + /* We check whether user with this nick is online, and kill it if so */ + EnforceQlinedNick(nick, s_BotServ); + } + + if (strcmp(nick, bi->nick)) + bi->ChangeNick(nick); + + if (user && strcmp(user, bi->user)) + { + free(bi->user); + bi->user = sstrdup(user); + } + if (host && strcmp(host, bi->host)) + { + free(bi->host); + bi->host = sstrdup(host); + } + if (real && strcmp(real, bi->real)) + { + free(bi->real); + bi->real = sstrdup(real); + } + + /* If only the nick changes, we just make the bot change his nick, + * else we must make it quit and rejoin. We must not forget to set + * the Q:Line either (it's otherwise set in SendClientIntroduction) + */ + if (!user) + { + ircdproto->SendChangeBotNick(bi, bi->nick); + ircdproto->SendSQLine(bi->nick, "Reserved for services"); + } + else + { + ircdproto->SendQuit(bi, "Quit: Be right back"); + ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, + ircd->pseudoclient_mode, bi->uid.c_str()); + bi->RejoinAll(); + } + + notice_lang(s_BotServ, u, BOT_BOT_CHANGED, + oldnick, bi->nick, bi->user, bi->host, bi->real); + + send_event(EVENT_BOT_CHANGE, 1, bi->nick); + } + else if (!stricmp(cmd, "DEL")) + { + char *nick = strtok(NULL, " "); + + if (!nick) + { + syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); return MOD_CONT; } @@ -315,22 +367,23 @@ int do_bot(User * u) notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, nick); return MOD_CONT; } - + if (nickIsServices(nick, 0)) { notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST); return MOD_CONT; } - + send_event(EVENT_BOT_DEL, 1, bi->nick); ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick); ircdproto->SendSQLineDel(bi->nick); delete bi; notice_lang(s_BotServ, u, BOT_BOT_DELETED, nick); - } else - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); - - return MOD_CONT; + } + else + syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + + return MOD_CONT; } |