00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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
00221
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 }