Ejemplo n.º 1
0
int list_global_opers(Channel *c, User *u) {
	int j, i , carryon, count = 0;
	User *u2;
	char *access;

	noticeLang(c->ci->bi->nick, u, LANG_GOLIST_HEADER);
	for (j = 0; j < 1024; j++) {
		for (u2 = userlist[j]; u2; u2 = u2->next) {
			carryon = 0;

			/* Prevent listing of users with +H */
			if (finduser((u2->nick)) && !has_umode_H(u2) && !has_umode_B(u2) && !is_ulined(u2->server->name)) {
				i = 0;
				while (i < excempt_nr) {
					if (!ListExempts[i] || !u2->nick)
						break;
					if (my_match_wild_nocase(ListExempts[i], u2->nick)) {
						carryon = 1;
						break;
					}
					i++;
				}

				if (carryon)
					continue;

				if (is_oper(u2)) {
					count++;
					access = getLangString(u->na, LANG_GOLIST_OPER_ONLY);
					if (is_services_oper(u2))
						access = getLangString(u->na, LANG_GOLIST_OPER_AND_SO);
					if (is_services_admin(u2))
						access = getLangString(u->na, LANG_GOLIST_OPER_AND_SA);
					if (is_services_root(u2))
						access = getLangString(u->na, LANG_GOLIST_OPER_AND_SRA);
					notice(c->ci->bi->nick, u->nick, "%-15s  -  %s", u2->nick, access);
				}
			}
		}
	}

	if (count == 0)
		noticeLang(c->ci->bi->nick, u, LANG_GOLIST_NONE);
	noticeLang(c->ci->bi->nick, u, LANG_GOLIST_FOOTER, count);

	return MOD_CONT;
}
Ejemplo 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;
}
Ejemplo n.º 3
0
/* Manage the AKILL list. */
int do_akill(User * u, Channel *c, char *cmd, char *expiry, char *mask, char *reason) {
	ChannelInfo *ci = c->ci;
	char breason[BUFSIZE];

	if (!cmd)
		cmd = "";

	if (!stricmp(cmd, "ADD")) {
		int deleted = 0;
		time_t expires;

		expires = expiry ? dotime(expiry) : AutokillExpiry;
		/* If the expiry given does not contain a final letter, it's in days,
		 * said the doc. Ah well.
		 */
		if (expiry && isdigit(expiry[strlen(expiry) - 1]))
			expires *= 86400;
		/* Do not allow less than a minute expiry time */
		if (expires != 0 && expires < 60) {
			notice_lang(ci->bi->nick, u, BAD_EXPIRY_TIME);
			return MOD_CONT;
		} else if (expires > 0) {
			expires += time(NULL);
		}

		if (mask && reason) {
			/* We first do some sanity check on the proposed mask. */
			if (strchr(mask, '!')) {
				notice_lang(ci->bi->nick, u, OPER_AKILL_NO_NICK);
				return MOD_CONT;
			}

			if (!strchr(mask, '@')) {
				notice_lang(ci->bi->nick, u, BAD_USERHOST_MASK);
				return MOD_CONT;
			}

			if (mask && strspn(mask, "~@.*?") == strlen(mask)) {
				notice_lang(ci->bi->nick, u, USERHOST_MASK_TOO_WIDE, mask);
				return MOD_CONT;
			}

			/**
			* Changed sprintf() to snprintf()and increased the size of
			* breason to match bufsize
			* -Rob
			**/
			if (AddAkiller) {
				snprintf(breason, sizeof(breason), "[%s] %s", u->nick, reason);
				reason = sstrdup(breason);
			}

			deleted = add_akill(u, mask, u->nick, expires, reason);
			if (deleted < 0) {
				return MOD_CONT;
			} else if (deleted) {
				notice_lang(ci->bi->nick, u, OPER_AKILL_DELETED_SEVERAL, deleted);
			}
			notice_lang(ci->bi->nick, u, OPER_AKILL_ADDED, mask);

			alog("[bs_fantasy_ext] %s added an AKILL for %s (%s).", u->nick, mask, reason);

			if (WallOSAkill) {
				char buf[128];

				if (!expires) {
					strcpy(buf, "does not expire");
				} else {
					int wall_expiry = expires - time(NULL);
					char *s = NULL;

					if (wall_expiry >= 86400) {
						wall_expiry /= 86400;
						s = "day";
					} else if (wall_expiry >= 3600) {
						wall_expiry /= 3600;
						s = "hour";
					} else if (wall_expiry >= 60) {
						wall_expiry /= 60;
						s = "minute";
					}

					snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, (wall_expiry == 1) ? "" : "s");
				}

				xanadu_cmd_global(ci->bi->nick, "%s added an AKILL for %s (%s) (%s)", u->nick, mask, reason, buf);
			}

			if (readonly) {
				notice_lang(ci->bi->nick, u, READ_ONLY_MODE);
			}
			/* memleak fixed in the core, forgot it here - Thx Trystan */
            if (AddAkiller) {
                free(reason);
            }
		} else {
			syntax_error(ci->bi->nick, u, "AKILL", OPER_AKILL_SYNTAX);
		}

	} else if (!stricmp(cmd, "DEL")) {
		int res = 0;

		if (!mask) {
			syntax_error(ci->bi->nick, u, "AKILL", OPER_AKILL_SYNTAX);
			return MOD_CONT;
		}

		if (akills.count == 0) {
			notice_lang(ci->bi->nick, u, OPER_AKILL_LIST_EMPTY);
			return MOD_CONT;
		}

		if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			/* Deleting a range */
			res = slist_delete_range(&akills, mask, NULL);
			if (res == 0) {
				notice_lang(ci->bi->nick, u, OPER_AKILL_NO_MATCH);
				return MOD_CONT;
			} else if (res == 1) {
				notice_lang(ci->bi->nick, u, OPER_AKILL_DELETED_ONE);
			} else {
				notice_lang(ci->bi->nick, u, OPER_AKILL_DELETED_SEVERAL,res);
			}

			alog("[bs_fantasy_ext] %s deleted %d AKILLs.", u->nick, res);
		} else {
			if ((res = slist_indexof(&akills, mask)) == -1) {
				notice_lang(ci->bi->nick, u, OPER_AKILL_NOT_FOUND, mask);
				return MOD_CONT;
			}

			slist_delete(&akills, res);
			notice_lang(ci->bi->nick, u, OPER_AKILL_DELETED, mask);

			alog("[bs_fantasy_ext] %s deleted an AKILL for %s.", u->nick, mask);
		}

		if (readonly)
			notice_lang(ci->bi->nick, u, READ_ONLY_MODE);

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

		if (akills.count == 0) {
			notice_lang(ci->bi->nick, u, OPER_AKILL_LIST_EMPTY);
			alog("[bs_fantasy_ext] %s requested the AKILL list.", u->nick);
			return MOD_CONT;
		}

		if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) {
			res = slist_enum(&akills, mask, &akill_list_callback, u, ci, &sent_header);
			if (res == 0) {
				notice_lang(ci->bi->nick, u, OPER_AKILL_NO_MATCH);
				alog("[bs_fantasy_ext] %s requested the AKILL list entrie(s) %s.", u->nick, mask);
				return MOD_CONT;
			} else {
				notice_lang(ci->bi->nick, u, END_OF_ANY_LIST, "Akill");
			}
		} else {
			int i;
			char amask[BUFSIZE];

			for (i = 0; i < akills.count; i++) {
				snprintf(amask, sizeof(amask), "%s@%s", ((Akill *) akills.list[i])->user, ((Akill *) akills.list[i])->host);
				if (!stricmp(mask, amask) || my_match_wild_nocase(mask, amask))
					akill_list(i + 1, akills.list[i], u, &sent_header, ci);
			}

			if (!sent_header)
				notice_lang(ci->bi->nick, u, OPER_AKILL_NO_MATCH);
			else {
				notice_lang(ci->bi->nick, u, END_OF_ANY_LIST, "Akill");
			}
		}

		alog("[bs_fantasy_ext] %s requested the AKILL list.", u->nick);
	} else if (!stricmp(cmd, "VIEW")) {
		int res, sent_header = 0;

		if (akills.count == 0) {
			notice_lang(ci->bi->nick, u, OPER_AKILL_LIST_EMPTY);
			return MOD_CONT;
		}

		if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) {
			res = slist_enum(&akills, mask, &akill_view_callback, u, ci, &sent_header);
		if (res == 0) {
			notice_lang(ci->bi->nick, u, OPER_AKILL_NO_MATCH);
			return MOD_CONT;
			}
		} else {
			int i;
			char amask[BUFSIZE];

			for (i = 0; i < akills.count; i++) {
				snprintf(amask, sizeof(amask), "%s@%s", ((Akill *) akills.list[i])->user, ((Akill *) akills.list[i])->host);
				if (!stricmp(mask, amask) || my_match_wild_nocase(mask, amask))
					akill_view(i + 1, akills.list[i], u, &sent_header, ci);
		}

		if (!sent_header)
			notice_lang(ci->bi->nick, u, OPER_AKILL_NO_MATCH);
		}
	} else if (!stricmp(cmd, "CLEAR")) {
		slist_clear(&akills, 1);
		notice_lang(ci->bi->nick, u, OPER_AKILL_CLEAR);

		alog("[bs_fantasy_ext] %s cleared the AKILL list.", u->nick);
	} else {
		syntax_error(ci->bi->nick, u, "AKILL", OPER_AKILL_SYNTAX);
	}
	return MOD_CONT;
}
Ejemplo n.º 4
0
int do_core_kick(User * u, Channel *c, char *target, char *reason) {
	ChannelInfo *ci = c->ci;
	User *u2;
	int is_same, exists;

	if (!target)
		target = u->nick;

	is_same = (target == u->nick) ? 1 : (stricmp(target, u->nick) == 0);

	if (is_same) {
		u2 = u;
		exists = 1;
	} else
		exists = ((u2 = finduser(target)) ? 1 : 0);

	if (!is_same ? !check_access(u, ci, CA_KICK) : !check_access(u, ci, CA_KICKME)) {
		notice_lang(ci->bi->nick, u, ACCESS_DENIED);
	} else if (!is_same && exists && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (exists && ((ircd->protectedumode && is_protected(u2)) && !is_founder(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (exists && RestrictKB && ((!is_founder(u, ci) && is_services_oper(u2)) ||
			(is_founder(u, ci) && is_services_admin(u2)))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (stricmp(target, ci->bi->nick) == 0) {
		bot_raw_kick(u, ci, u->nick, "Oops!");
	} else {
		if (exists) {
			if (is_on_chan(ci->c, u2)) {
				if (!reason)
					bot_raw_kick(u, ci, target, "Requested");
				else
					bot_raw_kick(u, ci, target, reason);
			}

		} else {
			char mask[BUFSIZE];
			struct c_userlist *cu = NULL, *next = NULL;

			if (my_match_wild_nocase("*!*@*", target))
				snprintf(mask, BUFSIZE, "%s", target);
			/* If we get a *@* target we need to add the *!... */
			else if (my_match_wild_nocase("*@*", target))
				snprintf(mask, BUFSIZE, "*!%s", target);
			else if (my_match_wild_nocase("*!*", target))
				snprintf(mask, BUFSIZE, "%s@*", target);
			/* If we get a * target we need to add the !*@* (assume nick)... */
			else
				snprintf(mask, BUFSIZE, "%s!*@*", target);

			cu = c->users;
			while (cu) {
				next = cu->next;
				/* This only checks against the cloacked host & vhost for normal users.
				 * IPs are only checked when triggered by an oper.. */
				if (is_oper(u) ? match_usermask_full(mask, cu->user, true) : match_usermask(mask, cu->user)) {
					/* Check whether we are allowed to kick this matching user.. */
					if (!((ircd->protectedumode && is_protected(cu->user) && !is_founder(u, ci))
							|| ((ci->flags & CI_PEACE) && (get_access(cu->user, ci) >= get_access(u, ci)))
							|| (RestrictKB && ((!is_founder(u, ci) && is_services_oper(cu->user)) ||
							(is_founder(u, ci) && is_services_admin(cu->user)))))) {
						if (!reason)
							bot_raw_kick(u, ci, cu->user->nick, "Requested");
						else
							bot_raw_kick(u, ci, cu->user->nick, reason);
					}
				}
				cu = next;
			}
		}
	}
	return MOD_CONT;
}
Ejemplo n.º 5
0
int do_core_kickban(User * u, Channel *c, char *target, char *reason) {
	ChannelInfo *ci = c->ci;
	User *u2;
	int is_same, exists;
	char *av[2];

	if (!target)
		target = u->nick;

	is_same = (target == u->nick) ? 1 : (stricmp(target, u->nick) == 0);

	if (is_same) {
		u2 = u;
		exists = 1;
	} else
		exists = ((u2 = finduser(target)) ? 1 : 0);

	if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME)) {
		notice_lang(ci->bi->nick, u, ACCESS_DENIED);
	} else if (!is_same && exists && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (exists && ((ircd->protectedumode && is_protected(u2)) && !is_founder(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	/**
	 * Dont ban the user on channels where he is excepted
	 * to prevent services <-> server wars.
	 **/
	} else if (exists && (ircd->except && is_excepted(ci, u2))) {
		notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, u2->nick, ci->name);
	} else if (!exists && (ircd->except && is_excepted_mask(ci, target))) {
		notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, target, ci->name);
	} else if (exists && RestrictKB && ((!is_founder(u, ci) && is_services_oper(u2)) ||
			(is_founder(u, ci) && is_services_admin(u2)))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (stricmp(target, ci->bi->nick) == 0) {
		bot_raw_ban(u, ci, u->nick, "Oops!");
	} else {
		if (exists) {
			if (is_on_chan(ci->c, u2)) {
				if (!reason)
					bot_raw_ban(u, ci, target, "Requested");
				else
					bot_raw_ban(u, ci, target, reason);
			}

		} else if (my_match_wild_nocase("*@*", target)) {
			char mask[BUFSIZE];

			/* If we get a *@* target we need to add the *!... */
			if (!my_match_wild_nocase("*!*@*", target))
				snprintf(mask, BUFSIZE, "*!%s", target);
			else
				snprintf(mask, BUFSIZE, "%s", target);

			/* Only continue if the mask doesn't match an exception or is otherwise prohibited.. */
			if (check_banmask(u, c, mask)) {
				struct c_userlist *cu = NULL, *next = NULL;

				av[0] = "+b";
				av[1] = mask;

				anope_cmd_mode(ci->bi->nick, c->name, "+b %s", av[1]);
				chan_set_modes(ci->bi->nick, c, 2, av, 1);

				cu = c->users;
				while (cu) {
					next = cu->next;
					/* This only checks against the cloacked host & vhost for normal users.
					 * IPs are only checked when triggered by an oper.. */
					if (is_oper(u) ? match_usermask_full(mask, cu->user, true) : match_usermask(mask, cu->user)) {
						if (!reason)
							bot_raw_kick(u, ci, cu->user->nick, "Requested");
						else
							bot_raw_kick(u, ci, cu->user->nick, reason);
					}
					cu = next;
				}
			}
		} else
			noticeLang(ci->bi->nick, u, LANG_REQ_NICK_OR_MASK);
	}
	return MOD_CONT;
}
Ejemplo n.º 6
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;
}