summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/bs_bot.c527
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;
}