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; }
/** * The /cs register command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_register(User * u) { char *chan = strtok(NULL, " "); char *pass = strtok(NULL, " "); char *desc = strtok(NULL, ""); NickCore *nc; Channel *c; ChannelInfo *ci; struct u_chaninfolist *uc; int is_servadmin = is_services_admin(u); char founderpass[PASSMAX + 1]; char tmp_pass[PASSMAX]; if (readonly) { notice_lang(s_ChanServ, u, CHAN_REGISTER_DISABLED); return MOD_CONT; } if (checkDefCon(DEFCON_NO_NEW_CHANNELS)) { notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } if (!desc) { syntax_error(s_ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX); } else if (*chan == '&') { notice_lang(s_ChanServ, u, CHAN_REGISTER_NOT_LOCAL); } else if (*chan != '#') { notice_lang(s_ChanServ, u, CHAN_SYMBOL_REQUIRED); } else if (!xanadu_valid_chan(chan)) { notice_lang(s_ChanServ, u, CHAN_X_INVALID, chan); } else if (!u->na || !(nc = u->na->nc)) { notice_lang(s_ChanServ, u, CHAN_MUST_REGISTER_NICK, s_NickServ); } else if (!nick_recognized(u)) { notice_lang(s_ChanServ, u, CHAN_MUST_IDENTIFY_NICK, s_NickServ, s_NickServ); } else if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_REGISTER_NONE_CHANNEL, chan); } else if ((ci = cs_findchan(chan)) != NULL) { if (ci->flags & CI_VERBOTEN) { alog("%s: Attempt to register FORBIDden channel %s by %s!%s@%s", s_ChanServ, ci->name, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); } else { notice_lang(s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan); } } else if (!stricmp(chan, "#")) { notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); } else if (!chan_has_user_status(c, u, CUS_OP)) { notice_lang(s_ChanServ, u, CHAN_MUST_BE_CHANOP); } else if (!is_servadmin && nc->channelmax > 0 && nc->channelcount >= nc->channelmax) { notice_lang(s_ChanServ, u, nc->channelcount > nc-> channelmax ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, nc->channelmax); } else if (stricmp(u->nick, pass) == 0 || (StrictPasswords && strlen(pass) < 5)) { notice_lang(s_ChanServ, u, MORE_OBSCURE_PASSWORD); } else if (!(ci = makechan(chan))) { alog("%s: makechan() failed for REGISTER %s", s_ChanServ, chan); notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED); } else if (strscpy(founderpass, pass, PASSMAX + 1), enc_encrypt_in_place(founderpass, PASSMAX) < 0) { alog("%s: Couldn't encrypt password for %s (REGISTER)", s_ChanServ, chan); notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED); delchan(ci); } else { c->ci = ci; ci->c = c; ci->bantype = CSDefBantype; ci->flags = CSDefFlags; ci->mlock_on = ircd->defmlock; ci->memos.memomax = MSMaxMemos; ci->last_used = ci->time_registered; ci->founder = nc; if (strlen(pass) > PASSMAX) notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX); memset(pass, 0, strlen(pass)); memcpy(ci->founderpass, founderpass, PASSMAX); ci->desc = sstrdup(desc); if (c->topic) { ci->last_topic = sstrdup(c->topic); strscpy(ci->last_topic_setter, c->topic_setter, NICKMAX); ci->last_topic_time = c->topic_time; } else { /* Set this to something, otherwise it will maliform the topic */ strscpy(ci->last_topic_setter, s_ChanServ, NICKMAX); } ci->bi = NULL; ci->botflags = BSDefFlags; ci->founder->channelcount++; alog("%s: Channel '%s' registered by %s!%s@%s", s_ChanServ, chan, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_REGISTERED, chan, u->nick); if(enc_decrypt(ci->founderpass,tmp_pass,PASSMAX) == 1) { notice_lang(s_ChanServ, u, CHAN_PASSWORD_IS, ci->founderpass); } uc = scalloc(sizeof(*uc), 1); uc->next = u->founder_chans; uc->prev = NULL; if (u->founder_chans) u->founder_chans->prev = uc; u->founder_chans = uc; uc->chan = ci; /* Implement new mode lock */ check_modes(c); /* On most ircds you do not receive the admin/owner mode till its registered */ if (ircd->admin) { xanadu_cmd_mode(s_ChanServ, chan, "%s %s", ircd->adminset, u->nick); } if (ircd->owner && ircd->ownerset) { xanadu_cmd_mode(s_ChanServ, chan, "%s %s", ircd->ownerset, u->nick); } send_event(EVENT_CHAN_REGISTERED, 1, chan); } return MOD_CONT; }
/** * The /ms info command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_info(User * u) { MemoInfo *mi; NickAlias *na = NULL; ChannelInfo *ci = NULL; char *name = strtok(NULL, " "); int is_servadmin = is_services_admin(u); int hardmax = 0; if (is_servadmin && name && *name != '#') { na = findnick(name); if (!na) { notice_lang(s_MemoServ, u, NICK_X_NOT_REGISTERED, name); return MOD_CONT; } else if (na->status & NS_VERBOTEN) { notice_lang(s_MemoServ, u, NICK_X_FORBIDDEN, name); return MOD_CONT; } mi = &na->nc->memos; hardmax = na->nc->flags & NI_MEMO_HARDMAX ? 1 : 0; } else if (name && *name == '#') { ci = cs_findchan(name); if (!ci) { notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, name); return MOD_CONT; } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, name); return MOD_CONT; } else if (!check_access(u, ci, CA_MEMO)) { notice_lang(s_MemoServ, u, ACCESS_DENIED); return MOD_CONT; } mi = &ci->memos; hardmax = ci->flags & CI_MEMO_HARDMAX ? 1 : 0; } else if (name) { /* It's not a chan and we aren't services admin */ notice_lang(s_MemoServ, u, ACCESS_DENIED); return MOD_CONT; } else { /* !name */ if (!nick_identified(u)) { notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); return MOD_CONT; } mi = &u->na->nc->memos; hardmax = u->na->nc->flags & NI_MEMO_HARDMAX ? 1 : 0; } if (name && (ci || na->nc != u->na->nc)) { if (!mi->memocount) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NO_MEMOS, name); } else if (mi->memocount == 1) { if (mi->memos[0].flags & MF_UNREAD) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMO_UNREAD, name); else notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMO, name); } else { int count = 0, i; for (i = 0; i < mi->memocount; i++) { if (mi->memos[i].flags & MF_UNREAD) count++; } if (count == mi->memocount) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS_ALL_UNREAD, name, count); else if (count == 0) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS, name, mi->memocount); else if (count == 1) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS_ONE_UNREAD, name, mi->memocount); else notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS_SOME_UNREAD, name, mi->memocount, count); } if (mi->memomax == 0) { if (hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_X_HARD_LIMIT, name, mi->memomax); else notice_lang(s_MemoServ, u, MEMO_INFO_X_LIMIT, name, mi->memomax); } else if (mi->memomax > 0) { if (hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_X_HARD_LIMIT, name, mi->memomax); else notice_lang(s_MemoServ, u, MEMO_INFO_X_LIMIT, name, mi->memomax); } else { notice_lang(s_MemoServ, u, MEMO_INFO_X_NO_LIMIT, name); } /* I ripped this code out of ircservices 4.4.5, since I didn't want to rewrite the whole thing (it pisses me off). */ if (na) { if ((na->nc->flags & NI_MEMO_RECEIVE) && (na->nc->flags & NI_MEMO_SIGNON)) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_ON, name); } else if (na->nc->flags & NI_MEMO_RECEIVE) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_RECEIVE, name); } else if (na->nc->flags & NI_MEMO_SIGNON) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_SIGNON, name); } else { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_OFF, name); } } } else { /* !name || (!ci || na->nc == u->na->nc) */ if (!mi->memocount) { notice_lang(s_MemoServ, u, MEMO_INFO_NO_MEMOS); } else if (mi->memocount == 1) { if (mi->memos[0].flags & MF_UNREAD) notice_lang(s_MemoServ, u, MEMO_INFO_MEMO_UNREAD); else notice_lang(s_MemoServ, u, MEMO_INFO_MEMO); } else { int count = 0, i; for (i = 0; i < mi->memocount; i++) { if (mi->memos[i].flags & MF_UNREAD) count++; } if (count == mi->memocount) notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS_ALL_UNREAD, count); else if (count == 0) notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS, mi->memocount); else if (count == 1) notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS_ONE_UNREAD, mi->memocount); else notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS_SOME_UNREAD, mi->memocount, count); } if (mi->memomax == 0) { if (!is_servadmin && hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_HARD_LIMIT_ZERO); else notice_lang(s_MemoServ, u, MEMO_INFO_LIMIT_ZERO); } else if (mi->memomax > 0) { if (!is_servadmin && hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_HARD_LIMIT, mi->memomax); else notice_lang(s_MemoServ, u, MEMO_INFO_LIMIT, mi->memomax); } else { notice_lang(s_MemoServ, u, MEMO_INFO_NO_LIMIT); } /* Ripped too. But differently because of a seg fault (loughs) */ if ((u->na->nc->flags & NI_MEMO_RECEIVE) && (u->na->nc->flags & NI_MEMO_SIGNON)) { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_ON); } else if (u->na->nc->flags & NI_MEMO_RECEIVE) { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_RECEIVE); } else if (u->na->nc->flags & NI_MEMO_SIGNON) { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_SIGNON); } else { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_OFF); } } return MOD_CONT; /* if (name && (ci || na->nc != u->na->nc)) */ }
/** * Add the help response to anopes /ns help output. * @param u The user who is requesting help **/ void myNickServHelp(User * u) { notice_lang(s_NickServ, u, NICK_HELP_CMD_LOGOUT); }
/** * The /hs list command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int listOut(User * u) { char *key = strtok(NULL, ""); struct tm *tm; char buf[BUFSIZE]; int counter = 1; int from = 0, to = 0; char *tmp = NULL; char *s = NULL; int display_counter = 0; HostCore *head = NULL; HostCore *current; head = hostCoreListHead(); current = head; if (current == NULL) notice_lang(s_HostServ, u, HOST_EMPTY); else { /** * Do a check for a range here, then in the next loop * we'll only display what has been requested.. **/ if (key) { if (key[0] == '#') { tmp = myStrGetOnlyToken((key + 1), '-', 0); /* Read FROM out */ if (!tmp) { notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } for (s = tmp; *s; s++) { if (!isdigit(*s)) { free(tmp); notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } } from = atoi(tmp); free(tmp); tmp = myStrGetTokenRemainder(key, '-', 1); /* Read TO out */ if (!tmp) { notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } for (s = tmp; *s; s++) { if (!isdigit(*s)) { free(tmp); notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } } to = atoi(tmp); free(tmp); key = NULL; } } while (current != NULL) { if (key) { if (((match_wild_nocase(key, current->nick)) || (match_wild_nocase(key, current->vHost))) && (display_counter < NSListMax)) { display_counter++; tm = localtime(¤t->time); strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); if (current->vIdent) { notice_lang(s_HostServ, u, HOST_IDENT_ENTRY, counter, current->nick, current->vIdent, current->vHost, current->creator, buf); } else { notice_lang(s_HostServ, u, HOST_ENTRY, counter, current->nick, current->vHost, current->creator, buf); } } } else { /** * List the host if its in the display range, and not more * than NSListMax records have been displayed... **/ if ((((counter >= from) && (counter <= to)) || ((from == 0) && (to == 0))) && (display_counter < NSListMax)) { display_counter++; tm = localtime(¤t->time); strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); if (current->vIdent) { notice_lang(s_HostServ, u, HOST_IDENT_ENTRY, counter, current->nick, current->vIdent, current->vHost, current->creator, buf); } else { notice_lang(s_HostServ, u, HOST_ENTRY, counter, current->nick, current->vHost, current->creator, buf); } } } counter++; current = current->next; } if (key) { notice_lang(s_HostServ, u, HOST_LIST_KEY_FOOTER, key, display_counter); } else { if (from != 0) { notice_lang(s_HostServ, u, HOST_LIST_RANGE_FOOTER, from, to); } else { notice_lang(s_HostServ, u, HOST_LIST_FOOTER, display_counter); } } } return MOD_CONT; }
/** * Add the help response to anopes /cs help output. * @param u The user who is requesting help **/ void myChanServHelp(User * u) { if (is_services_admin(u)) { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_GETPASS); } }
/* ENVINFO command */ static int do_envinfo(User * u, int ac, char **av) { int uptime; if (denora->protocoldebug) { protocol_debug(NULL, ac, av); } uptime = time(NULL) - denora->start_time; notice_lang(s_StatServ, u, STAT_ENVINFO_HEADER); /* version, protocol, uplink */ notice_lang(s_StatServ, u, STAT_ENVINFO_VERSION, denora->versiondotted); notice_lang(s_StatServ, u, STAT_ENVINFO_PROTOCOL, denora->version_protocol); notice_lang(s_StatServ, u, STAT_ENVINFO_UPLINK, denora->uplink); /* Yes/No responses */ notice_lang(s_StatServ, u, STAT_ENVINFO_SQL, denora->do_sql ? langstring(SAY_YES) : langstring(SAY_NO)); notice_lang(s_StatServ, u, STAT_ENVINFO_HTML, denora->do_html ? langstring(SAY_YES) : langstring(SAY_NO)); notice_lang(s_StatServ, u, STAT_ENVINFO_DEBUG, denora->debug ? langstring(SAY_YES) : langstring(SAY_NO)); /* How many modules loaded */ notice_lang(s_StatServ, u, STAT_ENVINFO_MODULESLOADED, moduleCount(0)); /* Language in use */ notice_lang(s_StatServ, u, STAT_ENVINFO_LANGUAGE, langstring(LANG_NAME)); /* Stats uptime information */ if (uptime / 86400 == 1) notice_lang(s_StatServ, u, STATS_UPTIME_1DHMS, uptime / 86400, (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); else notice_lang(s_StatServ, u, STATS_UPTIME_DHMS, uptime / 86400, (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); /* End of ENVINFO */ notice_lang(s_StatServ, u, STAT_ENVINFO_FOOTER); return MOD_CONT; }
/** * Add the help response to anopes /os help output. * @param u The user who is requesting help **/ void myOperServHelp(User * u) { if (is_services_oper(u)) { notice_lang(s_OperServ, u, OPER_HELP_CMD_SGLINE); } }
/** * The /os sgline command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_sgline(User * u) { char *cmd = strtok(NULL, " "); if (!cmd) cmd = ""; if (!stricmp(cmd, "ADD")) { int deleted = 0; char *expiry, *mask, *reason; time_t expires; mask = strtok(NULL, ":"); if (mask && *mask == '+') { expiry = mask; mask = strchr(expiry, ' '); if (mask) { *mask = 0; mask++; } } else { expiry = NULL; } expires = expiry ? dotime(expiry) : SGLineExpiry; /* 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(s_OperServ, u, BAD_EXPIRY_TIME); return MOD_CONT; } else if (expires > 0) { expires += time(NULL); } if (mask && (reason = strtok(NULL, ""))) { /* Clean up the last character of the mask if it is a space * See bug #761 */ size_t masklen = strlen(mask); if (mask[masklen - 1] == ' ') mask[masklen - 1] = '\0'; /* We first do some sanity check on the proposed mask. */ if (mask && strspn(mask, "*?") == strlen(mask)) { notice_lang(s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask); return MOD_CONT; } deleted = add_sgline(u, mask, u->nick, expires, reason); if (deleted < 0) return MOD_CONT; else if (deleted) notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, deleted); notice_lang(s_OperServ, u, OPER_SGLINE_ADDED, mask); if (WallOSSGLine) { 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(s_OperServ, "%s added an SGLINE for %s (%s)", u->nick, mask, buf); } if (readonly) notice_lang(s_OperServ, u, READ_ONLY_MODE); } else { syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX); } } else if (!stricmp(cmd, "DEL")) { char *mask; int res = 0; mask = strtok(NULL, ""); if (!mask) { syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX); return MOD_CONT; } if (sglines.count == 0) { notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY); return MOD_CONT; } if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) { /* Deleting a range */ res = slist_delete_range(&sglines, mask, NULL); if (res == 0) { notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH); return MOD_CONT; } else if (res == 1) { notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_ONE); } else { notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, res); } } else { if ((res = slist_indexof(&sglines, mask)) == -1) { notice_lang(s_OperServ, u, OPER_SGLINE_NOT_FOUND, mask); return MOD_CONT; } slist_delete(&sglines, res); notice_lang(s_OperServ, u, OPER_SGLINE_DELETED, mask); } if (readonly) notice_lang(s_OperServ, u, READ_ONLY_MODE); } else if (!stricmp(cmd, "LIST")) { char *mask; int res, sent_header = 0; if (sglines.count == 0) { notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY); return MOD_CONT; } mask = strtok(NULL, ""); if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) { res = slist_enum(&sglines, mask, &sgline_list_callback, u, &sent_header); if (res == 0) { notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH); return MOD_CONT; } } else { int i; char *amask; for (i = 0; i < sglines.count; i++) { amask = ((SXLine *) sglines.list[i])->mask; if (!stricmp(mask, amask) || match_wild_nocase(mask, amask)) sgline_list(i + 1, sglines.list[i], u, &sent_header); } if (!sent_header) notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH); else { notice_lang(s_OperServ, u, END_OF_ANY_LIST, "SGLine"); } } } else if (!stricmp(cmd, "VIEW")) { char *mask; int res, sent_header = 0; if (sglines.count == 0) { notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY); return MOD_CONT; } mask = strtok(NULL, ""); if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) { res = slist_enum(&sglines, mask, &sgline_view_callback, u, &sent_header); if (res == 0) { notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH); return MOD_CONT; } } else { int i; char *amask; for (i = 0; i < sglines.count; i++) { amask = ((SXLine *) sglines.list[i])->mask; if (!stricmp(mask, amask) || match_wild_nocase(mask, amask)) sgline_view(i + 1, sglines.list[i], u, &sent_header); } if (!sent_header) notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH); } } else if (!stricmp(cmd, "CLEAR")) { slist_clear(&sglines, 1); notice_lang(s_OperServ, u, OPER_SGLINE_CLEAR); } else { syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX); } return MOD_CONT; }
/** * Add the help response to anopes /os help output. * @param u The user who is requesting help **/ static void myOperServHelp(User * u) { notice_lang(s_OperServ, u, OPER_HELP_CMD_STAFF); }
/** * Add the help response to anopes /ms help output. * @param u The user who is requesting help **/ void myMemoServHelp(User * u) { notice_lang(s_MemoServ, u, MEMO_HELP_CMD_CANCEL); }
/** * The /bs kick command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_kickcmd(User * u) { char *chan = strtok(NULL, " "); char *option = strtok(NULL, " "); char *value = strtok(NULL, " "); char *ttb = strtok(NULL, " "); ChannelInfo *ci; if (readonly) notice_lang(s_BotServ, u, BOT_KICK_DISABLED); else if (!chan || !option || !value) syntax_error(s_BotServ, u, "KICK", BOT_KICK_SYNTAX); else if (stricmp(value, "ON") && stricmp(value, "OFF")) syntax_error(s_BotServ, u, "KICK", BOT_KICK_SYNTAX); else if (!(ci = cs_findchan(chan))) notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan); else if (ci->flags & CI_VERBOTEN) notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan); else if (!is_services_admin(u) && !check_access(u, ci, CA_SET)) notice_lang(s_BotServ, u, ACCESS_DENIED); else if (!ci->bi) notice_lang(s_BotServ, u, BOT_NOT_ASSIGNED); else { if (!stricmp(option, "BADWORDS")) { if (!stricmp(value, "ON")) { if (ttb) { ci->ttb[TTB_BADWORDS] = strtol(ttb, (char **) NULL, 10); /* Only error if errno returns ERANGE or EINVAL or we are less then 0 - TSL */ if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_BADWORDS] < 0) { /* leaving the debug behind since we might want to know what these are */ if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_BADWORDS]); } /* reset the value back to 0 - TSL */ ci->ttb[TTB_BADWORDS] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else { ci->ttb[TTB_BADWORDS] = 0; } ci->botflags |= BS_KICK_BADWORDS; if (ci->ttb[TTB_BADWORDS]) notice_lang(s_BotServ, u, BOT_KICK_BADWORDS_ON_BAN, ci->ttb[TTB_BADWORDS]); else notice_lang(s_BotServ, u, BOT_KICK_BADWORDS_ON); } else { ci->botflags &= ~BS_KICK_BADWORDS; notice_lang(s_BotServ, u, BOT_KICK_BADWORDS_OFF); } } else if (!stricmp(option, "BOLDS")) { if (!stricmp(value, "ON")) { if (ttb) { ci->ttb[TTB_BOLDS] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_BOLDS] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_BOLDS]); } ci->ttb[TTB_BOLDS] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_BOLDS] = 0; ci->botflags |= BS_KICK_BOLDS; if (ci->ttb[TTB_BOLDS]) notice_lang(s_BotServ, u, BOT_KICK_BOLDS_ON_BAN, ci->ttb[TTB_BOLDS]); else notice_lang(s_BotServ, u, BOT_KICK_BOLDS_ON); } else { ci->botflags &= ~BS_KICK_BOLDS; notice_lang(s_BotServ, u, BOT_KICK_BOLDS_OFF); } } else if (!stricmp(option, "CAPS")) { if (!stricmp(value, "ON")) { char *min = strtok(NULL, " "); char *percent = strtok(NULL, " "); if (ttb) { ci->ttb[TTB_CAPS] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_CAPS] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_CAPS]); } ci->ttb[TTB_CAPS] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_CAPS] = 0; if (!min) ci->capsmin = 10; else ci->capsmin = atol(min); if (ci->capsmin < 1) ci->capsmin = 10; if (!percent) ci->capspercent = 25; else ci->capspercent = atol(percent); if (ci->capspercent < 1 || ci->capspercent > 100) ci->capspercent = 25; ci->botflags |= BS_KICK_CAPS; if (ci->ttb[TTB_CAPS]) notice_lang(s_BotServ, u, BOT_KICK_CAPS_ON_BAN, ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]); else notice_lang(s_BotServ, u, BOT_KICK_CAPS_ON, ci->capsmin, ci->capspercent); } else { ci->botflags &= ~BS_KICK_CAPS; notice_lang(s_BotServ, u, BOT_KICK_CAPS_OFF); } } else if (!stricmp(option, "COLORS")) { if (!stricmp(value, "ON")) { if (ttb) { ci->ttb[TTB_COLORS] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_COLORS] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_COLORS]); } ci->ttb[TTB_COLORS] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_COLORS] = 0; ci->botflags |= BS_KICK_COLORS; if (ci->ttb[TTB_COLORS]) notice_lang(s_BotServ, u, BOT_KICK_COLORS_ON_BAN, ci->ttb[TTB_COLORS]); else notice_lang(s_BotServ, u, BOT_KICK_COLORS_ON); } else { ci->botflags &= ~BS_KICK_COLORS; notice_lang(s_BotServ, u, BOT_KICK_COLORS_OFF); } } else if (!stricmp(option, "FLOOD")) { if (!stricmp(value, "ON")) { char *lines = strtok(NULL, " "); char *secs = strtok(NULL, " "); if (ttb) { ci->ttb[TTB_FLOOD] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_FLOOD] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_FLOOD]); } ci->ttb[TTB_FLOOD] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_FLOOD] = 0; if (!lines) ci->floodlines = 6; else ci->floodlines = atol(lines); if (ci->floodlines < 2) ci->floodlines = 6; if (!secs) ci->floodsecs = 10; else ci->floodsecs = atol(secs); if (ci->floodsecs < 1 || ci->floodsecs > BSKeepData) ci->floodsecs = 10; ci->botflags |= BS_KICK_FLOOD; if (ci->ttb[TTB_FLOOD]) notice_lang(s_BotServ, u, BOT_KICK_FLOOD_ON_BAN, ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]); else notice_lang(s_BotServ, u, BOT_KICK_FLOOD_ON, ci->floodlines, ci->floodsecs); } else { ci->botflags &= ~BS_KICK_FLOOD; notice_lang(s_BotServ, u, BOT_KICK_FLOOD_OFF); } } else if (!stricmp(option, "REPEAT")) { if (!stricmp(value, "ON")) { char *times = strtok(NULL, " "); if (ttb) { ci->ttb[TTB_REPEAT] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_REPEAT] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_REPEAT]); } ci->ttb[TTB_REPEAT] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_REPEAT] = 0; if (!times) ci->repeattimes = 3; else ci->repeattimes = atol(times); if (ci->repeattimes < 2) ci->repeattimes = 3; ci->botflags |= BS_KICK_REPEAT; if (ci->ttb[TTB_REPEAT]) notice_lang(s_BotServ, u, BOT_KICK_REPEAT_ON_BAN, ci->repeattimes, ci->ttb[TTB_REPEAT]); else notice_lang(s_BotServ, u, BOT_KICK_REPEAT_ON, ci->repeattimes); } else { ci->botflags &= ~BS_KICK_REPEAT; notice_lang(s_BotServ, u, BOT_KICK_REPEAT_OFF); } } else if (!stricmp(option, "REVERSES")) { if (!stricmp(value, "ON")) { if (ttb) { ci->ttb[TTB_REVERSES] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_REVERSES] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_REVERSES]); } ci->ttb[TTB_REVERSES] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_REVERSES] = 0; ci->botflags |= BS_KICK_REVERSES; if (ci->ttb[TTB_REVERSES]) notice_lang(s_BotServ, u, BOT_KICK_REVERSES_ON_BAN, ci->ttb[TTB_REVERSES]); else notice_lang(s_BotServ, u, BOT_KICK_REVERSES_ON); } else { ci->botflags &= ~BS_KICK_REVERSES; notice_lang(s_BotServ, u, BOT_KICK_REVERSES_OFF); } } else if (!stricmp(option, "UNDERLINES")) { if (!stricmp(value, "ON")) { if (ttb) { ci->ttb[TTB_UNDERLINES] = strtol(ttb, (char **) NULL, 10); if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_UNDERLINES] < 0) { if (debug) { alog("debug: errno is %d ERANGE %d EINVAL %d ttb %d", errno, ERANGE, EINVAL, ci->ttb[TTB_UNDERLINES]); } ci->ttb[TTB_UNDERLINES] = 0; notice_lang(s_BotServ, u, BOT_KICK_BAD_TTB, ttb); return MOD_CONT; } } else ci->ttb[TTB_UNDERLINES] = 0; ci->botflags |= BS_KICK_UNDERLINES; if (ci->ttb[TTB_UNDERLINES]) notice_lang(s_BotServ, u, BOT_KICK_UNDERLINES_ON_BAN, ci->ttb[TTB_UNDERLINES]); else notice_lang(s_BotServ, u, BOT_KICK_UNDERLINES_ON); } else { ci->botflags &= ~BS_KICK_UNDERLINES; notice_lang(s_BotServ, u, BOT_KICK_UNDERLINES_OFF); } } else notice_help(s_BotServ, u, BOT_KICK_UNKNOWN, option); } return MOD_CONT; }
/** * Add the help response to Anopes /bs help output. * @param u The user who is requesting help **/ void myBotServHelp(User * u) { notice_lang(s_BotServ, u, BOT_HELP_CMD_KICK); }
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; }
/** * Add the help response to anopes /cs help output. * @param u The user who is requesting help **/ static void myChanServHelp(User * u) { if (is_services_admin(u)) { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_FORBID); } }
/** * Add the help response to anopes /os help output. * @param u The user who is requesting help **/ static void myOperServHelp(User * u) { if (is_services_root(u)) { notice_lang(s_OperServ, u, OPER_HELP_CMD_SET); } }
/** * The /cs forbid command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_forbid(User * u) { Channel *c; ChannelInfo *ci; char *chan = strtok(NULL, " "); char *reason = strtok(NULL, ""); Entry *cur, *enext; /* Assumes that permission checking has already been done. */ if (!chan || (ForceForbidReason && !reason)) { syntax_error(s_ChanServ, u, "FORBID", (ForceForbidReason ? CHAN_FORBID_SYNTAX_REASON : CHAN_FORBID_SYNTAX)); return MOD_CONT; } if (*chan != '#') { notice_lang(s_ChanServ, u, CHAN_SYMBOL_REQUIRED); return MOD_CONT; } else if (!anope_valid_chan(chan)) { notice_lang(s_ChanServ, u, CHAN_X_INVALID, chan); return MOD_CONT; } if (readonly) notice_lang(s_ChanServ, u, READ_ONLY_MODE); if ((ci = cs_findchan(chan)) != NULL) { delchan(ci); send_event(EVENT_CHAN_DROP, 1, chan); } ci = makechan(chan); if (ci) { ci->flags |= CI_VERBOTEN; ci->forbidby = sstrdup(u->nick); if (reason) ci->forbidreason = sstrdup(reason); if ((c = findchan(ci->name))) { struct c_userlist *cu, *next; char *av[3]; /* Before banning everyone, it might be prudent to clear +e and +I lists.. * to prevent ppl from rejoining.. ~ Viper */ if (ircd->except && c->excepts && c->excepts->count) { av[0] = sstrdup("-e"); for (cur = c->excepts->entries; cur; cur = enext) { enext = cur->next; av[1] = sstrdup(cur->mask); anope_cmd_mode(whosends(ci), chan, "-e %s", cur->mask); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); } free(av[0]); } if (ircd->invitemode && c->invites && c->invites->count) { av[0] = sstrdup("-I"); for (cur = c->invites->entries; cur; cur = enext) { enext = cur->next; av[1] = sstrdup(cur->mask); anope_cmd_mode(whosends(ci), chan, "-I %s", cur->mask); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); } free(av[0]); } for (cu = c->users; cu; cu = next) { next = cu->next; if (is_oper(cu->user)) continue; av[0] = c->name; av[1] = cu->user->nick; av[2] = reason ? reason : "CHAN_FORBID_REASON"; anope_cmd_kick(s_ChanServ, av[0], av[1], av[2]); do_kick(s_ChanServ, 3, av); } } if (WallForbid) anope_cmd_global(s_ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick, ci->name); if (ircd->chansqline) { anope_cmd_sqline(ci->name, ((reason) ? reason : "Forbidden")); } alog("%s: %s set FORBID for channel %s", s_ChanServ, u->nick, ci->name); notice_lang(s_ChanServ, u, CHAN_FORBID_SUCCEEDED, chan); send_event(EVENT_CHAN_FORBIDDEN, 1, chan); } else { alog("%s: Valid FORBID for %s by %s failed", s_ChanServ, ci->name, u->nick); notice_lang(s_ChanServ, u, CHAN_FORBID_FAILED, chan); } return MOD_CONT; }
/** * The /os set command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_set(User * u) { char *option = strtok(NULL, " "); char *setting = strtok(NULL, " "); int index; Channel *c; if (!option) { syntax_error(s_OperServ, u, "SET", OPER_SET_SYNTAX); } else if (stricmp(option, "LIST") == 0) { index = (allow_ignore ? OPER_SET_LIST_OPTION_ON : OPER_SET_LIST_OPTION_OFF); notice_lang(s_OperServ, u, index, "IGNORE"); index = (readonly ? OPER_SET_LIST_OPTION_ON : OPER_SET_LIST_OPTION_OFF); notice_lang(s_OperServ, u, index, "READONLY"); index = (logchan ? OPER_SET_LIST_OPTION_ON : OPER_SET_LIST_OPTION_OFF); notice_lang(s_OperServ, u, index, "LOGCHAN"); index = (debug ? OPER_SET_LIST_OPTION_ON : OPER_SET_LIST_OPTION_OFF); notice_lang(s_OperServ, u, index, "DEBUG"); index = (noexpire ? OPER_SET_LIST_OPTION_ON : OPER_SET_LIST_OPTION_OFF); notice_lang(s_OperServ, u, index, "NOEXPIRE"); #ifdef USE_MYSQL index = (do_mysql ? OPER_SET_LIST_OPTION_ON : OPER_SET_LIST_OPTION_OFF); notice_lang(s_OperServ, u, index, "SQL"); #endif } else if (!setting) { syntax_error(s_OperServ, u, "SET", OPER_SET_SYNTAX); } else if (stricmp(option, "IGNORE") == 0) { if (stricmp(setting, "on") == 0) { allow_ignore = 1; notice_lang(s_OperServ, u, OPER_SET_IGNORE_ON); } else if (stricmp(setting, "off") == 0) { allow_ignore = 0; notice_lang(s_OperServ, u, OPER_SET_IGNORE_OFF); } else { notice_lang(s_OperServ, u, OPER_SET_IGNORE_ERROR); } #ifdef USE_MYSQL } else if (stricmp(option, "SQL") == 0) { if (stricmp(setting, "on") == 0) { if (!MysqlHost) { notice_lang(s_OperServ, u, OPER_SET_SQL_ERROR_DISABLED); } else { if (rdb_init()) { notice_lang(s_OperServ, u, OPER_SET_SQL_ON); } else { notice_lang(s_OperServ, u, OPER_SET_SQL_ERROR_INIT); } } } else if (stricmp(setting, "off") == 0) { if (!MysqlHost) { notice_lang(s_OperServ, u, OPER_SET_SQL_ERROR_DISABLED); } else { /* could call rdb_close() but that does nothing - TSL */ do_mysql = 0; notice_lang(s_OperServ, u, OPER_SET_SQL_OFF); } } else { notice_lang(s_OperServ, u, OPER_SET_SQL_ERROR); } #endif } else if (stricmp(option, "READONLY") == 0) { if (stricmp(setting, "on") == 0) { readonly = 1; alog("Read-only mode activated"); close_log(); notice_lang(s_OperServ, u, OPER_SET_READONLY_ON); } else if (stricmp(setting, "off") == 0) { readonly = 0; open_log(); alog("Read-only mode deactivated"); notice_lang(s_OperServ, u, OPER_SET_READONLY_OFF); } else { notice_lang(s_OperServ, u, OPER_SET_READONLY_ERROR); } } else if (stricmp(option, "LOGCHAN") == 0) { /* Unlike the other SET commands where only stricmp is necessary, * we also have to ensure that LogChannel is defined or we can't * send to it. * * -jester */ if (LogChannel && (stricmp(setting, "on") == 0)) { if (ircd->join2msg) { c = findchan(LogChannel); anope_cmd_join(s_GlobalNoticer, LogChannel, c ? c->creation_time : time(NULL)); } logchan = 1; alog("Now sending log messages to %s", LogChannel); notice_lang(s_OperServ, u, OPER_SET_LOGCHAN_ON, LogChannel); } else if (LogChannel && (stricmp(setting, "off") == 0)) { alog("No longer sending log messages to a channel"); if (ircd->join2msg) { anope_cmd_part(s_GlobalNoticer, LogChannel, NULL); } logchan = 0; notice_lang(s_OperServ, u, OPER_SET_LOGCHAN_OFF); } else { notice_lang(s_OperServ, u, OPER_SET_LOGCHAN_ERROR); } /** * Allow the user to turn super admin on/off * * Rob **/ } else if (stricmp(option, "SUPERADMIN") == 0) { if (!SuperAdmin) { notice_lang(s_OperServ, u, OPER_SUPER_ADMIN_NOT_ENABLED); } else if (stricmp(setting, "on") == 0) { u->isSuperAdmin = 1; notice_lang(s_OperServ, u, OPER_SUPER_ADMIN_ON); alog("%s: %s is a SuperAdmin ", s_OperServ, u->nick); anope_cmd_global(s_OperServ, getstring2(NULL, OPER_SUPER_ADMIN_WALL_ON), u->nick); } else if (stricmp(setting, "off") == 0) { u->isSuperAdmin = 0; notice_lang(s_OperServ, u, OPER_SUPER_ADMIN_OFF); alog("%s: %s is no longer a SuperAdmin", s_OperServ, u->nick); anope_cmd_global(s_OperServ, getstring2(NULL, OPER_SUPER_ADMIN_WALL_OFF), u->nick); } else { notice_lang(s_OperServ, u, OPER_SUPER_ADMIN_SYNTAX); } } else if (stricmp(option, "DEBUG") == 0) { if (stricmp(setting, "on") == 0) { debug = 1; alog("Debug mode activated"); notice_lang(s_OperServ, u, OPER_SET_DEBUG_ON); } else if (stricmp(setting, "off") == 0 || (*setting == '0' && atoi(setting) == 0)) { alog("Debug mode deactivated"); debug = 0; notice_lang(s_OperServ, u, OPER_SET_DEBUG_OFF); } else if (isdigit(*setting) && atoi(setting) > 0) { debug = atoi(setting); alog("Debug mode activated (level %d)", debug); notice_lang(s_OperServ, u, OPER_SET_DEBUG_LEVEL, debug); } else { notice_lang(s_OperServ, u, OPER_SET_DEBUG_ERROR); } } else if (stricmp(option, "NOEXPIRE") == 0) { if (stricmp(setting, "ON") == 0) { noexpire = 1; alog("No expire mode activated"); notice_lang(s_OperServ, u, OPER_SET_NOEXPIRE_ON); } else if (stricmp(setting, "OFF") == 0) { noexpire = 0; alog("No expire mode deactivated"); notice_lang(s_OperServ, u, OPER_SET_NOEXPIRE_OFF); } else { notice_lang(s_OperServ, u, OPER_SET_NOEXPIRE_ERROR); } } else { notice_lang(s_OperServ, u, OPER_SET_UNKNOWN_OPTION, option); } return MOD_CONT; }
/** * Split from do_send, this way we can easily send a memo from any point. * * @param u User Struct * @param name Target of the memo * @param text Memo Text * @param z type see info * @param source Nickname of the alias the memo originates from. * 0 - reply to user * 1 - silent * 2 - silent with no delay timer * 3 - reply to user and request read receipt * @return void */ void memo_send_from(User * u, char *name, char *text, int z, char *source) { int ischan; int isforbid; Memo *m; MemoInfo *mi; time_t now = time(NULL); int is_servoper = is_services_oper(u); if (readonly) { notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED); } else if (checkDefCon(DEFCON_NO_NEW_MEMOS)) { notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED); return; } else if (!text) { if (z == 0) syntax_error(s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX); if (z == 3) syntax_error(s_MemoServ, u, "RSEND", MEMO_RSEND_SYNTAX); } else if (!nick_recognized(u)) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (!(mi = getmemoinfo(name, &ischan, &isforbid))) { if (z == 0 || z == 3) { if (isforbid) { notice_lang(s_MemoServ, u, ischan ? CHAN_X_FORBIDDEN : NICK_X_FORBIDDEN, name); } else { notice_lang(s_MemoServ, u, ischan ? CHAN_X_NOT_REGISTERED : NICK_X_NOT_REGISTERED, name); } } } else if (z != 2 && MSSendDelay > 0 && u && u->lastmemosend + MSSendDelay > now && !is_servoper) { u->lastmemosend = now; if (z == 0) notice_lang(s_MemoServ, u, MEMO_SEND_PLEASE_WAIT, MSSendDelay); if (z == 3) notice_lang(s_MemoServ, u, MEMO_RSEND_PLEASE_WAIT, MSSendDelay); } else if (mi->memomax == 0 && !is_servoper) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_X_GETS_NO_MEMOS, name); } else if (mi->memocount >= 32767 || (mi->memomax > 0 && mi->memocount >= mi->memomax && !is_servoper)) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_X_HAS_TOO_MANY_MEMOS, name); } else { u->lastmemosend = now; mi->memocount++; mi->memos = srealloc(mi->memos, sizeof(Memo) * mi->memocount); m = &mi->memos[mi->memocount - 1]; strscpy(m->sender, source, NICKMAX); m->moduleData = NULL; if (mi->memocount > 1) { m->number = m[-1].number + 1; if (m->number < 1) { int i; for (i = 0; i < mi->memocount; i++) { mi->memos[i].number = i + 1; } } } else { m->number = 1; } m->time = time(NULL); m->text = sstrdup(text); m->flags = MF_UNREAD; #ifdef USE_MYSQL m->id = 0; #endif /* Set notify sent flag - DrStein */ if (z == 2) { m->flags |= MF_NOTIFYS; } /* Set receipt request flag */ if (z == 3) m->flags |= MF_RECEIPT; if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_SENT, name); if (!ischan) { NickAlias *na; NickCore *nc = (findnick(name))->nc; if (MSNotifyAll) { if ((nc->flags & NI_MEMO_RECEIVE) && get_ignore(name) == NULL) { int i; for (i = 0; i < nc->aliases.count; i++) { na = nc->aliases.list[i]; if (na->u && nick_identified(na->u)) notice_lang(s_MemoServ, na->u, MEMO_NEW_MEMO_ARRIVED, source, s_MemoServ, m->number); } } else { if ((u = finduser(name)) && nick_identified(u) && (nc->flags & NI_MEMO_RECEIVE)) notice_lang(s_MemoServ, u, MEMO_NEW_MEMO_ARRIVED, source, s_MemoServ, m->number); } /* if (flags & MEMO_RECEIVE) */ } /* if (MSNotifyAll) */ /* let's get out the mail if set in the nickcore - certus */ if (nc->flags & NI_MEMO_MAIL) new_memo_mail(nc, m); } else { struct c_userlist *cu, *next; Channel *c; if (MSNotifyAll && (c = findchan(name))) { for (cu = c->users; cu; cu = next) { next = cu->next; if (check_access(cu->user, c->ci, CA_MEMO)) { if (cu->user->na && (cu->user->na->nc->flags & NI_MEMO_RECEIVE) && get_ignore(cu->user->nick) == NULL) { notice_lang(s_MemoServ, cu->user, MEMO_NEW_X_MEMO_ARRIVED, c->ci->name, s_MemoServ, c->ci->name, m->number); } } } } /* MSNotifyAll */ } /* if (!ischan) */ } /* if command is valid */ }
int add_szline(User * u, char *mask, const char *by, const time_t expires, const char *reason) { int deleted = 0, i; SXLine *entry; if (!mask) { return -1; } /* Checks whether there is an SZLINE that already covers * the one we want to add, and whether there are SZLINEs * that would be covered by this one. * If so, warn the user in the first case and cleanup * the useless SZLINEs in the second. */ if (szlines.count > 0) { for (i = szlines.count - 1; i >= 0; i--) { entry = szlines.list[i]; if (!entry) continue; if (!stricmp(entry->mask, mask)) { if (entry->expires >= expires || entry->expires == 0) { if (u) notice_lang(s_OperServ, u, OPER_SZLINE_EXISTS, mask); return -1; } else { entry->expires = expires; if (u) notice_lang(s_OperServ, u, OPER_SZLINE_EXISTS, mask); return -2; } } if (match_wild_nocase(entry->mask, mask)) { if (u) notice_lang(s_OperServ, u, OPER_SZLINE_ALREADY_COVERED, mask, entry->mask); return -1; } if (match_wild_nocase(mask, entry->mask)) { slist_delete(&szlines, i); deleted++; } } } /* We can now check whether the list is full or not. */ if (slist_full(&szlines)) { if (u) notice_lang(s_OperServ, u, OPER_SZLINE_REACHED_LIMIT, szlines.limit); return -1; } /* We can now (really) add the SZLINE. */ entry = scalloc(sizeof(SXLine), 1); if (!entry) return -1; entry->mask = sstrdup(mask); entry->by = sstrdup(by); entry->reason = sstrdup(reason); entry->seton = time(NULL); entry->expires = expires; slist_add(&szlines, entry); anope_cmd_szline(entry->mask, entry->reason, entry->by); return deleted; }
/** * Add the help response to anopes /os help output. * @param u The user who is requesting help **/ void myOperServHelp(User * u) { if (is_services_admin(u)) { notice_lang(s_OperServ, u, OPER_HELP_CMD_LOGONNEWS); } }
int add_akill(User * u, char *mask, const char *by, const time_t expires, const char *reason) { int deleted = 0, i; char *user, *mask2, *host; Akill *entry; if (!mask) { return -1; } /* Checks whether there is an AKILL that already covers * the one we want to add, and whether there are AKILLs * that would be covered by this one. The masks AND the * expiry times are used to determine this, because some * AKILLs may become useful when another one expires. * If so, warn the user in the first case and cleanup * the useless AKILLs in the second. */ if (akills.count > 0) { for (i = akills.count - 1; i >= 0; i--) { char amask[BUFSIZE]; entry = akills.list[i]; if (!entry) continue; snprintf(amask, sizeof(amask), "%s@%s", entry->user, entry->host); if (!stricmp(amask, mask)) { /* We change the AKILL expiry time if its current one is less than the new. * This is preferable to be sure we don't change an important AKILL * accidentely. */ if (entry->expires >= expires || entry->expires == 0) { if (u) notice_lang(s_OperServ, u, OPER_AKILL_EXISTS, mask); return -1; } else { entry->expires = expires; if (u) notice_lang(s_OperServ, u, OPER_AKILL_CHANGED, amask); return -2; } } if (match_wild_nocase(amask, mask) && (entry->expires >= expires || entry->expires == 0)) { if (u) notice_lang(s_OperServ, u, OPER_AKILL_ALREADY_COVERED, mask, amask); return -1; } if (match_wild_nocase(mask, amask) && (entry->expires <= expires || expires == 0)) { slist_delete(&akills, i); deleted++; } } } /* We can now check whether the list is full or not. */ if (slist_full(&akills)) { if (u) notice_lang(s_OperServ, u, OPER_AKILL_REACHED_LIMIT, akills.limit); return -1; } /* We can now (really) add the AKILL. */ mask2 = sstrdup(mask); host = strchr(mask2, '@'); if (!host) { free(mask2); return -1; } user = mask2; *host = 0; host++; if (!*host) { if (u) notice_lang(s_OperServ, u, BAD_USERHOST_MASK); free(mask2); return -1; } entry = scalloc(sizeof(Akill), 1); if (!entry) { free(mask2); return -1; } entry->user = sstrdup(user); entry->host = sstrdup(host); entry->by = sstrdup(by); entry->reason = sstrdup(reason); entry->seton = time(NULL); entry->expires = expires; slist_add(&akills, entry); if (AkillOnAdd) anope_cmd_akill(entry->user, entry->host, entry->by, entry->seton, entry->expires, entry->reason); free(mask2); return deleted; }
/** * Add the help response to anopes /hs help output. * @param u The user who is requesting help **/ static void myHostServHelp(User * u) { if (is_services_oper(u)) { notice_lang(s_HostServ, u, HOST_HELP_CMD_LIST); } }
int add_sgline(User * u, char *mask, const char *by, const time_t expires, const char *reason) { int deleted = 0, i; SXLine *entry; User *u2, *next; char buf[BUFSIZE]; *buf = '\0'; /* Checks whether there is an SGLINE that already covers * the one we want to add, and whether there are SGLINEs * that would be covered by this one. * If so, warn the user in the first case and cleanup * the useless SGLINEs in the second. */ if (!mask) { return -1; } if (sglines.count > 0) { for (i = sglines.count - 1; i >= 0; i--) { entry = sglines.list[i]; if (!entry) continue; if (!stricmp(entry->mask, mask)) { if (entry->expires >= expires || entry->expires == 0) { if (u) notice_lang(s_OperServ, u, OPER_SGLINE_EXISTS, mask); return -1; } else { entry->expires = expires; if (u) notice_lang(s_OperServ, u, OPER_SGLINE_CHANGED, entry->mask); return -2; } } if (match_wild_nocase(entry->mask, mask) && (entry->expires >= expires || entry->expires == 0)) { if (u) notice_lang(s_OperServ, u, OPER_SGLINE_ALREADY_COVERED, mask, entry->mask); return -1; } if (match_wild_nocase(mask, entry->mask) && (entry->expires <= expires || expires == 0)) { slist_delete(&sglines, i); deleted++; } } } /* We can now check whether the list is full or not. */ if (slist_full(&sglines)) { if (u) notice_lang(s_OperServ, u, OPER_SGLINE_REACHED_LIMIT, sglines.limit); return -1; } /* We can now (really) add the SGLINE. */ entry = scalloc(sizeof(SXLine), 1); if (!entry) return -1; entry->mask = sstrdup(mask); entry->by = sstrdup(by); entry->reason = sstrdup(reason); entry->seton = time(NULL); entry->expires = expires; slist_add(&sglines, entry); anope_cmd_sgline(entry->mask, entry->reason); if (KillonSGline && !ircd->sglineenforce) { snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason); u2 = firstuser(); while (u2) { next = nextuser(); if (!is_oper(u2)) { if (match_wild_nocase(entry->mask, u2->realname)) { kill_user(ServerName, u2->nick, buf); } } u2 = next; } } return deleted; }
/** * Add the help response to anopes /cs help output. * @param u The user who is requesting help **/ void myChanServHelp(User * u) { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_REGISTER); }
int do_session(User * u) { Session *session; Exception *exception; char *cmd = strtok(NULL, " "); char *param1 = strtok(NULL, " "); int mincount; int i; if (!LimitSessions) { notice_lang(s_OperServ, u, OPER_SESSION_DISABLED); return MOD_CONT; } if (!cmd) cmd = ""; if (stricmp(cmd, "LIST") == 0) { if (!param1) { syntax_error(s_OperServ, u, "SESSION", OPER_SESSION_LIST_SYNTAX); } else if ((mincount = atoi(param1)) <= 1) { notice_lang(s_OperServ, u, OPER_SESSION_INVALID_THRESHOLD); } else { notice_lang(s_OperServ, u, OPER_SESSION_LIST_HEADER, mincount); notice_lang(s_OperServ, u, OPER_SESSION_LIST_COLHEAD); for (i = 0; i < 1024; i++) { for (session = sessionlist[i]; session; session = session->next) { if (session->count >= mincount) notice_lang(s_OperServ, u, OPER_SESSION_LIST_FORMAT, session->count, session->host); } } } } else if (stricmp(cmd, "VIEW") == 0) { if (!param1) { syntax_error(s_OperServ, u, "SESSION", OPER_SESSION_VIEW_SYNTAX); } else { session = findsession(param1); if (!session) { notice_lang(s_OperServ, u, OPER_SESSION_NOT_FOUND, param1); } else { exception = find_host_exception(param1); notice_lang(s_OperServ, u, OPER_SESSION_VIEW_FORMAT, param1, session->count, exception ? exception-> limit : DefSessionLimit); } } } else { syntax_error(s_OperServ, u, "SESSION", OPER_SESSION_SYNTAX); } return MOD_CONT; }
/** * Add the help response to anopes /ms help output. * @param u The user who is requesting help **/ static void myMemoServHelp(User * u) { notice_lang(s_MemoServ, u, MEMO_HELP_CMD_INFO); }
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; }
static int my_cs_appendtopic(User * u) { char *cur_buffer; char *chan; char *newtopic; char topic[1024]; Channel *c; ChannelInfo *ci; cur_buffer = moduleGetLastBuffer(); chan = myStrGetToken(cur_buffer, ' ', 0); newtopic = myStrGetTokenRemainder(cur_buffer, ' ', 1); if (!chan || !newtopic) { moduleNoticeLang(s_ChanServ, u, LNG_APPENDTOPIC_SYNTAX); } else if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); } else if (!(ci = c->ci)) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name); } else if (!is_services_admin(u) && !check_access(u, ci, CA_TOPIC)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else { if (ci->last_topic) { snprintf(topic, sizeof(topic), "%s %s", ci->last_topic, newtopic); free(ci->last_topic); } else { strscpy(topic, newtopic, sizeof(topic)); } 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)) alog("%s: %s!%s@%s changed topic of %s as services admin.", s_ChanServ, u->nick, u->username, u->host, c->name); if (ircd->join2set) { if (whosends(ci) == s_ChanServ) { anope_cmd_join(s_ChanServ, c->name, c->creation_time); anope_cmd_mode(NULL, c->name, "+o %s", GET_BOT(s_ChanServ)); } } anope_cmd_topic(whosends(ci), c->name, u->nick, topic, c->topic_time); if (ircd->join2set) { if (whosends(ci) == s_ChanServ) { anope_cmd_part(s_ChanServ, c->name, NULL); } } } Anope_Free(chan); Anope_Free(newtopic); return MOD_CONT; }
/** * The /cs clear command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_clear(User * u) { char *chan = strtok(NULL, " "); char *what = strtok(NULL, " "); char tmp[BUFSIZE]; Channel *c; ChannelInfo *ci; if (!what) { syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } else if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); } else if (!(ci = c->ci)) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan); } else if (!u || !check_access(u, ci, CA_CLEAR)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else if (stricmp(what, "bans") == 0) { char *av[2]; int i; /* Save original ban info */ int count = c->bancount; char **bans = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) bans[i] = sstrdup(c->bans[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; xanadu_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan); free(bans); } else if (ircd->except && stricmp(what, "excepts") == 0) { char *av[2]; int i; /* Save original except info */ int count = c->exceptcount; char **excepts = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) excepts[i] = sstrdup(c->excepts[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; xanadu_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan); free(excepts); } else if (ircd->invitemode && stricmp(what, "invites") == 0) { char *av[2]; int i; /* Save original except info */ int count = c->invitecount; char **invites = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) invites[i] = sstrdup(c->invite[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; xanadu_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan); free(invites); } else if (stricmp(what, "modes") == 0) { char buf[BUFSIZE], *end = buf; char *argv[2]; if (c->mode) { /* Clear modes the bulk of the modes */ xanadu_cmd_mode(whosends(ci), c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(whosends(ci), c, 1, argv, 0); free(argv[0]); /* to prevent the internals from complaining send -k, -L, -f by themselves if we need to send them - TSL */ if (c->key) { xanadu_cmd_mode(whosends(ci), c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { xanadu_cmd_mode(whosends(ci), c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { xanadu_cmd_mode(whosends(ci), c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } else { if (debug) { alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes"); } } } check_modes(c); } /* TODO: decide if the above implementation is better than this one. */ if (0) { CBModeInfo *cbmi = cbmodeinfos; CBMode *cbm; do { if (c->mode & cbmi->flag) *end++ = cbmi->mode; } while ((++cbmi)->flag != 0); cbmi = cbmodeinfos; do { if (cbmi->getvalue && (c->mode & cbmi->flag) && !(cbmi->flags & CBM_MINUS_NO_ARG)) { char *value = cbmi->getvalue(c); if (value) { *end++ = ' '; while (*value) *end++ = *value++; /* Free the value */ cbm = &cbmodes[(int) cbmi->mode]; cbm->setvalue(c, NULL); } } } while ((++cbmi)->flag != 0); *end = 0; xanadu_cmd_mode(whosends(ci), c->name, "-%s", buf); c->mode = 0; check_modes(c); } notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan); } else if (stricmp(what, "ops") == 0) { char *av[3]; struct c_userlist *cu, *next; if (ircd->svsmode_ucmode) { av[0] = sstrdup(chan); xanadu_cmd_svsmode_chan(av[0], "-o", NULL); if (ircd->owner) { xanadu_cmd_svsmode_chan(av[0], ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { xanadu_cmd_svsmode_chan(av[0], ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); av[1] = sstrdup(tmp); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); av[1] = sstrdup(tmp); } } else { av[1] = sstrdup("-o"); } av[2] = sstrdup(cu->user->nick); do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); av[1] = sstrdup(tmp); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); av[1] = sstrdup(tmp); } } else { av[1] = sstrdup("-o"); } av[2] = sstrdup(cu->user->nick); xanadu_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } } notice_lang(s_ChanServ, u, CHAN_CLEARED_OPS, chan); } else if (ircd->halfop && stricmp(what, "hops") == 0) { char *av[3]; struct c_userlist *cu, *next; for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; av[0] = sstrdup(chan); av[1] = sstrdup("-h"); av[2] = sstrdup(cu->user->nick); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(av[0], av[1], NULL); do_cmode(s_ChanServ, 3, av); break; } else { xanadu_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); } do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_HOPS, chan); } else if (stricmp(what, "voices") == 0) { char *av[3]; struct c_userlist *cu, *next; for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; av[0] = sstrdup(chan); av[1] = sstrdup("-v"); av[2] = sstrdup(cu->user->nick); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(av[0], av[1], NULL); do_cmode(s_ChanServ, 3, av); break; } else { xanadu_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); } do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_VOICES, chan); } else if (stricmp(what, "users") == 0) { char *av[3]; struct c_userlist *cu, *next; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); av[1] = sstrdup(cu->user->nick); av[2] = sstrdup(buf); xanadu_cmd_kick(whosends(ci), av[0], av[1], av[2]); do_kick(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_USERS, chan); } else { syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } return MOD_CONT; }