Пример #1
0
int do_invite(User * u, Channel *c, char *nick) {
	ChannelInfo *ci = c->ci;

	if (!nick)
		noticeLang(ci->bi->nick, u, LANG_INVITE_SYNTAX);

	else {
		if (check_access(u, ci, CA_OPDEOP)	&& check_access(u, ci, CA_OPDEOPME)) {
			User *u2;

			if ((u2 = finduser(nick))) {
				if (stricmp(u2->nick, u->nick) != 0) {
					if (!is_on_chan(c, u2)) {
						anope_cmd_invite(ci->bi->nick, ci->name, u2->nick);
						notice(ci->bi->nick, ci->name, "%s was invited to the channel.", u2->nick);
					} else
						noticeLang(ci->bi->nick, u, LANG_INVITE_IS_ON);
				} else
					noticeLang(ci->bi->nick, u, LANG_INVITE_YOURSELF);
			} else
				noticeLang(ci->bi->nick, u, LANG_INVITE_NO_USER);
		} else
			notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	}

	return MOD_CONT;
}
Пример #2
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;
}
Пример #3
0
int list_admins(Channel *c, User *u) {
	int j, i , carryon, count = 0;
	User *u2;

	noticeLang(c->ci->bi->nick, u, LANG_ADLIST_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 (!stricmp(u2->nick, ListExempts[i]))
						carryon = 1;
					i++;
				}

				if (carryon)
					continue;

				if (is_oper(u2)) {
					if (is_services_root(u2)) {
						count++;
						notice(c->ci->bi->nick, u->nick, "%-15s  -  %s", u2->nick, getLangString(u->na, LANG_ADLIST_SRA));
						continue;
					}
					if (is_services_admin(u2)) {
						count++;
						notice(c->ci->bi->nick, u->nick, "%-15s  -  %s", u2->nick, getLangString(u->na, LANG_ADLIST_SA));
					}
				}
			}
		}
	}

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

	return MOD_CONT;
}
Пример #4
0
int append_to_topic(User * u, Channel *c, char *newtopic) {
	char topic[1024];
	ChannelInfo *ci = c->ci;

	if (!newtopic) {
		noticeLang(ci->bi->nick, u, LANG_APPENDT_SYNTAX);
		return MOD_STOP;
	}

	if (ci->flags & CI_VERBOTEN) {
		notice_lang(ci->bi->nick, u, CHAN_X_FORBIDDEN, ci->name);
		return MOD_STOP;
	}

	if (!my_check_access(u, ci, CA_TOPIC) && ((ci->flags & CI_TOPICLOCK) || !my_check_access(u, ci, CA_OPDEOPME))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
		return MOD_STOP;
	}

	if (ci->last_topic) {
		snprintf(topic, sizeof(topic), "%s %s %s", ci->last_topic,
			(AppendToTopicDel ? AppendToTopicDel : "||"), newtopic);
		free(ci->last_topic);
	} else
		strcpy(topic, newtopic);

	ci->last_topic = *topic ? sstrdup(topic) : NULL;
	strscpy(ci->last_topic_setter, u->nick, NICKMAX);
	ci->last_topic_time = time(NULL);

	if (c->topic) free(c->topic);
	c->topic = *topic ? sstrdup(topic) : NULL;
	strscpy(c->topic_setter, u->nick, NICKMAX);

	if (ircd->topictsbackward) {
		c->topic_time = c->topic_time - 1;
	} else {
		c->topic_time = ci->last_topic_time;
	}

	if (is_services_admin(u) && !check_access(u, ci, CA_TOPIC) &&
			((ci->flags & CI_TOPICLOCK) || !check_access(u, ci, CA_OPDEOPME)))
		alog("%s: %s!%s@%s changed topic of %s as services admin.",
			ci->bi->nick, u->nick, u->username, u->host, c->name);

	anope_cmd_topic(ci->bi->nick, c->name, u->nick, topic, c->topic_time);

	return MOD_CONT;
}
Пример #5
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;
}
Пример #6
0
int do_clear(User *u, Channel *c, int type) {
/* 1= Modes
 * 2= Bans
 * 3= Excepts
 * 4= Invites
 * 5= Ops
 * 6= Hops
 * 7= Voices
 * 8= Users */

	/* Clear Channel Modes */
	if (type == 1) {
		char *argv[2];

		notice(c->ci->bi->nick, c->name, "CLEAR MODES command from %s", u->nick);

		if (c->mode) {
			/* Clear modes the bulk of the modes */
			anope_cmd_mode(c->ci->bi->nick, c->name, "%s", ircd->modestoremove);
			argv[0] = sstrdup(ircd->modestoremove);
			chan_set_modes(c->ci->bi->nick, c, 1, argv, 0);
			free(argv[0]);

			if (c->key) {
				anope_cmd_mode(c->ci->bi->nick, c->name, "-k %s", c->key);
				argv[0] = sstrdup("-k");
				argv[1] = c->key;
				chan_set_modes(c->ci->bi->nick, c, 2, argv, 0);
				free(argv[0]);
			}
			if (ircd->Lmode && c->redirect) {
				anope_cmd_mode(c->ci->bi->nick, c->name, "-L %s", c->redirect);
				argv[0] = sstrdup("-L");
				argv[1] = c->redirect;
				chan_set_modes(c->ci->bi->nick, c, 2, argv, 0);
				free(argv[0]);
			}
			if (ircd->fmode && c->flood) {
				if (flood_mode_char_remove) {
					anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", flood_mode_char_remove, c->flood);
					argv[0] = sstrdup(flood_mode_char_remove);
					argv[1] = c->flood;
					chan_set_modes(c->ci->bi->nick, c, 2, argv, 0);
					free(argv[0]);
				}
			}
			check_modes(c);
		}

	/* Clear Channel Bans */
	} else if (type == 2) {
		char *av[2];
		Entry *ban, *next;

		notice(c->ci->bi->nick, c->name, "CLEAR BANS command from %s", u->nick);
		if (c->bans && c->bans->count) {
			if (ircd->svsmode_ucmode) {
				anope_cmd_svsmode_chan(c->name, "-b", NULL);
				av[0] = "-b";
				for (ban = c->bans->entries; ban; ban = next) {
					next = ban->next;
					av[1] = ban->mask;
					chan_set_modes(c->ci->bi->nick, c, 2, av, 0);
				}
			} else {
				av[0] = "-b";
				for (ban = c->bans->entries; ban; ban = next) {
					next = ban->next;
					av[1] = ban->mask;
					anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]);
					chan_set_modes(c->ci->bi->nick, c, 2, av, 0);
				}
			}
		}

	/* Clear Channel Excepts */
	} else if (ircd->except && type == 3) {
		char *av[2];
		Entry *except, *next;

		notice(c->ci->bi->nick, c->name, "CLEAR EXCEPTS command from %s", u->nick);
		if (c->excepts && c->excepts->count) {
			if (ircd->svsmode_ucmode) {
				anope_cmd_svsmode_chan(c->name, "-e", NULL);
				av[0] = "-e";
				for (except = c->excepts->entries; except; except = next) {
					next = except->next;
					av[1] = except->mask;
					chan_set_modes(c->ci->bi->nick, c, 2, av, 0);
				}
			} else {
				av[0] = "-e";
				for (except = c->excepts->entries; except; except = next) {
					next = except->next;
					av[1] = except->mask;
					anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]);
					chan_set_modes(c->ci->bi->nick, c, 2, av, 0);
				}
			}
		}
	} else if (!(ircd->except) && type == 3) {
		noticeLang(c->ci->bi->nick, u, LANG_EXCEPTS_UNSUPPORTED);

	/* Clear Channel Invites */
	} else if (ircd->invitemode && type == 4) {
		char *av[2];
		Entry *invite, *next;

		notice(c->ci->bi->nick, c->name, "CLEAR INVITES command from %s", u->nick);
		if (c->invites && c->invites->count) {
			if (ircd->svsmode_ucmode) {
				anope_cmd_svsmode_chan(c->name, "-e", NULL);
				av[0] = "-I";
				for (invite = c->invites->entries; invite; invite = next) {
					next = invite->next;
					av[1] = invite->mask;
					chan_set_modes(c->ci->bi->nick, c, 2, av, 0);
				}
			} else {
				av[0] = "-I";
				for (invite = c->invites->entries; invite; invite = next) {
					next = invite->next;
					av[1] = invite->mask;
					anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]);
					chan_set_modes(c->ci->bi->nick, c, 2, av, 0);
				}
			}
		}
	} else if (!(ircd->invitemode) && type == 4) {
		noticeLang(c->ci->bi->nick, u, LANG_INVITEMODE_UNSUPPORTED);

	/* Clear Channel OPs */
	} else if (type == 5) {
		char *av[6];  /* The max we have to hold: chan, ts, modes(max3), nick, nick, nick */
		int ac, isop, isadmin, isown, count, i;
		char buf[BUFSIZE], tmp[BUFSIZE], tmp2[BUFSIZE];
		struct c_userlist *cu, *next;

		notice(c->ci->bi->nick, c->name, "CLEAR OPS command from %s", u->nick);

		av[0] = c->name;
		if (ircd->svsmode_ucmode) {
			anope_cmd_svsmode_chan(c->name, "-o", NULL);
			if (ircd->owner) {
				anope_cmd_svsmode_chan(c->name, ircd->ownerunset, NULL);
			}
			if (ircd->protect || ircd->admin) {
				anope_cmd_svsmode_chan(c->name, ircd->adminunset, NULL);
			}
			for (cu = c->users; cu; cu = next) {
				next = cu->next;
				isop = chan_has_user_status(c, cu->user, CUS_OP);
				isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT);
				isown = chan_has_user_status(c, cu->user, CUS_OWNER);
				count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0);

				if (!isop && !isadmin && !isown)
					continue;

				snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ?
						ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : ""));

				if (ircdcap->tsmode) {
					snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
					av[1] = buf;
					av[2] = tmp;
					/* We have to give as much nicks as modes.. - Viper */
					for (i = 0; i < count; i++)
						av[i+3] = cu->user->nick;
					ac = 3 + i;
				} else {
					av[1] = tmp;
					/* We have to give as much nicks as modes.. - Viper */
					for (i = 0; i < count; i++)
						av[i+2] = cu->user->nick;
					ac = 2 + i;
				}
				do_cmode(c->ci->bi->nick, ac, av);
			}
		} else {
			for (cu = c->users; cu; cu = next) {
				next = cu->next;
				isop = chan_has_user_status(c, cu->user, CUS_OP);
				isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT);
				isown = chan_has_user_status(c, cu->user, CUS_OWNER);
				count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0);

				if (!isop && !isadmin && !isown)
					continue;

				snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? 
						ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : ""));
				/* We need to send the IRCd a nick for every mode.. - Viper */
				snprintf(tmp2, BUFSIZE, "%s %s %s", (isop ? cu->user->nick : ""), 
						(isadmin ? cu->user->nick : ""), (isown ? cu->user->nick : ""));

				if (ircdcap->tsmode) {
					snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
					av[1] = buf;
					av[2] = tmp;
					/* We have to give as much nicks as modes.. - Viper */
					for (i = 0; i < count; i++)
						av[i+3] = cu->user->nick;
					ac = 3 + i;
					anope_cmd_mode(c->ci->bi->nick, av[0], "%s %s", av[2], tmp2);
				} else {
					av[1] = tmp;
					/* We have to give as much nicks as modes.. - Viper */
					for (i = 0; i < count; i++)
						av[i+2] = cu->user->nick;
					ac = 2 + i;
					anope_cmd_mode(c->ci->bi->nick, av[0], "%s %s", av[1], tmp2);
				}
				do_cmode(c->ci->bi->nick, ac, av);
			}
		}

	/* Clear Channel HOPs */
	} else if (ircd->halfop && type == 6) {
		char *av[4];
		struct c_userlist *cu, *next;
		char buf[BUFSIZE];
		int ac;

		notice(c->ci->bi->nick, c->name, "CLEAR HOPS command from %s", u->nick);

		av[0] = c->name;
		if (ircdcap->tsmode)
			av[2] = sstrdup("-h");
		else
			av[1] = sstrdup("-h");

		if (ircd->svsmode_ucmode) {
			anope_cmd_svsmode_chan(c->name, "-h", NULL);

			for (cu = c->users; cu; cu = next) {
				next = cu->next;
				if (!chan_has_user_status(c, cu->user, CUS_HALFOP))
					continue;

				if (ircdcap->tsmode) {
					snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
					av[1] = buf;
					av[3] = cu->user->nick;
					ac = 4;
				} else {
					av[2] = cu->user->nick;
					ac = 3;
				}

				do_cmode(c->ci->bi->nick, ac, av);
			}
		} else {
			for (cu = c->users; cu; cu = next) {
				next = cu->next;
				if (!chan_has_user_status(c, cu->user, CUS_HALFOP))
					continue;

				if (ircdcap->tsmode) {
					snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
					av[1] = buf;
					av[3] = cu->user->nick;
					ac = 4;
				} else {
					av[2] = cu->user->nick;
					ac = 3;
				}

				anope_cmd_mode(c->ci->bi->nick, c->name, "-h %s", cu->user->nick);
				do_cmode(c->ci->bi->nick, ac, av);
			}
		}

		if (ircdcap->tsmode)
			free(av[2]);
		else
			free(av[1]);

	} else if (!(ircd->halfop) && type == 6) {
		noticeLang(c->ci->bi->nick, u, LANG_HOPS_UNSUPPORTED);

	/* Clear Channel Voices */
    } else if (type == 7) {
		char *av[4];
		struct c_userlist *cu, *next;
		char buf[BUFSIZE];
		int ac;

		notice(c->ci->bi->nick, c->name, "CLEAR VOICES command from %s", u->nick);

		av[0] = c->name;
		if (ircdcap->tsmode)
			av[2] = sstrdup("-v");
		else
			av[1] = sstrdup("-v");

		if (ircd->svsmode_ucmode) {
			anope_cmd_svsmode_chan(av[0], "-v", NULL);

			for (cu = c->users; cu; cu = next) {
				next = cu->next;
				if (!chan_has_user_status(c, cu->user, CUS_VOICE))
					continue;

				if (ircdcap->tsmode) {
					snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
					av[1] = buf;
					av[3] = cu->user->nick;
					ac = 4;
				} else {
					av[2] = cu->user->nick;
					ac = 3;
				}

				do_cmode(c->ci->bi->nick, ac, av);
			}
		} else {
			for (cu = c->users; cu; cu = next) {
				next = cu->next;
				if (!chan_has_user_status(c, cu->user, CUS_VOICE))
					continue;

				if (ircdcap->tsmode) {
					snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
					av[1] = buf;
					av[3] = cu->user->nick;
					ac = 4;
				} else {
					av[2] = cu->user->nick;
					ac = 3;
				}

				anope_cmd_mode(c->ci->bi->nick, c->name, "-v %s", cu->user->nick);
				do_cmode(c->ci->bi->nick, ac, av);
			}
		}

		if (ircdcap->tsmode)
			free(av[2]);
		else
			free(av[1]);

	/* Clear Channel Users */
	} else if (type == 8) {
		char *av[3];
		struct c_userlist *cu, *next;
		char buf[256];

		snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick);
		notice(c->ci->bi->nick, c->name, buf);

		av[0] = c->name;
		av[2] = buf;
		for (cu = c->users; cu; cu = next) {
			next = cu->next;
			av[1] = cu->user->nick;
			anope_cmd_kick(c->ci->bi->nick, av[0], av[1], av[2]);
			do_kick(c->ci->bi->nick, 3, av);
		}
	}

	/* Should NEVER happen, therefor if it does, stop processing */
	else {
		alog("[bs_fantasy_ext] An error has occured while processing CLEAR !!!");
		return MOD_STOP;
	}

	return MOD_CONT;
}
Пример #7
0
int do_sync(User *u, Channel *c) {
	struct c_userlist *cu, *next;
	/* Variables needed for building the cmd to remove voices.. */
	int count = 0, newac = 0;
	char modes[BUFSIZE], nicks[BUFSIZE], buf[BUFSIZE];
	char *end1, *end2;
	char **newav = scalloc(sizeof(char *) * 13, 1);
	end1 = modes;
	end2 = nicks;
	*end1 = 0;
	*end2 = 0;
	newav[newac] = c->name;
	newac++;

	if (!c->ci) {
		free(newav);
		return MOD_CONT;
	}

	if (ircdcap->tsmode) {
		snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
		newav[newac] = buf;
		newac++;
	}

	cu = c->users;
	while (cu) {
		/* We store the next user just in case current user ends up getting kicked off the channel. */
		next = cu->next;
		do_up_down(cu->user, c, "up", 0);

		/* We have to remove voices manually because the cores function doesn't care about that
		 * as it's not covered by secureops.. */
		if (chan_has_user_status(c, cu->user, CUS_VOICE) && !check_access(cu->user, c->ci, CA_AUTOVOICE)
				&& !check_access(cu->user, c->ci, CA_VOICEME) && !check_access(cu->user, c->ci, CA_VOICE)) {
			/* Add the user to the string to remove his voice.. */
			end1 += snprintf(end1, sizeof(modes) - (end1 - modes), "-v");
			end2 += snprintf(end2, sizeof(nicks) - (end2 - nicks), "%s ", GET_USER(cu->user));
			newav[newac+1] = GET_USER(cu->user);
			newac++;
			count++;

			/* Check whether the command hasn't grown too long yet.
			 * We don't allow more then 10 mode changes per command.. this should keep us safely below the 512 max length per cmd. */
			if (count == 10) {
				/* We've reached the maximum.. send the mode changes. */
				if (ircdcap->tsmode)
					newav[2] = modes;
				else
					newav[1] = modes;
				newac++;

				anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", modes, nicks);
				do_cmode(c->ci->bi->nick, newac, newav);

				/* Reset the buffer for the next set of changes.. */
				if (ircdcap->tsmode)
					newac = 2;
				else
					newac = 1;
				*end1 = 0;
				*end2 = 0;
				count = 0;
			}
		}

		cu = next;
	}

	/* If we still have some mode changes to send, do it now.. */
	if (count > 0) {
		if (ircdcap->tsmode)
			newav[2] = modes;
		else
			newav[1] = modes;
		newac++;

		anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", modes, nicks);
		do_cmode(c->ci->bi->nick, newac, newav);
	}

	noticeLang(c->ci->bi->nick, u, LANG_SYNC_DONE, c->name);

	free(newav);
	return MOD_CONT;
}
Пример #8
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;
}