* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
- * $Id: s_user.c 3161 2007-01-25 07:23:01Z nenolod $
+ * $Id: s_user.c 3219 2007-02-24 19:34:28Z jilles $
*/
#include "stdinc.h"
char umodebuf[128];
+static int orphaned_umodes = 0;
int user_modes[256] = {
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */
add_to_id_hash(source_p->id, source_p);
}
- source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes;
+ source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes & ~orphaned_umodes;
if (source_p->umodes & UMODE_INVISIBLE)
Count.invisi++;
if((flag = user_modes[(unsigned char) *pm]))
{
if(MyConnect(source_p)
- && !IsOper(source_p)
- && (ConfigFileEntry.oper_only_umodes & flag))
+ && ((!IsOper(source_p)
+ && (ConfigFileEntry.oper_only_umodes & flag))
+ || (orphaned_umodes & flag)))
{
if (what == MODE_ADD || source_p->umodes & flag)
badflag = YES;
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s (%s@%s) is now an operator", source_p->name,
source_p->username, source_p->host);
+ if(!(old & UMODE_INVISIBLE) && IsInvisible(source_p))
+ ++Count.invisi;
+ if((old & UMODE_INVISIBLE) && !IsInvisible(source_p))
+ --Count.invisi;
send_umode_out(source_p, source_p, old);
sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
construct_snobuf(source_p->snomask));
return (1);
}
+/*
+ * find_umode_slot
+ *
+ * inputs - NONE
+ * outputs - an available umode bitmask or
+ * 0 if no umodes are available
+ * side effects - NONE
+ */
+unsigned int
+find_umode_slot(void)
+{
+ unsigned int all_umodes = 0, my_umode = 0, i;
+
+ for (i = 0; i < 128; i++)
+ all_umodes |= user_modes[i];
+
+ for (my_umode = 1; my_umode && (all_umodes & my_umode);
+ my_umode <<= 1);
+
+ return my_umode;
+}
+
void
construct_umodebuf(void)
{
int i;
char *ptr = umodebuf;
+ static int prev_user_modes[128];
*ptr = '\0';
for (i = 0; i < 128; i++)
+ {
+ if (prev_user_modes[i] != 0 && prev_user_modes[i] != user_modes[i])
+ {
+ if (user_modes[i] == 0)
+ {
+ orphaned_umodes |= prev_user_modes[i];
+ sendto_realops_snomask(SNO_DEBUG, L_ALL, "Umode +%c is now orphaned", i);
+ }
+ else
+ {
+ orphaned_umodes &= ~prev_user_modes[i];
+ sendto_realops_snomask(SNO_DEBUG, L_ALL, "Orphaned umode +%c is picked up by module", i);
+ }
+ user_modes[i] = prev_user_modes[i];
+ }
+ else
+ prev_user_modes[i] = user_modes[i];
if (user_modes[i])
*ptr++ = (char) i;
+ }
*ptr++ = '\0';
}