#define CMD_SVSPART "SVSPART"
#define CMD_SVSQUIT "SVSQUIT"
#define CMD_SWHOIS "SWHOIS"
+#define CMD_TEMPSHUN "TEMPSHUN"
#define CMD_TIME "TIME"
#define CMD_TOPIC "TOPIC"
#define CMD_TRACE "TRACE"
#define TOK_SVSPART "SP"
#define TOK_SVSQUIT "SX"
#define TOK_SWHOIS "SW"
+#define TOK_TEMPSHUN "TS"
#define TOK_TIME "TI"
#define TOK_TOPIC "T"
#define TOK_TRACE "TR"
#define P10_SVSPART TYPE(SVSPART)
#define P10_SVSQUIT TYPE(SVSQUIT)
#define P10_SWHOIS TYPE(SWHOIS)
+#define P10_TEMPSHUN TYPE(TEMPSHUN)
#define P10_TIME TYPE(TIME)
#define P10_TOPIC TYPE(TOPIC)
#define P10_TRACE TYPE(TRACE)
}
+void
+irc_tempshun(struct userNode *from, struct userNode *target, int remove, const char *reason)
+{
+ putsock("%s " P10_TEMPSHUN " %s %s :%s", from->numeric, (remove ? "-" : "+"), target->numeric, reason);
+}
+
void
irc_part(struct userNode *who, struct chanNode *what, const char *reason)
{
if (!serv)
return 0;
- call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[5] : NULL));
+ call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[argc-1] : NULL));
return 1;
}
P(SHUN), P(LOCAL_SHUN), P(WIDE_SHUN), P(ZLINE),
P(LOCAL_ZLINE), P(WIDE_ZLINE), P(LIST_CHAN), P(WHOIS_NOTICE),
P(HIDE_IDLE), P(XTRAOP), P(HIDE_CHANNELS), P(DISPLAY_MODE),
- P(FREEFORM), P(REMOVE), P(SPAMFILTER),
+ P(FREEFORM), P(REMOVE), P(SPAMFILTER), P(ADMIN),
+ P(APASS_OPMODE), P(HIDE_OPER), P(REMOTE), P(SERVICE),
#undef P
{ 0, 0 }
};
if (argc < 2)
return 0;
- user = GetUserN(argv[1]);
+ if (strncmp(argv[1], "*", 2) == 0)
+ {
+ if (!(user = GetUserH(origin))) {
+ log_module(MAIN_LOG, LOG_ERROR, "Could not find SILENCE origin user %s", origin);
+ return 0;
+ }
+ }
+ else
+ user = GetUserN(argv[1]);
/* Sanity, go nuts if this happens */
if (!user)
dict_insert(irc_func_dict, TOK_SVSPART, cmd_svspart);
dict_insert(irc_func_dict, CMD_SWHOIS, cmd_dummy);
dict_insert(irc_func_dict, TOK_SWHOIS, cmd_dummy);
+ dict_insert(irc_func_dict, CMD_TEMPSHUN, cmd_dummy);
+ dict_insert(irc_func_dict, TOK_TEMPSHUN, cmd_dummy);
dict_insert(irc_func_dict, CMD_WHOIS, cmd_whois);
dict_insert(irc_func_dict, TOK_WHOIS, cmd_whois);
dict_insert(irc_func_dict, CMD_GLINE, cmd_gline);
user->uplink->clients--;
user->uplink->users[user->num_local] = NULL;
- if (IsOper(user))
+ if (IsOper(user)) {
userList_remove(&curr_opers, user);
+ if (count_opers > 0 && !IsBotM(user) && !IsService(user) && !IsHideOper(user))
+ count_opers--;
+ }
/* remove from global dictionary, but not if after a collide */
if (user == dict_find(clients, user->nick, NULL))
dict_remove(clients, user->nick);
void mod_usermode(struct userNode *user, const char *mode_change) {
int add = 1;
+ long setmodes = 0;
+ int donemodes = 0;
const char *word = mode_change;
if (!user || !mode_change)
call_user_mode_funcs(user, mode_change);
+ setmodes = user->modes;
+
while (*word != ' ' && *word) word++;
while (*word == ' ') word++;
- while (1) {
+ while (!donemodes) {
#define do_user_mode(FLAG) do { if (add) user->modes |= FLAG; else user->modes &= ~FLAG; } while (0)
switch (*mode_change++) {
- case 0: case ' ': return;
+ case 0: case ' ':
+ donemodes = 1;
+ break;
case '+': add = 1; break;
case '-': add = 0; break;
case 'o':
case 'g': do_user_mode(FLAGS_GLOBAL); break;
case 'B': do_user_mode(FLAGS_BOT); break;
case 'n': do_user_mode(FLAGS_HIDECHANS); break;
+ case 'p': do_user_mode(FLAGS_HIDECHANS); break;
case 'I': do_user_mode(FLAGS_HIDEIDLE); break;
case 'X': do_user_mode(FLAGS_XTRAOP); break;
case 'C': do_user_mode(FLAGS_CLOAKHOST);
}
#undef do_user_mode
}
+
+ // Set user mode +o
+ if (!(setmodes & FLAGS_OPER) && IsOper(user)) {
+ if (!IsBotM(user) && !IsService(user) && !IsHideOper(user))
+ count_opers++;
+ }
+
+ // Set user mode -o
+ if ((setmodes & FLAGS_OPER) && !IsOper(user)) {
+ if (count_opers > 1 && !(setmodes & FLAGS_BOT) &&
+ !(setmodes & FLAGS_SERVICE) && !(setmodes & FLAGS_HIDEOPER))
+ count_opers--;
+ }
+
+ // Set +H, +k or +B
+ if (!(setmodes & FLAGS_HIDEOPER) &&
+ !(setmodes & FLAGS_SERVICE) &&
+ !(setmodes & FLAGS_BOT) &&
+ (IsHideOper(user) || IsService(user) || IsBotM(user))) {
+ if ((setmodes & FLAGS_OPER) && IsOper(user) && count_opers > 0)
+ count_opers--;
+ }
+
+ // Set -H, -k or -B
+ if (((setmodes & FLAGS_HIDEOPER) ||
+ (setmodes & FLAGS_SERVICE) ||
+ (setmodes & FLAGS_BOT)) &&
+ !IsHideOper(user) && !IsService(user) && !IsBotM(user)) {
+ if ((setmodes & FLAGS_OPER) && IsOper(user))
+ count_opers++;
+ }
}
static int