X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/5366977b4f3c7a50d170bf7a1e29b14c74944db7..652b8478fb78e4a90dfa73dcdf486eb7c9a0b9cc:/src/s_user.c?ds=sidebyside diff --git a/src/s_user.c b/src/s_user.c index 46c0190..a6196d6 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -21,7 +21,7 @@ * 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" @@ -65,6 +65,7 @@ extern char *crypt(); 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 */ @@ -520,7 +521,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char 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++; @@ -1055,8 +1056,9 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char 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; @@ -1305,6 +1307,10 @@ oper_up(struct Client *source_p, struct oper_conf *oper_p) 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)); @@ -1315,17 +1321,58 @@ oper_up(struct Client *source_p, struct oper_conf *oper_p) 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'; }