Exemplo n.º 1
0
/**
 * The /ms read command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_read(User * u)
{
    MemoInfo *mi;
    ChannelInfo *ci;
    char *numstr = strtok(NULL, " "), *chan = NULL;
    int num, count;

    if (numstr && *numstr == '#') {
        chan = numstr;
        numstr = strtok(NULL, " ");
        if (!(ci = cs_findchan(chan))) {
            notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan);
            return MOD_CONT;
        } else if (ci->flags & CI_VERBOTEN) {
            notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, chan);
            return MOD_CONT;
        } else if (!check_access(u, ci, CA_MEMO)) {
            notice_lang(s_MemoServ, u, ACCESS_DENIED);
            return MOD_CONT;
        }
        mi = &ci->memos;
    } else {
        if (!nick_identified(u)) {
            notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
            return MOD_CONT;
        }
        mi = &u->na->nc->memos;
    }
    num = numstr ? atoi(numstr) : -1;
    if (!numstr
        || (stricmp(numstr, "LAST") != 0 && stricmp(numstr, "NEW") != 0
            && num <= 0)) {
        syntax_error(s_MemoServ, u, "READ", MEMO_READ_SYNTAX);

    } else if (mi->memocount == 0) {
        if (chan)
            notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_MEMOS, chan);
        else
            notice_lang(s_MemoServ, u, MEMO_HAVE_NO_MEMOS);

    } else {
        int i;

        if (stricmp(numstr, "NEW") == 0) {
            int readcount = 0;
            for (i = 0; i < mi->memocount; i++) {
                if (mi->memos[i].flags & MF_UNREAD) {
                    read_memo(u, i, mi, chan);
                    readcount++;
                }
            }
            if (!readcount) {
                if (chan)
                    notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_NEW_MEMOS,
                                chan);
                else
                    notice_lang(s_MemoServ, u, MEMO_HAVE_NO_NEW_MEMOS);
            }
        } else if (stricmp(numstr, "LAST") == 0) {
            for (i = 0; i < mi->memocount - 1; i++);
            read_memo(u, i, mi, chan);
        } else {                /* number[s] */
            if (!process_numlist(numstr, &count, read_memo_callback, u,
                                 mi, chan)) {
                if (count == 1)
                    notice_lang(s_MemoServ, u, MEMO_DOES_NOT_EXIST, num);
                else
                    notice_lang(s_MemoServ, u, MEMO_LIST_NOT_FOUND,
                                numstr);
            }
        }

    }
    return MOD_CONT;
}
Exemplo n.º 2
0
int do_akick(User * u, Channel *c, char *cmd, char *mask, char *reason) {
	ChannelInfo *ci = c->ci;
	AutoKick *akick;
	int i;
	struct c_userlist *cu = NULL, *next = NULL;
	User *u2;
	char *argv[3];
	int count = 0;

	if (!cmd || (!mask && (!stricmp(cmd, "ADD") || !stricmp(cmd, "STICK")
		|| !stricmp(cmd, "UNSTICK") || !stricmp(cmd, "DEL")))) {
		noticeLang(ci->bi->nick, u, LANG_AKICK_SYNTAX);
	} else if (!check_access(u, ci, CA_AKICK) && !is_services_admin(u)) {
		notice_lang(ci->bi->nick, u, ACCESS_DENIED);
	} else if (stricmp(cmd, "ADD") == 0) {
		NickAlias *na = findnick(mask), *na2;
		User *target = finduser(mask);
		NickCore *nc = NULL;
		char *nick, *user, *host;
		int freemask = 0;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (!na) {
			if (target) {
				char tmp[BUFSIZE];
				mask = NULL;
				freemask = 1;
				get_idealban(ci, target, tmp, BUFSIZE);
				mask = sstrdup(tmp);
			} else {
				split_usermask(mask, &nick, &user, &host);
				mask = scalloc(strlen(nick) + strlen(user) + strlen(host) + 3, 1);
				freemask = 1;
				sprintf(mask, "%s!%s@%s", nick, user, host);

				free(nick);
				free(user);
				free(host);
			}
		} else {
			if (na->status & NS_VERBOTEN) {
				notice_lang(ci->bi->nick, u, NICK_X_FORBIDDEN, mask);
				return MOD_CONT;
			}
			nc = na->nc;
		}

		/* Check excepts BEFORE we get this far */
		if (ircd->except) {
			if (is_excepted_mask(ci, mask) == 1) {
				notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, mask, c->name);
				if (freemask) free(mask);
				return MOD_CONT;
			}
		}

		/* Check whether target nick has equal/higher access 
		 * or whether the mask matches a user with higher/equal access ~ Viper */
		if ((ci->flags & CI_PEACE) && nc) {
			if ((nc == ci->founder) || (get_access_nc(nc, ci) >= get_access(u, ci))) {
				notice_lang(s_ChanServ, u, PERMISSION_DENIED);
				if (freemask)
					free(mask);
				return MOD_CONT;
			}
		} else if ((ci->flags & CI_PEACE)) {
			char buf[BUFSIZE];
			/* Match against all currently online users with equal or
			 * higher access. - Viper */
			for (i = 0; i < 1024; i++) {
				for (u2 = userlist[i]; u2; u2 = u2->next) {
					if (is_founder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci))) {
						if (match_usermask(mask, u2)) {
							notice_lang(s_ChanServ, u, PERMISSION_DENIED);
							free(mask);
							return MOD_CONT;
						}
					}
				}
			}

			/* Match against the lastusermask of all nickalias's with equal
			 * or higher access. ~ Viper */
			for (i = 0; i < 1024; i++) {
				for (na2 = nalists[i]; na2; na2 = na2->next) {
					if (na2->status & NS_VERBOTEN)
						continue;

					if (na2->nc && ((na2->nc == ci->founder) || (get_access_nc(na2->nc, ci) 
							>= get_access(u, ci)))) {
						snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask);
						if (match_wild_nocase(mask, buf)) {
							notice_lang(s_ChanServ, u, PERMISSION_DENIED);
							free(mask);
							return MOD_CONT;
						}
					}
				}
			}
		}

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED))
				continue;
			if ((akick->flags & AK_ISNICK) ? akick->u.nc == nc : stricmp(akick->u.mask, mask) == 0) {
				notice_lang(ci->bi->nick, u, CHAN_AKICK_ALREADY_EXISTS, (akick->flags & AK_ISNICK) ? akick->u.nc->
					display : akick->u.mask, c->name);
				if (freemask) free(mask);
				return MOD_CONT;
			}
		}

		/* All entries should be in use so we don't have to go over
		 * the entire list. We simply add new entries at the end. */
		if (ci->akickcount >= CSAutokickMax) {
			notice_lang(s_ChanServ, u, CHAN_AKICK_REACHED_LIMIT, CSAutokickMax);
			if (freemask) free(mask);
			return MOD_CONT;
		}
		ci->akickcount++;
		ci->akick = srealloc(ci->akick, sizeof(AutoKick) * ci->akickcount);

		akick = &ci->akick[i];
		akick->flags = AK_USED;
		if (nc) {
			akick->flags |= AK_ISNICK;
			akick->u.nc = nc;
		} else {
			akick->u.mask = sstrdup(mask);
		}
		akick->creator = sstrdup(u->nick);
		akick->addtime = time(NULL);
		if (reason) {
			if (strlen(reason) > 200)
				reason[200] = '\0';
			akick->reason = sstrdup(reason);
		} else {
			akick->reason = NULL;
		}

		/* Auto ENFORCE #63 */
		cu = c->users;
		while (cu) {
			next = cu->next;
			if (check_kick(cu->user, c->name, c->creation_time)) {
				argv[0] = sstrdup(c->name);
				argv[1] = sstrdup(cu->user->nick);
				if (akick->reason)
					argv[2] = sstrdup(akick->reason);
				else
					argv[2] = sstrdup("none");

				do_kick(ci->bi->nick, 3, argv);

				free(argv[2]);
				free(argv[1]);
				free(argv[0]);
				count++;

			}
			cu = next;
		}
		alog("%s: %s!%s@%s added akick for %s to %s",
				ci->bi->nick, u->nick, u->username, u->host, mask, c->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_ADDED, mask, c->name);

		if (count)
			notice_lang(ci->bi->nick, u, CHAN_AKICK_ENFORCE_DONE, c->name, count);

		if (freemask) free(mask);

	} else if (stricmp(cmd, "STICK") == 0) {
		NickAlias *na;
		NickCore *nc;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, ci->name);
			return MOD_CONT;
		}

		na = findnick(mask);
		nc = (na ? na->nc : NULL);

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
				continue;
			if (!stricmp(akick->u.mask, mask))
				break;
		}

		if (i == ci->akickcount) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_NOT_FOUND, mask, ci->name);
			return MOD_CONT;
		}

		akick->flags |= AK_STUCK;
		alog("%s: %s!%s@%s set STICK on akick %s on %s",
				ci->bi->nick, u->nick, u->username, u->host, akick->u.mask, ci->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_STUCK, akick->u.mask, ci->name);

		if (ci->c)
			stick_mask(ci, akick);

	} else if (stricmp(cmd, "UNSTICK") == 0) {
		NickAlias *na;
		NickCore *nc;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, ci->name);
			return MOD_CONT;
		}

		na = findnick(mask);
		nc = (na ? na->nc : NULL);

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
				continue;
			if (!stricmp(akick->u.mask, mask))
				break;
		}

		if (i == ci->akickcount) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_NOT_FOUND, mask, ci->name);
			return MOD_CONT;
		}

		akick->flags &= ~AK_STUCK;
		alog("%s: %s!%s@%s unset STICK on akick %s on %s",
				ci->bi->nick, u->nick, u->username, u->host, akick->u.mask, ci->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_UNSTUCK, akick->u.mask, ci->name);

	} else if (stricmp(cmd, "DEL") == 0) {
		int deleted, a, b;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, c->name);
			return MOD_CONT;
		}

		/* Special case: is it a number/list?  Only do search if it isn't. */
		if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			int count, last = -1;
			deleted = process_numlist(mask, &count, akick_del_callback, u, ci, &last);
			if (!deleted) {
				if (count == 1) {
					notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_SUCH_ENTRY, last, ci->name);
				} else {
					notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_MATCH, ci->name);
				}
			} else if (deleted == 1) {
				alog("%s: %s!%s@%s deleted 1 akick on %s",
						ci->bi->nick, u->nick, u->username, u->host, ci->name);
				notice_lang(ci->bi->nick, u, CHAN_AKICK_DELETED_ONE, ci->name);
			} else {
				alog("%s: %s!%s@%s deleted %d akicks on %s",
						ci->bi->nick, u->nick, u->username, u->host, deleted, ci->name);
				notice_lang(ci->bi->nick, u, CHAN_AKICK_DELETED_SEVERAL, deleted, ci->name);
			}
		} else {
			NickAlias *na = findnick(mask);
			NickCore *nc = (na ? na->nc : NULL);

			for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
				if (!(akick->flags & AK_USED))
					continue;
				if (((akick->flags & AK_ISNICK) && akick->u.nc == nc) || (!(akick->flags & AK_ISNICK)
					&& stricmp(akick->u.mask, mask) == 0))
					break;
			}
			if (i == ci->akickcount) {
				notice_lang(ci->bi->nick, u, CHAN_AKICK_NOT_FOUND, mask, c->name);
				return MOD_CONT;
			}
			alog("%s: %s!%s@%s deleted akick %s on %s",
					ci->bi->nick, u->nick, u->username, u->host, mask, c->name);
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DELETED, mask, c->name);
			akick_del(u, akick);
			deleted = 1;
		}
		if (deleted) {
			/* Reordering - DrStein */
			for (b = 0; b < ci->akickcount; b++) {
				if (ci->akick[b].flags & AK_USED) {
					for (a = 0; a < ci->akickcount; a++) {
					if (a > b)
						break;
						if (!(ci->akick[a].flags & AK_USED)) {
							ci->akick[a].flags = ci->akick[b].flags;
							if (ci->akick[b].flags & AK_ISNICK) {
								ci->akick[a].u.nc = ci->akick[b].u.nc;
							} else {
								ci->akick[a].u.mask = sstrdup(ci->akick[b].u.mask);
							}
							/* maybe we should first check whether there
							is a reason before we sstdrup it -Certus */
							if (ci->akick[b].reason)
								ci->akick[a].reason = sstrdup(ci->akick[b].reason);
							else
								ci->akick[a].reason = NULL;
							ci->akick[a].creator = sstrdup(ci->akick[b].creator);
							ci->akick[a].addtime = ci->akick[b].addtime;

							akick_del(u, &ci->akick[b]);
							break;
						}
					}
				}
			}

			/* After reordering only the entries at the end could still be empty.
			 * We ll free the places no longer in use... - Viper */
			for (i = ci->akickcount - 1; i >= 0; i--) {
				if (ci->akick[i].flags & AK_USED)
					break;

				ci->akickcount--;
			}
			ci->akick = srealloc(ci->akick,sizeof(AutoKick) * ci->akickcount);
		}
    } else if (stricmp(cmd, "LIST") == 0) {
		int sent_header = 0;

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, c->name);
			return MOD_CONT;
		}
		if (mask && isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			process_numlist(mask, NULL, akick_list_callback, u, ci, &sent_header);
		} else {
			for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
				if (!(akick->flags & AK_USED))
					continue;
				if (mask) {
					if (!(akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.mask))
						continue;
					if ((akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.nc->display))
						continue;
				}
				akick_list(u, i, ci, &sent_header);
			}
		}
		if (!sent_header)
		notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_MATCH, c->name);

	} else if (stricmp(cmd, "VIEW") == 0) {
		int sent_header = 0;

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, c->name);
			return MOD_CONT;
		}
		if (mask && isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			process_numlist(mask, NULL, akick_view_callback, u, ci, &sent_header);
		} else {
			for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
				if (!(akick->flags & AK_USED))
					continue;
				if (mask) {
					if (!(akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.mask))
						continue;
					if ((akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.nc->display))
						continue;
				}
				akick_view(u, i, ci, &sent_header);
			}
		}
		if (!sent_header)
		notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_MATCH, c->name);

	} else if (stricmp(cmd, "ENFORCE") == 0) {
		struct c_userlist *cu = NULL, *next = NULL;
		char *argv[3];
		int count = 0;

		if (!c) {
			notice_lang(ci->bi->nick, u, CHAN_X_NOT_IN_USE, ci->name);
			return MOD_CONT;
		}

		cu = c->users;

		while (cu) {
			next = cu->next;
			if (check_kick(cu->user, c->name, c->creation_time)) {
				argv[0] = sstrdup(c->name);
				argv[1] = sstrdup(cu->user->nick);
				argv[2] = sstrdup(CSAutokickReason);

				do_kick(ci->bi->nick, 3, argv);

				free(argv[2]);
				free(argv[1]);
				free(argv[0]);

				count++;
			}
			cu = next;
		}

		notice_lang(ci->bi->nick, u, CHAN_AKICK_ENFORCE_DONE, ci->name, count);

	} else if (stricmp(cmd, "CLEAR") == 0) {

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED))
				continue;
			akick_del(u, akick);
		}

		free(ci->akick);
		ci->akick = NULL;
		ci->akickcount = 0;

		alog("%s: %s!%s@%s cleared akicks on %s",
				ci->bi->nick, u->nick, u->username, u->host, ci->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_CLEAR, ci->name);

	} else {
		noticeLang(ci->bi->nick, u, LANG_AKICK_SYNTAX);
	}
	return MOD_CONT;
}
Exemplo n.º 3
0
int do_badwords(User * u, Channel *c, char *cmd, char *word, char *style) {
	ChannelInfo *ci = c->ci;
	BadWord *bw;

	int i;
	int need_args = (cmd && (!stricmp(cmd, "LIST") || !stricmp(cmd, "CLEAR")));

	if (!cmd || (need_args ? 0 : !word)) {
		moduleNoticeLang(ci->bi->nick, u, LANG_BADWORDS_SYNTAX, BSFantasyCharacter);
	} else if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !is_services_admin(u))) {
		notice_lang(c->ci->bi->nick, u, ACCESS_DENIED);
	} else if (stricmp(cmd, "ADD") == 0) {
		int type = BW_ANY;

		if (readonly) {
			notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_DISABLED);
			return MOD_CONT;
		}

		if (style) {
			if (!stricmp(style, "SINGLE"))
				type = BW_SINGLE;
			else if (!stricmp(style, "START"))
				type = BW_START;
			else if (!stricmp(style, "END"))
				type = BW_END;
		}

		for (bw = ci->badwords, i = 0; i < ci->bwcount; bw++, i++) {
			if (bw->word && ((BSCaseSensitive && (!strcmp(bw->word, word))) || (!BSCaseSensitive
				&& (!stricmp(bw->word, word))))) {
				notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_ALREADY_EXISTS, bw->word, ci->name);
				return MOD_CONT;
			}
		}

		for (i = 0; i < ci->bwcount; i++) {
			if (!ci->badwords[i].in_use)
				break;
		}
		if (i == ci->bwcount) {
			if (i < BSBadWordsMax) {
				ci->bwcount++;
				ci->badwords = srealloc(ci->badwords, sizeof(BadWord) * ci->bwcount);
			} else {
				notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_REACHED_LIMIT, BSBadWordsMax);
				return MOD_CONT;
			}
		}
		bw = &ci->badwords[i];
		bw->in_use = 1;
		bw->word = sstrdup(word);
		bw->type = type;

		notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_ADDED, bw->word, ci->name);

	} else if (stricmp(cmd, "DEL") == 0) {
		int deleted = 0, a, b;

		if (readonly) {
			notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_DISABLED);
			return MOD_CONT;
		}

		/* Special case: is it a number/list?  Only do search if it isn't. */
		if (isdigit(*word) && strspn(word, "1234567890,-") == strlen(word)) {
			int count, last = -1;
			deleted = process_numlist(word, &count, badwords_del_callback, u, ci, &last);
			if (!deleted) {
				if (count == 1) {
					notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_NO_SUCH_ENTRY, last, ci->name);
				} else {
					notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_NO_MATCH, ci->name);
				}
			} else if (deleted == 1) {
				notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_DELETED_ONE, ci->name);
			} else {
				notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_DELETED_SEVERAL, deleted, ci->name);
			}
		} else {
			for (i = 0; i < ci->bwcount; i++) {
				if (ci->badwords[i].in_use && !stricmp(ci->badwords[i].word, word))
					break;
			}
			if (i == ci->bwcount) {
				notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_NOT_FOUND, word, ci->name);
				return MOD_CONT;
			}
			bw = &ci->badwords[i];
			notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_DELETED, bw->word, ci->name);
			if (bw->word)
				free(bw->word);
			bw->word = NULL;
			bw->in_use = 0;
			deleted = 1;
		}

		if (deleted) {
			/* Reordering - DrStein */
			for (b = 0; b < ci->bwcount; b++) {
				if (ci->badwords[b].in_use) {
					for (a = 0; a < ci->bwcount; a++) {
						if (a > b)
							break;
						if (!(ci->badwords[a].in_use)) {
							ci->badwords[a].in_use = ci->badwords[b].in_use;
							ci->badwords[a].type = ci->badwords[b].type;
							if (ci->badwords[b].word) {
								ci->badwords[a].word = sstrdup(ci->badwords[b].word);
								free(ci->badwords[b].word);
							}
							ci->badwords[b].word = NULL;
							ci->badwords[b].in_use = 0;
							break;
						}
					}
				}
			}
			/* After reordering only the entries at the end could still be empty.
			 * We ll free the places no longer in use... - Viper */
			for (i = ci->bwcount - 1; i >= 0; i--) {
				if (ci->badwords[i].in_use)
					break;
				ci->bwcount--;
			}
			ci->badwords = srealloc(ci->badwords,sizeof(BadWord) * ci->bwcount);
		}

	} else if (stricmp(cmd, "LIST") == 0) {
		int sent_header = 0;

		if (ci->bwcount == 0) {
			notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_LIST_EMPTY, ci->name);
			return MOD_CONT;
		}
		if (word && strspn(word, "1234567890,-") == strlen(word)) {
			process_numlist(word, NULL, badwords_list_callback, u, ci, &sent_header);
		} else {
			for (i = 0; i < ci->bwcount; i++) {
				if (!(ci->badwords[i].in_use))
					continue;
				if (word && ci->badwords[i].word && !my_match_wild_nocase(word, ci->badwords[i].word))
					continue;
				badwords_list(u, i, ci, &sent_header);
			}
		}
		if (!sent_header)
			notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_NO_MATCH, ci->name);

    } else if (stricmp(cmd, "CLEAR") == 0) {
		if (readonly) {
			notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_DISABLED);
			return MOD_CONT;
		}

		for (i = 0; i < ci->bwcount; i++)
			if (ci->badwords[i].word)
				free(ci->badwords[i].word);

		free(ci->badwords);
		ci->badwords = NULL;
		ci->bwcount = 0;

		notice_lang(c->ci->bi->nick, u, BOT_BADWORDS_CLEAR);

	} else {
		moduleNoticeLang(ci->bi->nick, u, LANG_BADWORDS_SYNTAX, BSFantasyCharacter);
	}
	return MOD_CONT;
}
Exemplo n.º 4
0
int do_exception(User * u)
{
    char *cmd = strtok(NULL, " ");
    char *mask, *reason, *expiry, *limitstr;
    int limit, expires;
    int i;
    int x;

    if (!LimitSessions) {
        notice_lang(s_OperServ, u, OPER_EXCEPTION_DISABLED);
        return MOD_CONT;
    }

    if (!cmd)
        cmd = "";

    if (stricmp(cmd, "ADD") == 0) {
        if (nexceptions >= 32767) {
            notice_lang(s_OperServ, u, OPER_EXCEPTION_TOO_MANY);
            return MOD_CONT;
        }

        mask = strtok(NULL, " ");
        if (mask && *mask == '+') {
            expiry = mask;
            mask = strtok(NULL, " ");
        } else {
            expiry = NULL;
        }
        limitstr = strtok(NULL, " ");
        reason = strtok(NULL, "");

        if (!reason) {
            syntax_error(s_OperServ, u, "EXCEPTION",
                         OPER_EXCEPTION_ADD_SYNTAX);
            return MOD_CONT;
        }

        expires = expiry ? dotime(expiry) : ExceptionExpiry;
        if (expires < 0) {
            notice_lang(s_OperServ, u, BAD_EXPIRY_TIME);
            return MOD_CONT;
        } else if (expires > 0) {
            expires += time(NULL);
        }

        limit = (limitstr && isdigit(*limitstr)) ? atoi(limitstr) : -1;

        if (limit < 0 || limit > MaxSessionLimit) {
            notice_lang(s_OperServ, u, OPER_EXCEPTION_INVALID_LIMIT,
                        MaxSessionLimit);
            return MOD_CONT;

        } else {
            if (strchr(mask, '!') || strchr(mask, '@')) {
                notice_lang(s_OperServ, u,
                            OPER_EXCEPTION_INVALID_HOSTMASK);
                return MOD_CONT;
            }

            x = exception_add(u, mask, limit, reason, u->nick, expires);

            if (x == 1) {
                notice_lang(s_OperServ, u, OPER_EXCEPTION_ADDED, mask,
                            limit);
            }

            if (readonly)
                notice_lang(s_OperServ, u, READ_ONLY_MODE);
        }
    } else if (stricmp(cmd, "DEL") == 0) {
        mask = strtok(NULL, " ");

        if (!mask) {
            syntax_error(s_OperServ, u, "EXCEPTION",
                         OPER_EXCEPTION_DEL_SYNTAX);
            return MOD_CONT;
        }

        if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
            int count, deleted, last = -1;
            deleted =
                process_numlist(mask, &count, exception_del_callback, u,
                                &last);
            if (!deleted) {
                if (count == 1) {
                    notice_lang(s_OperServ, u,
                                OPER_EXCEPTION_NO_SUCH_ENTRY, last);
                } else {
                    notice_lang(s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
                }
            } else if (deleted == 1) {
                notice_lang(s_OperServ, u, OPER_EXCEPTION_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_EXCEPTION_DELETED_SEVERAL,
                            deleted);
            }
        } else {
            int deleted = 0;

            for (i = 0; i < nexceptions; i++) {
                if (stricmp(mask, exceptions[i].mask) == 0) {
                    exception_del(i);
                    notice_lang(s_OperServ, u, OPER_EXCEPTION_DELETED,
                                mask);
                    deleted = 1;
                    break;
                }
            }
            if (!deleted && i == nexceptions)
                notice_lang(s_OperServ, u, OPER_EXCEPTION_NOT_FOUND, mask);
        }

        /* Renumber the exception list. I don't believe in having holes in 
         * lists - it makes code more complex, harder to debug and we end up 
         * with huge index numbers. Imho, fixed numbering is only beneficial
         * when one doesn't have range capable manipulation. -TheShadow */

        for (i = 0; i < nexceptions; i++)
            exceptions[i].num = i;

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);

    } else if (stricmp(cmd, "MOVE") == 0) {
        Exception *exception;
        char *n1str = strtok(NULL, " ");        /* From position */
        char *n2str = strtok(NULL, " ");        /* To position */
        int n1, n2;

        if (!n2str) {
            syntax_error(s_OperServ, u, "EXCEPTION",
                         OPER_EXCEPTION_MOVE_SYNTAX);
            return MOD_CONT;
        }

        n1 = atoi(n1str) - 1;
        n2 = atoi(n2str) - 1;

        if ((n1 >= 0 && n1 < nexceptions) && (n2 >= 0 && n2 < nexceptions)
            && (n1 != n2)) {
            exception = scalloc(sizeof(Exception), 1);
            memcpy(exception, &exceptions[n1], sizeof(Exception));

            if (n1 < n2) {
                /* Shift upwards */
                memmove(&exceptions[n1], &exceptions[n1 + 1],
                        sizeof(Exception) * (n2 - n1));
                memmove(&exceptions[n2], exception, sizeof(Exception));
            } else {
                /* Shift downwards */
                memmove(&exceptions[n2 + 1], &exceptions[n2],
                        sizeof(Exception) * (n1 - n2));
                memmove(&exceptions[n2], exception, sizeof(Exception));
            }

            free(exception);

            notice_lang(s_OperServ, u, OPER_EXCEPTION_MOVED,
                        exceptions[n1].mask, n1 + 1, n2 + 1);

            /* Renumber the exception list. See the DEL block above for why. */
            for (i = 0; i < nexceptions; i++)
                exceptions[i].num = i;

            if (readonly)
                notice_lang(s_OperServ, u, READ_ONLY_MODE);
        } else {
            syntax_error(s_OperServ, u, "EXCEPTION",
                         OPER_EXCEPTION_MOVE_SYNTAX);
        }
    } else if (stricmp(cmd, "LIST") == 0) {
        int sent_header = 0;
        expire_exceptions();
        mask = strtok(NULL, " ");
        if (mask && strspn(mask, "1234567890,-") == strlen(mask)) {
            process_numlist(mask, NULL, exception_list_callback, u,
                            &sent_header);
        } else {
            for (i = 0; i < nexceptions; i++) {
                if (!mask || match_wild_nocase(mask, exceptions[i].mask))
                    exception_list(u, i, &sent_header);
            }
        }
        if (!sent_header)
            notice_lang(s_OperServ, u, OPER_EXCEPTION_NO_MATCH);

    } else if (stricmp(cmd, "VIEW") == 0) {
        int sent_header = 0;
        expire_exceptions();
        mask = strtok(NULL, " ");
        if (mask && strspn(mask, "1234567890,-") == strlen(mask)) {
            process_numlist(mask, NULL, exception_view_callback, u,
                            &sent_header);
        } else {
            for (i = 0; i < nexceptions; i++) {
                if (!mask || match_wild_nocase(mask, exceptions[i].mask))
                    exception_view(u, i, &sent_header);
            }
        }
        if (!sent_header)
            notice_lang(s_OperServ, u, OPER_EXCEPTION_NO_MATCH);

    } else {
        syntax_error(s_OperServ, u, "EXCEPTION", OPER_EXCEPTION_SYNTAX);
    }
    return MOD_CONT;
}
Exemplo n.º 5
0
/**
 * List the memos (if any) for the source nick or given channel.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
static int do_list(User * u)
{
    char *param = strtok(NULL, " "), *chan = NULL;
    ChannelInfo *ci;
    MemoInfo *mi;
    Memo *m;
    int i;

    if (param && *param == '#') {
        chan = param;
        param = strtok(NULL, " ");
        if (!(ci = cs_findchan(chan))) {
            notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan);
            return MOD_CONT;
        } else if (ci->flags & CI_VERBOTEN) {
            notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, chan);
            return MOD_CONT;
        } else if (!check_access(u, ci, CA_MEMO)) {
            notice_lang(s_MemoServ, u, ACCESS_DENIED);
            return MOD_CONT;
        }
        mi = &ci->memos;
    } else {
        if (!nick_identified(u)) {
            notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
            return MOD_CONT;
        }
        mi = &u->na->nc->memos;
    }
    if (param && !isdigit(*param) && stricmp(param, "NEW") != 0) {
        syntax_error(s_MemoServ, u, "LIST", MEMO_LIST_SYNTAX);
    } else if (mi->memocount == 0) {
        if (chan)
            notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_MEMOS, chan);
        else
            notice_lang(s_MemoServ, u, MEMO_HAVE_NO_MEMOS);
    } else {
        int sent_header = 0;
        if (param && isdigit(*param)) {
            process_numlist(param, NULL, list_memo_callback, u,
                            mi, &sent_header, chan);
        } else {
            if (param) {
                for (i = 0, m = mi->memos; i < mi->memocount; i++, m++) {
                    if (m->flags & MF_UNREAD)
                        break;
                }
                if (i == mi->memocount) {
                    if (chan)
                        notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_NEW_MEMOS,
                                    chan);
                    else
                        notice_lang(s_MemoServ, u, MEMO_HAVE_NO_NEW_MEMOS);
                    return MOD_CONT;
                }
            }
            for (i = 0, m = mi->memos; i < mi->memocount; i++, m++) {
                if (param && !(m->flags & MF_UNREAD))
                    continue;
                list_memo(u, i, mi, &sent_header, param != NULL, chan);
            }
        }
    }
    return MOD_CONT;
}