bs_badwords.c

Go to the documentation of this file.
00001 /* BotServ core functions
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  * $Id: bs_badwords.c 1292 2007-08-31 17:34:42Z drstein $
00012  *
00013  */
00014 /*************************************************************************/
00015 
00016 #include "module.h"
00017 
00018 int do_badwords(User * u);
00019 void myBotServHelp(User * u);
00020 int badwords_del_callback(User * u, int num, va_list args);
00021 int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header);
00022 int badwords_list_callback(User * u, int num, va_list args);
00023 
00030 int AnopeInit(int argc, char **argv)
00031 {
00032     Command *c;
00033 
00034     moduleAddAuthor("Anope");
00035     moduleAddVersion("$Id: bs_badwords.c 1292 2007-08-31 17:34:42Z drstein $");
00036     moduleSetType(CORE);
00037 
00038     c = createCommand("BADWORDS", do_badwords, NULL, BOT_HELP_BADWORDS, -1,
00039                       -1, -1, -1);
00040     moduleAddCommand(BOTSERV, c, MOD_UNIQUE);
00041 
00042     moduleSetBotHelp(myBotServHelp);
00043 
00044     return MOD_CONT;
00045 }
00046 
00050 void AnopeFini(void)
00051 {
00052 
00053 }
00054 
00055 
00056 
00061 void myBotServHelp(User * u)
00062 {
00063     notice_lang(s_BotServ, u, BOT_HELP_CMD_BADWORDS);
00064 }
00065 
00071 int do_badwords(User * u)
00072 {
00073     char *chan = strtok(NULL, " ");
00074     char *cmd = strtok(NULL, " ");
00075     char *word = strtok(NULL, "");
00076     ChannelInfo *ci;
00077     BadWord *bw;
00078 
00079     int i;
00080     int need_args = (cmd
00081                      && (!stricmp(cmd, "LIST") || !stricmp(cmd, "CLEAR")));
00082 
00083     if (!cmd || (need_args ? 0 : !word)) {
00084         syntax_error(s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX);
00085     } else if (!(ci = cs_findchan(chan))) {
00086         notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan);
00087     } else if (ci->flags & CI_VERBOTEN) {
00088         notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan);
00089     } else if (!check_access(u, ci, CA_BADWORDS)
00090                && (!need_args || !is_services_admin(u))) {
00091         notice_lang(s_BotServ, u, ACCESS_DENIED);
00092     } else if (stricmp(cmd, "ADD") == 0) {
00093 
00094         char *opt, *pos;
00095         int type = BW_ANY;
00096 
00097         if (readonly) {
00098             notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED);
00099             return MOD_CONT;
00100         }
00101 
00102         pos = strrchr(word, ' ');
00103         if (pos) {
00104             opt = pos + 1;
00105             if (*opt) {
00106                 if (!stricmp(opt, "SINGLE"))
00107                     type = BW_SINGLE;
00108                 else if (!stricmp(opt, "START"))
00109                     type = BW_START;
00110                 else if (!stricmp(opt, "END"))
00111                     type = BW_END;
00112                 if (type != BW_ANY)
00113                     *pos = 0;
00114             }
00115         }
00116 
00117         for (bw = ci->badwords, i = 0; i < ci->bwcount; bw++, i++) {
00118             if (bw->word && ((BSCaseSensitive && (!strcmp(bw->word, word)))
00119                              || (!BSCaseSensitive
00120                                  && (!stricmp(bw->word, word))))) {
00121                 notice_lang(s_BotServ, u, BOT_BADWORDS_ALREADY_EXISTS,
00122                             bw->word, ci->name);
00123                 return MOD_CONT;
00124             }
00125         }
00126 
00127         for (i = 0; i < ci->bwcount; i++) {
00128             if (!ci->badwords[i].in_use)
00129                 break;
00130         }
00131         if (i == ci->bwcount) {
00132             if (i < BSBadWordsMax) {
00133                 ci->bwcount++;
00134                 ci->badwords =
00135                     srealloc(ci->badwords, sizeof(BadWord) * ci->bwcount);
00136             } else {
00137                 notice_lang(s_BotServ, u, BOT_BADWORDS_REACHED_LIMIT,
00138                             BSBadWordsMax);
00139                 return MOD_CONT;
00140             }
00141         }
00142         bw = &ci->badwords[i];
00143         bw->in_use = 1;
00144         bw->word = sstrdup(word);
00145         bw->type = type;
00146 
00147         notice_lang(s_BotServ, u, BOT_BADWORDS_ADDED, bw->word, ci->name);
00148 
00149     } else if (stricmp(cmd, "DEL") == 0) {
00150         int deleted = 0, a, b;
00151 
00152         if (readonly) {
00153             notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED);
00154             return MOD_CONT;
00155         }
00156 
00157         /* Special case: is it a number/list?  Only do search if it isn't. */
00158         if (isdigit(*word) && strspn(word, "1234567890,-") == strlen(word)) {
00159             int count, last = -1;
00160             deleted =
00161                 process_numlist(word, &count, badwords_del_callback, u, ci,
00162                                 &last);
00163             if (!deleted) {
00164                 if (count == 1) {
00165                     notice_lang(s_BotServ, u, BOT_BADWORDS_NO_SUCH_ENTRY,
00166                                 last, ci->name);
00167                 } else {
00168                     notice_lang(s_BotServ, u, BOT_BADWORDS_NO_MATCH,
00169                                 ci->name);
00170                 }
00171             } else if (deleted == 1) {
00172                 notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED_ONE,
00173                             ci->name);
00174             } else {
00175                 notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL,
00176                             deleted, ci->name);
00177             }
00178         } else {
00179             for (i = 0; i < ci->bwcount; i++) {
00180                 if (ci->badwords[i].in_use
00181                     && !stricmp(ci->badwords[i].word, word))
00182                     break;
00183             }
00184             if (i == ci->bwcount) {
00185                 notice_lang(s_BotServ, u, BOT_BADWORDS_NOT_FOUND, word,
00186                             chan);
00187                 return MOD_CONT;
00188             }
00189             bw = &ci->badwords[i];
00190             notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED, bw->word,
00191                         ci->name);
00192             if (bw->word)
00193                 free(bw->word);
00194             bw->word = NULL;
00195             bw->in_use = 0;
00196             deleted = 1;
00197         }
00198 
00199         if (deleted) {
00200             /* Reordering - DrStein */
00201             for (b = 0; b < ci->bwcount; b++) {
00202                 if (ci->badwords[b].in_use) {
00203                     for (a = 0; a < ci->bwcount; a++) {
00204                         if (a > b)
00205                             break;
00206                         if (!(ci->badwords[a].in_use)) {
00207                             ci->badwords[a].in_use = ci->badwords[b].in_use;
00208                             ci->badwords[a].type = ci->badwords[b].type;
00209                             if (ci->badwords[b].word) {
00210                                 ci->badwords[a].word = sstrdup(ci->badwords[b].word);
00211                                 free(ci->badwords[b].word);
00212                             }
00213                             ci->badwords[b].word = NULL;
00214                             ci->badwords[b].in_use = 0;
00215                             break;
00216                         }
00217                     }
00218                 }
00219             }
00220             /* After reordering only the entries at the end could still be empty.
00221              * We ll free the places no longer in use... - Viper */
00222             for (i = ci->bwcount - 1; i >= 0; i--) {
00223                 if (ci->badwords[i].in_use)
00224                     break;
00225                 ci->bwcount--;
00226             }
00227             ci->badwords =
00228                 srealloc(ci->badwords,sizeof(BadWord) * ci->bwcount);
00229         }
00230 
00231     } else if (stricmp(cmd, "LIST") == 0) {
00232         int sent_header = 0;
00233 
00234         if (ci->bwcount == 0) {
00235             notice_lang(s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, chan);
00236             return MOD_CONT;
00237         }
00238         if (word && strspn(word, "1234567890,-") == strlen(word)) {
00239             process_numlist(word, NULL, badwords_list_callback, u, ci,
00240                             &sent_header);
00241         } else {
00242             for (i = 0; i < ci->bwcount; i++) {
00243                 if (!(ci->badwords[i].in_use))
00244                     continue;
00245                 if (word && ci->badwords[i].word
00246                     && !match_wild_nocase(word, ci->badwords[i].word))
00247                     continue;
00248                 badwords_list(u, i, ci, &sent_header);
00249             }
00250         }
00251         if (!sent_header)
00252             notice_lang(s_BotServ, u, BOT_BADWORDS_NO_MATCH, chan);
00253 
00254     } else if (stricmp(cmd, "CLEAR") == 0) {
00255 
00256         if (readonly) {
00257             notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED);
00258             return MOD_CONT;
00259         }
00260 
00261         for (i = 0; i < ci->bwcount; i++)
00262             if (ci->badwords[i].word)
00263                 free(ci->badwords[i].word);
00264 
00265         free(ci->badwords);
00266         ci->badwords = NULL;
00267         ci->bwcount = 0;
00268 
00269         notice_lang(s_BotServ, u, BOT_BADWORDS_CLEAR);
00270 
00271     } else {
00272         syntax_error(s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX);
00273     }
00274     return MOD_CONT;
00275 }
00276 
00277 int badwords_del_callback(User * u, int num, va_list args)
00278 {
00279     BadWord *bw;
00280     ChannelInfo *ci = va_arg(args, ChannelInfo *);
00281     int *last = va_arg(args, int *);
00282 
00283     *last = num;
00284 
00285     if (num < 1 || num > ci->bwcount)
00286         return 0;
00287 
00288     bw = &ci->badwords[num - 1];
00289     if (bw->word)
00290         free(bw->word);
00291     bw->word = NULL;
00292     bw->in_use = 0;
00293 
00294     return 1;
00295 }
00296 
00297 int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header)
00298 {
00299     BadWord *bw = &ci->badwords[index];
00300 
00301     if (!bw->in_use)
00302         return 0;
00303     if (!*sent_header) {
00304         notice_lang(s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name);
00305         *sent_header = 1;
00306     }
00307 
00308     notice_lang(s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, index + 1,
00309                 bw->word,
00310                 ((bw->type ==
00311                   BW_SINGLE) ? "(SINGLE)" : ((bw->type ==
00312                                               BW_START) ? "(START)"
00313                                              : ((bw->type ==
00314                                                  BW_END) ? "(END)" : "")))
00315         );
00316     return 1;
00317 }
00318 
00319 int badwords_list_callback(User * u, int num, va_list args)
00320 {
00321     ChannelInfo *ci = va_arg(args, ChannelInfo *);
00322     int *sent_header = va_arg(args, int *);
00323     if (num < 1 || num > ci->bwcount)
00324         return 0;
00325     return badwords_list(u, num - 1, ci, sent_header);
00326 }

Generated on Sun Dec 30 09:26:46 2007 for Anope by  doxygen 1.5.1-20070107