00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "module.h"
00017
00018 int do_bot(User * u);
00019 int delbot(BotInfo * bi);
00020 void myBotServHelp(User * u);
00021 void change_bot_nick(BotInfo * bi, char *newnick);
00022
00029 int AnopeInit(int argc, char **argv)
00030 {
00031 Command *c;
00032
00033 moduleAddAuthor("Anope");
00034 moduleAddVersion("$Id: bs_bot.c 1352 2008-01-24 14:08:36Z drstein $");
00035 moduleSetType(CORE);
00036
00037 c = createCommand("BOT", do_bot, is_services_admin, -1, -1, -1,
00038 BOT_SERVADMIN_HELP_BOT, BOT_SERVADMIN_HELP_BOT);
00039 moduleAddCommand(BOTSERV, c, MOD_UNIQUE);
00040
00041 moduleSetBotHelp(myBotServHelp);
00042
00043 return MOD_CONT;
00044 }
00045
00049 void AnopeFini(void)
00050 {
00051
00052 }
00053
00054
00055
00060 void myBotServHelp(User * u)
00061 {
00062 if (is_services_admin(u)) {
00063 notice_lang(s_BotServ, u, BOT_HELP_CMD_BOT);
00064 }
00065 }
00066
00072 int do_bot(User * u)
00073 {
00074 BotInfo *bi;
00075 char *cmd = strtok(NULL, " ");
00076 char *ch = NULL;
00077
00078 if (!cmd)
00079 syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX);
00080 else if (!stricmp(cmd, "ADD")) {
00081 char *nick = strtok(NULL, " ");
00082 char *user = strtok(NULL, " ");
00083 char *host = strtok(NULL, " ");
00084 char *real = strtok(NULL, "");
00085
00086 if (!nick || !user || !host || !real)
00087 syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX);
00088 else if (readonly)
00089 notice_lang(s_BotServ, u, BOT_BOT_READONLY);
00090 else if (findbot(nick))
00091 notice_lang(s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick);
00092 else if (strlen(nick) > NickLen)
00093 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00094 else if (strlen(user) >= USERMAX)
00095 notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1);
00096 else if (strlen(user) > HOSTMAX)
00097 notice_lang(s_BotServ, u, BOT_LONG_HOST, HOSTMAX);
00098 else {
00099 NickAlias *na;
00100
00104 if (isdigit(nick[0]) || nick[0] == '-') {
00105 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00106 return MOD_CONT;
00107 }
00108 for (ch = nick; *ch && (ch - nick) < NICKMAX; ch++) {
00109 if (!isvalidnick(*ch)) {
00110 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00111 return MOD_CONT;
00112 }
00113 }
00114
00115
00116 if (!anope_valid_nick(nick)) {
00117 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00118 return MOD_CONT;
00119 }
00120
00121 if (!isValidHost(host, 3)) {
00122 notice_lang(s_BotServ, u, BOT_BAD_HOST);
00123 return MOD_CONT;
00124 }
00125 for (ch = user; *ch && (ch - user) < USERMAX; ch++) {
00126 if (!isalnum(*ch)) {
00127 notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1);
00128 return MOD_CONT;
00129 }
00130 }
00131
00136
00137
00138
00139 if (nickIsServices(nick, 0)) {
00140 notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED);
00141 return MOD_CONT;
00142 }
00143
00144
00145
00146
00147
00148 if ((na = findnick(nick))) {
00149 notice_lang(s_BotServ, u, NICK_ALREADY_REGISTERED, nick);
00150 return MOD_CONT;
00151 }
00152
00153 bi = makebot(nick);
00154 if (!bi) {
00155 notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED);
00156 return MOD_CONT;
00157 }
00158
00159 bi->user = sstrdup(user);
00160 bi->host = sstrdup(host);
00161 bi->real = sstrdup(real);
00162 bi->created = time(NULL);
00163 bi->chancount = 0;
00164
00165
00166 EnforceQlinedNick(nick, s_BotServ);
00167
00168
00169 anope_cmd_bot_nick(bi->nick, bi->user, bi->host, bi->real,
00170 ircd->botserv_bot_mode);
00171
00172 notice_lang(s_BotServ, u, BOT_BOT_ADDED, bi->nick, bi->user,
00173 bi->host, bi->real);
00174
00175 send_event(EVENT_BOT_CREATE, 1, bi->nick);
00176 }
00177 } else if (!stricmp(cmd, "CHANGE")) {
00178 char *oldnick = strtok(NULL, " ");
00179 char *nick = strtok(NULL, " ");
00180 char *user = strtok(NULL, " ");
00181 char *host = strtok(NULL, " ");
00182 char *real = strtok(NULL, "");
00183
00184 if (!oldnick || !nick)
00185 syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX);
00186 else if (readonly)
00187 notice_lang(s_BotServ, u, BOT_BOT_READONLY);
00188 else if (!(bi = findbot(oldnick)))
00189 notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, oldnick);
00190 else if (strlen(nick) > NickLen)
00191 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00192 else if (user && strlen(user) >= USERMAX)
00193 notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1);
00194 else if (host && strlen(host) > HOSTMAX)
00195 notice_lang(s_BotServ, u, BOT_LONG_HOST, HOSTMAX);
00196 else {
00197 NickAlias *na;
00198
00199
00200
00201
00202
00203
00204 if (!strcmp(bi->nick, nick)
00205 && ((user) ? !strcmp(bi->user, user) : 1)
00206 && ((host) ? !strcmp(bi->host, host) : 1)
00207 && ((real) ? !strcmp(bi->real, real) : 1)) {
00208 notice_lang(s_BotServ, u, BOT_BOT_ANY_CHANGES);
00209 return MOD_CONT;
00210 }
00211
00212
00213
00214 if (nickIsServices(nick, 0)) {
00215 notice_lang(s_BotServ, u, BOT_BOT_CREATION_FAILED);
00216 return MOD_CONT;
00217 }
00218
00222 if (isdigit(nick[0]) || nick[0] == '-') {
00223 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00224 return MOD_CONT;
00225 }
00226 for (ch = nick; *ch && (ch - nick) < NICKMAX; ch++) {
00227 if (!isvalidnick(*ch)) {
00228 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00229 return MOD_CONT;
00230 }
00231 }
00232
00233
00234 if (!anope_valid_nick(nick)) {
00235 notice_lang(s_BotServ, u, BOT_BAD_NICK);
00236 return MOD_CONT;
00237 }
00238
00239 if (host && !isValidHost(host, 3)) {
00240 notice_lang(s_BotServ, u, BOT_BAD_HOST);
00241 return MOD_CONT;
00242 }
00243
00244 if (user) {
00245 for (ch = user; *ch && (ch - user) < USERMAX; ch++) {
00246 if (!isalnum(*ch)) {
00247 notice_lang(s_BotServ, u, BOT_LONG_IDENT, USERMAX - 1);
00248 return MOD_CONT;
00249 }
00250 }
00251 }
00252
00253 if (stricmp(bi->nick, nick) && findbot(nick)) {
00254 notice_lang(s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick);
00255 return MOD_CONT;
00256 }
00257
00258 if (stricmp(bi->nick, nick)) {
00259
00260
00261
00262
00263 if ((na = findnick(nick))) {
00264 notice_lang(s_BotServ, u, NICK_ALREADY_REGISTERED,
00265 nick);
00266 return MOD_CONT;
00267 }
00268
00269
00270
00271 if (ircd->sqline) {
00272 anope_cmd_unsqline(bi->nick);
00273 }
00274
00275
00276 EnforceQlinedNick(nick, s_BotServ);
00277 }
00278
00279 if (strcmp(nick, bi->nick))
00280 change_bot_nick(bi, nick);
00281
00282 if (user && strcmp(user, bi->user)) {
00283 free(bi->user);
00284 bi->user = sstrdup(user);
00285 }
00286 if (host && strcmp(host, bi->host)) {
00287 free(bi->host);
00288 bi->host = sstrdup(host);
00289 }
00290 if (real && strcmp(real, bi->real)) {
00291 free(bi->real);
00292 bi->real = sstrdup(real);
00293 }
00294
00295
00296
00297
00298 if (!user) {
00299 anope_cmd_chg_nick(oldnick, bi->nick);
00300 anope_cmd_sqline(bi->nick, "Reserved for services");
00301 } else {
00302 anope_cmd_quit(oldnick, "Quit: Be right back");
00303
00304 anope_cmd_bot_nick(bi->nick, bi->user, bi->host, bi->real,
00305 ircd->botserv_bot_mode);
00306 bot_rejoin_all(bi);
00307 }
00308
00309 notice_lang(s_BotServ, u, BOT_BOT_CHANGED, oldnick, bi->nick,
00310 bi->user, bi->host, bi->real);
00311
00312 send_event(EVENT_BOT_CHANGE, 1, bi->nick);
00313 }
00314 } else if (!stricmp(cmd, "DEL")) {
00315 char *nick = strtok(NULL, " ");
00316
00317 if (!nick)
00318 syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX);
00319 else if (readonly)
00320 notice_lang(s_BotServ, u, BOT_BOT_READONLY);
00321 else if (!(bi = findbot(nick)))
00322 notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, nick);
00323 else {
00324 send_event(EVENT_BOT_DEL, 1, bi->nick);
00325 anope_cmd_quit(bi->nick,
00326 "Quit: Help! I'm being deleted by %s!",
00327 u->nick);
00328 if (ircd->sqline) {
00329 anope_cmd_unsqline(bi->nick);
00330 }
00331 delbot(bi);
00332
00333 notice_lang(s_BotServ, u, BOT_BOT_DELETED, nick);
00334 }
00335 } else
00336 syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX);
00337
00338 return MOD_CONT;
00339 }
00340
00341 int delbot(BotInfo * bi)
00342 {
00343 cs_remove_bot(bi);
00344
00345 if (bi->next)
00346 bi->next->prev = bi->prev;
00347 if (bi->prev)
00348 bi->prev->next = bi->next;
00349 else
00350 botlists[tolower(*bi->nick)] = bi->next;
00351
00352 nbots--;
00353
00354 free(bi->nick);
00355 free(bi->user);
00356 free(bi->host);
00357 free(bi->real);
00358
00359 free(bi);
00360
00361 return 1;
00362 }
00363
00364 void change_bot_nick(BotInfo * bi, char *newnick)
00365 {
00366 if (bi->next)
00367 bi->next->prev = bi->prev;
00368 if (bi->prev)
00369 bi->prev->next = bi->next;
00370 else
00371 botlists[tolower(*bi->nick)] = bi->next;
00372
00373 if (bi->nick)
00374 free(bi->nick);
00375 bi->nick = sstrdup(newnick);
00376
00377 insert_bot(bi);
00378 }