Explorar el Código

* Added private() chk_op/deop/voice/devoice
* -Applied functions wherever seemed fit
* Fixed several cmds for +private: +/-ban +/-exempt +/-invite bans invites exempts (un)stick -/+chrec
-Untested
* Fixed getkey (cmd/msg)
* Fixed bug in remote cmd (chat text)
* Channel msg cmds now accept <botnick> +cmd
* Increase +take warning to 1 min if opped
* Renamed isauthed() to findauth()
* Added channel '*' to cmds: kick kickban


svn: 219

Bryan Drewery hace 22 años
padre
commit
0b7cbb130d

+ 3 - 2
src/auth.c

@@ -121,7 +121,8 @@ Context;
   return i;
 }
 
-int isauthed(char *host)
+/* returns 0 if not found, -1 if problem, and > 0 if found. */
+int findauth(char *host)
 {
   int i = 0;
 Context;
@@ -129,7 +130,7 @@ Context;
     return -1;
   for (i = 0; i < auth_total; i++) {
     if (auth[i].host[0] && !strcmp(auth[i].host, host)) {
-      putlog(LOG_DEBUG, "*", STR("Debug for isauthed: checking: %s i: %d :: %s"), host, i, auth[i].host);
+      putlog(LOG_DEBUG, "*", STR("Debug for findauth: checking: %s i: %d :: %s"), host, i, auth[i].host);
       return i;
     }
   }

+ 1 - 1
src/cmds.c

@@ -766,8 +766,8 @@ Context;
       dprintf(idx, STR("Description: %s\n"), cmds[o].desc ? cmds[o].desc : "None");
       break;
     }
-  */
   }
+  */
   
   if (showall) {
     qsort(cmds, o, sizeof(mycmds), my_cmp);

+ 2 - 2
src/dccutil.c

@@ -239,7 +239,7 @@ void chatout EGG_VARARGS_DEF(char *, arg1)
   s[len + 1] = 0;
 
   for (i = 0; i < dcc_total; i++)
-    if (dcc[i].type == &DCC_CHAT)
+    if ((dcc[i].type == &DCC_CHAT) && !(dcc[i].simul))
       if (dcc[i].u.chat->channel >= 0)
         dprintf(i, "%s", s);
 
@@ -265,7 +265,7 @@ void chanout_but EGG_VARARGS_DEF(int, arg1)
   s[len + 1] = 0;
 
   for (i = 0; i < dcc_total; i++)
-    if ((dcc[i].type == &DCC_CHAT) && (i != x))
+    if ((dcc[i].type == &DCC_CHAT) && (i != x) && !(dcc[i].simul))
       if (dcc[i].u.chat->channel == chan)
         dprintf(i, "%s", s);
 }

+ 3 - 0
src/eggdrop.h

@@ -87,6 +87,9 @@
 #define kill_threshold (CFG_KILLTHRESHOLD.gdata ? atoi(CFG_KILLTHRESHOLD.gdata) : 0)
 #endif
 
+#define PRIV_OP 1
+#define PRIV_VOICE 2
+
 #define PRIO_DEOP 1
 #define PRIO_KICK 2
 #define KICK_BANNED 1

+ 58 - 5
src/misc.c

@@ -485,10 +485,8 @@ void show_channels(int idx, char *handle)
     if (l < strlen(chan->dname)) {
       l = strlen(chan->dname);
     }
-    if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
-       (glob_owner(fr) || ((glob_op(fr) || chan_op(fr)) && !(chan_deop(fr) || glob_deop(fr))))) {
+    if (chk_op(fr, chan))
       total++;
-    }
   }
 
   egg_snprintf(format, sizeof format, "  %%-%us %%-s%%-s%%-s%%-s%%-s\n", (l+2));
@@ -496,8 +494,7 @@ void show_channels(int idx, char *handle)
   for (chan = chanset;chan;chan = chan->next) {
     get_user_flagrec(u, &fr, chan->dname);
 
-    if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
-       (glob_owner(fr) || ((glob_op(fr) || chan_op(fr)) && !(chan_deop(fr) || glob_deop(fr))))) {
+    if (chk_op(fr, chan)) {
         if (!first) { 
           dprintf(idx, STR("%s %s access to %d channel%s:\n"), handle ? u->handle : "You", handle ? "has" : "have", total, (total > 1) ? "s" : "");
           
@@ -1898,3 +1895,59 @@ void werr(int errnum)
   printf(STR("(segmentation fault)\n"));
   fatal("", 0);
 }
+
+
+/* private returns 0 if user has access, and 1 if they dont because of +private 
+ * This function does not check if the user has "op" access, it only checks if the user is
+ * restricted by +private for the channel
+ */
+int private(struct flag_record fr, struct chanset_t *chan, int type)
+{
+  if (!channel_private(chan) || glob_bot(fr) || glob_owner(fr))
+    return 0; /* user is implicitly not restricted by +private, they may however be lacking other flags */
+
+  if (type == PRIV_OP) {
+    /* |o implies all flags above. n| has access to all +private. Bots are exempt. */
+    if (chan_op(fr))
+      return 0;
+  } else if (type == PRIV_VOICE) {
+    if (chan_voice(fr))
+      return 0;
+  }
+  return 1; /* user is restricted by +private */
+}
+
+int chk_op(struct flag_record fr, struct chanset_t *chan)
+{
+  if (!private(fr, chan, PRIV_OP) && !chk_deop(fr, chan)) {
+    if (chan_op(fr) || (glob_op(fr) && !chan_deop(fr)))
+      return 1;
+  }
+  return 0;
+}
+
+int chk_deop(struct flag_record fr, struct chanset_t *chan)
+{
+  if (chan_deop(fr) || (glob_deop(fr) && !chan_op(fr)))
+    return 1;
+  else
+    return 0;
+}
+
+int chk_voice(struct flag_record fr, struct chanset_t *chan)
+{
+  if (!private(fr, chan, PRIV_VOICE) && !chk_devoice(fr, chan)) {
+    if (chan_voice(fr) || (glob_voice(fr) && !chan_quiet(fr)))
+      return 1;
+  }
+  return 0;
+}
+
+int chk_devoice(struct flag_record fr, struct chanset_t *chan)
+{
+  if (chan_quiet(fr) || (glob_quiet(fr) && !chan_voice(fr)))
+    return 1;
+  else
+    return 0;
+}
+

+ 14 - 16
src/mod/channels.mod/channels.c

@@ -253,32 +253,31 @@ ContextNote("rebalance_roles");
 }
 #endif
 
-static void warn_pls_take() 
-{
-  struct chanset_t *chan;
-  for (chan = chanset; chan; chan = chan->next)
-    if (channel_take(chan))
-      putlog(LOG_WARN, "@", "%s is set +take!", chan->dname);
-}
-
 static void channels_checkslowjoin() {
   struct chanset_t * chan;
-  Context;
+Context;
   for (chan=chanset;chan;chan=chan->next) {
+Context;
     if ((chan->parttime) && (chan->parttime < now)) {
       chan->parttime = 0;
+Context;
 #ifdef LEAF
       if (channel_active(chan) && !channel_inactive(chan))
         dprintf(DP_MODE, "PART %s\n", chan->dname);
-#endif
+#endif /* LEAF */
+Context;
       remove_channel(chan);
+Context;
     } else if ((chan->jointime) && (chan->jointime < now)) {
+Context;
         chan->status &= ~CHAN_INACTIVE;
+Context;
         chan->jointime=0;
+Context;
 #ifdef LEAF
       if (!channel_inactive(chan))
         dprintf(DP_MODE, "JOIN %s %s\n", chan->dname, chan->key_prot);
-#endif
+#endif /* LEAF */
     }
   }
 }
@@ -519,7 +518,7 @@ static void remove_channel(struct chanset_t *chan)
 {
    int		 i;
    module_entry	*me;
-
+Context;
    /* Remove the channel from the list, so that noone can pull it
       away from under our feet during the check_tcl_part() call. */
    (void) chanset_unlink(chan);
@@ -1020,16 +1019,15 @@ char *channels_start(Function * global_funcs)
   module_register(MODULE_NAME, channels_table, 1, 0);
 #ifdef LEAF
   add_hook(HOOK_MINUTELY, (Function) check_limitraise);
-#endif
+#endif /* LEAF */
 #ifdef HUB
   add_hook(HOOK_30SECONDLY, (Function) rebalance_roles);
-#endif
-  add_hook(HOOK_HOURLY, (Function) warn_pls_take);
+#endif /* HUB */
   add_hook(HOOK_MINUTELY, (Function) check_expired_bans);
 #ifdef S_IRCNET
   add_hook(HOOK_MINUTELY, (Function) check_expired_exempts);
   add_hook(HOOK_MINUTELY, (Function) check_expired_invites);
-#endif
+#endif /* S_IRCNET */
   add_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
   add_hook(HOOK_3SECONDLY, (Function) channels_checkslowjoin);
   Tcl_TraceVar(interp, "global-chanset",

+ 59 - 9
src/mod/channels.mod/cmdschan.c

@@ -35,6 +35,9 @@ static void cmd_pls_ban(struct userrec *u, int idx, char *par)
       if (!chan) {
         dprintf(idx, "That channel doesn't exist!\n");
         return;
+      } else if (private(user, chan, PRIV_OP)) {
+        dprintf(idx, "No such channel.\n");
+        return;
       } else if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
         dprintf(idx, "You don't have access to set bans on %s.\n", chname);
         return;
@@ -172,6 +175,9 @@ static void cmd_pls_exempt(struct userrec *u, int idx, char *par)
       if (!chan) {
         dprintf(idx, "That channel doesn't exist!\n");
 	return;
+      } else if (private(user, chan, PRIV_OP)) {
+        dprintf(idx, "No such channel.\n");
+        return;
       } else if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
         dprintf(idx, "You don't have access to set exempts on %s.\n", chname);
         return;
@@ -299,6 +305,9 @@ static void cmd_pls_invite(struct userrec *u, int idx, char *par)
       if (!chan) {
 	dprintf(idx, "That channel doesn't exist!\n");
 	return;
+      } else if (private(user, chan, PRIV_OP)) {
+        dprintf(idx, "No such channel.\n");
+        return;
       } else if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
         dprintf(idx, "You don't have access to set invites on %s.\n", chname);
         return;
@@ -421,6 +430,11 @@ static void cmd_mns_ban(struct userrec *u, int idx, char *par)
       chname = dcc[idx].u.chat->con_chan;
     get_user_flagrec(u, &user, chname);
 
+    if (private(user, chan, PRIV_OP)) {
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
+
     if ((!chan_op(user) && (!glob_op(user) || chan_deop(user)))) {
       dprintf(idx, "You don't have access to remove bans on %s.\n", chname);
       return;
@@ -531,6 +545,12 @@ static void cmd_mns_exempt (struct userrec *u, int idx, char *par)
     if (!chname)
       chname = dcc[idx].u.chat->con_chan;
     get_user_flagrec(u, &user, chname);
+
+    if (private(user, chan, PRIV_OP)) {
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
+
     if ((!chan_op(user) && (!glob_op(user) || chan_deop(user)))) {
       dprintf(idx, "You don't have access to remove exempts on %s.\n", chname);
       return;
@@ -642,6 +662,12 @@ static void cmd_mns_invite (struct userrec *u, int idx, char *par)
     if (!chname)
       chname = dcc[idx].u.chat->con_chan;
     get_user_flagrec(u, &user, chname);
+
+    if (private(user, chan, PRIV_OP)) {
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
+
     if ((!chan_op(user) && (!glob_op(user) || chan_deop(user)))) {
       dprintf(idx, "You don't have access to remove invites on %s.\n", chname);
       return;
@@ -909,6 +935,7 @@ static void cmd_chinfo(struct userrec *u, int idx, char *par)
       dprintf(idx, "Wiped default info for %s\n", handle);
   }
 }
+
 static void cmd_slowjoin(struct userrec *u, int idx, char *par)
 {
   int intvl=0, delay=0, count=1;
@@ -958,7 +985,7 @@ static void cmd_slowjoin(struct userrec *u, int idx, char *par)
   count=0;
 #else
   count=1;
-#endif
+#endif /* HUB */
   for (bot=tandbot;bot;bot=bot->next) {
     struct userrec *ubot;
     char tmp[100];
@@ -981,7 +1008,7 @@ static void cmd_slowjoin(struct userrec *u, int idx, char *par)
   chan->status &= ~CHAN_INACTIVE;
 #ifdef LEAF
   dprintf(DP_MODE, "JOIN %s %s\n", chan->dname, chan->key_prot);
-#endif
+#endif /* LEAF */
 }
 
 static void cmd_slowpart(struct userrec *u, int idx, char *par)
@@ -1012,7 +1039,7 @@ static void cmd_slowpart(struct userrec *u, int idx, char *par)
   remove_channel(chan);
 #ifdef HUB
   write_userfile(-1);
-#endif
+#endif /* HUB */
   dprintf(idx, "Channel %s removed from the bot.\n", chname);
   dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
 
@@ -1025,7 +1052,7 @@ static void cmd_slowpart(struct userrec *u, int idx, char *par)
   count=0;
 #else
   count=1;
-#endif
+#endif /* HUB */
   for (bot=tandbot;bot;bot=bot->next) {
     char tmp[100];
     struct userrec *ubot;
@@ -1047,7 +1074,7 @@ static void cmd_slowpart(struct userrec *u, int idx, char *par)
   dprintf(idx, "%i bots parting %s during the next %i seconds\n", count, chname, delay);
 #ifdef LEAF
   dprintf(DP_MODE, "PART %s\n", chname);
-#endif
+#endif /* LEAF */
 }
 
 static void cmd_stick_yn(int idx, char *par, int yn)
@@ -1102,6 +1129,11 @@ static void cmd_stick_yn(int idx, char *par, int yn)
       dprintf(idx, "No such channel.\n");
       return;
     }
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+    if (private(user, chan, PRIV_OP)) {
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
     if (i)
       egg_snprintf(s, sizeof s, "%d", -i);
     j = u_setsticky_exempt(chan, s, yn);
@@ -1135,6 +1167,11 @@ static void cmd_stick_yn(int idx, char *par, int yn)
       dprintf(idx, "No such channel.\n");
       return;
     }
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+    if (private(user, chan, PRIV_OP)) {
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
     if (i)
       egg_snprintf(s, sizeof s, "%d", -i);
     j = u_setsticky_invite(chan, s, yn);
@@ -1147,7 +1184,7 @@ static void cmd_stick_yn(int idx, char *par, int yn)
     dprintf(idx, "No such invite.\n");
     return;
   }
-#endif
+#endif /* S_IRCNET */
   if (!chname[0]) {
     i = u_setsticky_ban(NULL, s,
                         (dcc[idx].user->flags & USER_MASTER) ? yn : -1);
@@ -1167,6 +1204,11 @@ static void cmd_stick_yn(int idx, char *par, int yn)
     dprintf(idx, "No such channel.\n");
     return;
   }
+  get_user_flagrec(dcc[idx].user, &user, chan->dname);
+  if (private(user, chan, PRIV_OP)) {
+    dprintf(idx, "No such channel.\n");
+    return;
+  }
   if (i)
     egg_snprintf(s, sizeof s, "%d", -i);
   j = u_setsticky_ban(chan, s, yn);
@@ -1221,6 +1263,10 @@ static void cmd_pls_chrec(struct userrec *u, int idx, char *par)
   }
   get_user_flagrec(u, &user, chan->dname);
   get_user_flagrec(u1, &victim, chan->dname);
+  if (private(user, chan, PRIV_OP)) {
+    dprintf(idx, "No such channel.\n");
+    return;
+  }
   if ((!glob_master(user) && !chan_master(user)) ||  /* drummer */
       (chan_owner(victim) && !chan_owner(user) && !glob_owner(user)) ||
       (glob_owner(victim) && !glob_owner(user))) {
@@ -1269,6 +1315,10 @@ static void cmd_mns_chrec(struct userrec *u, int idx, char *par)
     chn = newsplit(&par);
   get_user_flagrec(u, &user, chn);
   get_user_flagrec(u1, &victim, chn);
+  if (private(user, findchan_by_dname(chn), PRIV_OP)) {
+    dprintf(idx, "No such channel.\n");
+    return;
+  }
   if ((!glob_master(user) && !chan_master(user)) ||  /* drummer */
       (chan_owner(victim) && !chan_owner(user) && !glob_owner(user)) ||
       (glob_owner(victim) && !glob_owner(user))) {
@@ -1410,7 +1460,7 @@ static void cmd_mns_chan(struct userrec *u, int idx, char *par)
   remove_channel(chan);
 #ifdef HUB
   write_userfile(-1);
-#endif
+#endif /* HUB */
   dprintf(idx, "Channel %s removed from the bot.\n", chname);
   dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
 }
@@ -1480,7 +1530,7 @@ static void cmd_chaninfo(struct userrec *u, int idx, char *par)
       dprintf(idx, "invite-time: %d\n", chan->invite_time);
     else
       dprintf(idx, "invite-time: 0\n");
-#endif
+#endif /* S_IRCNET */
     /* Only bot owners can see/change these (they're TCL commands) */
     if (u->flags & USER_OWNER) {
       if (chan->need_op[0])
@@ -1517,7 +1567,7 @@ static void cmd_chaninfo(struct userrec *u, int idx, char *par)
 	    (chan->ircnet_status & CHAN_NOUSEREXEMPTS) ? '-' : '+',
 	    (chan->ircnet_status & CHAN_DYNAMICINVITES) ? '+' : '-',
 	    (chan->ircnet_status & CHAN_NOUSERINVITES) ? '-' : '+');
-#endif
+#endif /* S_IRCNET */
     dprintf(idx, "     %cclosed         %ctake           %cnomop          %cmanop\n",
 	    (chan->status & CHAN_CLOSED) ? '+' : '-',
 	    (chan->status & CHAN_TAKE) ? '+' : '-',

+ 15 - 0
src/mod/channels.mod/userchan.c

@@ -789,6 +789,11 @@ static void tell_bans(int idx, int show_inact, char *match)
   if (!chan && !(chan = findchan_by_dname(dcc[idx].u.chat->con_chan)) &&
       !(chan = chanset))
     chan = NULL;
+  get_user_flagrec(dcc[idx].user, &user, chan->dname);
+  if (private(user, chan, PRIV_OP)) {
+    dprintf(idx, "%s.\n", CHAN_NOSUCH);
+    return;
+  }
 
   if (chan && show_inact)
     dprintf(idx, "%s:   (! = %s %s)\n", BANS_GLOBAL,
@@ -883,6 +888,11 @@ static void tell_exempts(int idx, int show_inact, char *match)
       && !(chan = chanset))
     chan = NULL;
 
+  get_user_flagrec(dcc[idx].user, &user, chan->dname);
+  if (private(user, chan, PRIV_OP)) {
+    dprintf(idx, "%s.\n", CHAN_NOSUCH);
+    return;
+  }
   if (chan && show_inact)
     dprintf(idx, "%s:   (! = %s %s)\n", EXEMPTS_GLOBAL,
 	    MODES_NOTACTIVE, chan->dname);
@@ -977,6 +987,11 @@ static void tell_invites(int idx, int show_inact, char *match)
       && !(chan = chanset))
     chan = NULL;
 
+  get_user_flagrec(dcc[idx].user, &user, chan->dname);
+  if (private(user, chan, PRIV_OP)) {
+    dprintf(idx, "%s.\n", CHAN_NOSUCH);
+    return;
+  }
   if (chan && show_inact)
     dprintf(idx, "%s:   (! = %s %s)\n", INVITES_GLOBAL,
 	    MODES_NOTACTIVE, chan->dname);

+ 309 - 263
src/mod/irc.mod/cmdsirc.c

@@ -77,7 +77,7 @@ static void cmd_act(struct userrec *u, int idx, char *par)
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
@@ -132,7 +132,7 @@ static void cmd_say(struct userrec *u, int idx, char *par)
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
@@ -152,42 +152,34 @@ static void cmd_say(struct userrec *u, int idx, char *par)
 
 static void cmd_kickban(struct userrec *u, int idx, char *par)
 {
-  struct chanset_t *chan;
+  struct chanset_t *chan = NULL;
   char *chname, *nick, *s1;
+  int all = 0;
   memberlist *m;
   char s[UHOSTLEN];
   char bantype = 0;
 
   if (!par[0]) {
-    dprintf(idx, "Usage: kickban [channel] [-|@]<nick> [reason]\n");
+    dprintf(idx, "Usage: kickban [channel|*] [-|@]<nick> [reason]\n");
     return;
   }
-  if (strchr(CHANMETA, par[0]) != NULL)
-    chname = newsplit(&par);
-  else
-    chname = 0;
-  chan = get_channel(idx, chname);
-  if (!chan || !has_op(idx, chan))
-    return;
 
-  get_user_flagrec(dcc[idx].user, &user, chan->dname);
-
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
-    dprintf(idx, "No such channel.\n");
-    return;
+  if (par[0] == '*' && par[1] == ' ') {
+    all = 1;
+    newsplit(&par);
+  } else {
+    if (strchr(CHANMETA, par[0]) != NULL)
+      chname = newsplit(&par);
+    else
+      chname = 0;
+    chan = get_channel(idx, chname);
+    if (!chan || !has_op(idx, chan))
+      return;
   }
 
-  if (!channel_active(chan)) {
-    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
-    return;
-  }
-  if (!me_op(chan)) {
-    dprintf(idx, "I can't help you now because I'm not a channel op"
-           " on %s.\n", chan->dname);
-    return;
-  }
   putlog(LOG_CMDS, "*", "#%s# (%s) kickban %s", dcc[idx].nick,
-	 chan->dname, par);
+	 all ? "*" : chan->dname, par);
+
   nick = newsplit(&par);
   if ((nick[0] == '@') || (nick[0] == '-')) {
     bantype = nick[0];
@@ -197,60 +189,95 @@ static void cmd_kickban(struct userrec *u, int idx, char *par)
     dprintf(idx, "I'm not going to kickban myself.\n");
     return;
   }
-  m = ismember(chan, nick);
-  if (!m) {
-    dprintf(idx, "%s is not on %s\n", nick, chan->dname);
-    return;
-  }
-  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-  u = get_user_by_host(s);
-  get_user_flagrec(u, &victim, chan->dname);
+
+  if (all)
+    chan = chanset;
+  while (chan) {
+
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+
+    if (private(user, chan, PRIV_OP)) {
+      if (all) goto next;
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
+
+    if (!channel_active(chan)) {
+      if (all) goto next;
+      dprintf(idx, "I'm not on %s right now!\n", chan->dname);
+      return;
+    }
+    if (!me_op(chan)) {
+      if (all) goto next;
+      dprintf(idx, "I can't help you now because I'm not a channel op"
+             " on %s.\n", chan->dname);
+      return;
+    }
+
+
+    m = ismember(chan, nick);
+    if (!m) {
+      if (all) goto next;
+      dprintf(idx, "%s is not on %s\n", nick, chan->dname);
+      return;
+    }
+    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
+    u = get_user_by_host(s);
+    get_user_flagrec(u, &victim, chan->dname);
   
-  if ((chan_master(victim) || glob_master(victim)) &&
-      !(glob_owner(user) || chan_owner(user))) {
-    dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
-    return;
-  }
-  if (glob_bot(victim) && !(glob_owner(user) || chan_owner(user))) {
-    dprintf(idx, "%s is another channel bot!\n", nick);
-    return;
-  }
+    if ((chan_master(victim) || glob_master(victim)) &&
+        !(glob_owner(user) || chan_owner(user))) {
+      if (all) goto next;
+      dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
+      return;
+    }
+    if (glob_bot(victim) && !(glob_owner(user) || chan_owner(user))) {
+      if (all) goto next;
+      dprintf(idx, "%s is another channel bot!\n", nick);
+      return;
+    }
 #ifdef S_IRCNET
-  if (use_exempts && (u_match_mask(global_exempts,s) ||
-      u_match_mask(chan->exempts, s))) {
-    dprintf(idx, "%s is permanently exempted!\n", nick);
-    return;
-  }
-#endif
-  if (m->flags & CHANOP)
-    add_mode(chan, '-', 'o', m->nick);
-  check_exemptlist(chan, s);
-  switch (bantype) {
-    case '@':
-      s1 = strchr(s, '@');
-      s1 -= 3;
-      s1[0] = '*';
-      s1[1] = '!';
-      s1[2] = '*';
-      break;
-    case '-':
-      s1 = strchr(s, '!');
-      s1[1] = '*';
-      s1--;
-      s1[0] = '*';
-      break;
-    default:
-      s1 = quickban(chan, m->userhost);
-      break;
+    if (use_exempts && (u_match_mask(global_exempts,s) ||
+        u_match_mask(chan->exempts, s))) {
+      dprintf(idx, "%s is permanently exempted!\n", nick);
+      return;
+    }
+#endif /* S_IRCNET */
+    if (m->flags & CHANOP)
+      add_mode(chan, '-', 'o', m->nick);
+    check_exemptlist(chan, s);
+    switch (bantype) {
+      case '@':
+        s1 = strchr(s, '@');
+        s1 -= 3;
+        s1[0] = '*';
+        s1[1] = '!';
+        s1[2] = '*';
+        break;
+      case '-':
+        s1 = strchr(s, '!');
+        s1[1] = '*';
+        s1--;
+        s1[0] = '*';
+        break;
+      default:
+        s1 = quickban(chan, m->userhost);
+        break;
+    }
+    if (bantype == '@' || bantype == '-')
+      do_mask(chan, chan->channel.ban, s1, 'b');
+    if (!par[0])
+      par = "requested";
+    dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, bankickprefix, par);
+    m->flags |= SENTKICK;
+    u_addban(chan, s1, dcc[idx].nick, par, now + (60 * chan->ban_time), 0);
+    dprintf(idx, "Kick-banned %s on %s.\n", nick, chan->dname);
+    next:;
+    if (!all)
+      chan = NULL;
+    else
+      chan = chan->next;
   }
-  if (bantype == '@' || bantype == '-')
-    do_mask(chan, chan->channel.ban, s1, 'b');
-  if (!par[0])
-    par = "requested";
-  dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, bankickprefix, par);
-  m->flags |= SENTKICK;
-  u_addban(chan, s1, dcc[idx].nick, par, now + (60 * chan->ban_time), 0);
-  dprintf(idx, "Okay, done.\n");
 }
 
 static void cmd_voice(struct userrec *u, int idx, char *par)
@@ -277,9 +304,17 @@ static void cmd_voice(struct userrec *u, int idx, char *par)
   while (chan) {
     if (!nick[0] && !(nick = getnick(u->handle, chan))) {
       if (all) goto next;
-      dprintf(idx, "Usage: voice <nick> [channel]\n");
+      dprintf(idx, "Usage: voice <nick> [channel|*]\n");
+      return;
+    }
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+
+    if (private(user, chan, PRIV_VOICE)) {
+      if (all) goto next;
+      dprintf(idx, "No such channel.\n");
       return;
     }
+
     if (!channel_active(chan)) {
       if (all) goto next;
       dprintf(idx, "I'm not on %s right now!\n", chan->dname);
@@ -334,9 +369,17 @@ static void cmd_devoice(struct userrec *u, int idx, char *par)
   while (chan) {
   if (!nick[0] && !(nick = getnick(u->handle, chan))) {
     if (all) goto next;
-    dprintf(idx, "Usage: devoice <nick> [channel]\n");
+    dprintf(idx, "Usage: devoice <nick> [channel|*]\n");
+    return;
+  }
+  get_user_flagrec(dcc[idx].user, &user, chan->dname);
+
+  if (private(user, chan, PRIV_VOICE)) {
+    if (all) goto next;
+    dprintf(idx, "No such channel.\n");
     return;
   }
+
   if (!channel_active(chan)) {
     if (all) goto next;
     dprintf(idx, "I'm not on %s right now!\n", chan->dname);
@@ -414,11 +457,11 @@ static void cmd_op(struct userrec *u, int idx, char *par)
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
   if (!nick[0] && !(nick = getnick(u->handle, chan))) {
     if (all) goto next;
-    dprintf(idx, "Usage: op <nick> [channel/*]\n"); /*nano fix*/
+    dprintf(idx, "Usage: op <nick> [channel|*]\n");
     return;
   }
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     if (!all)
       dprintf(idx, "No such channel.\n");
     goto next;
@@ -449,17 +492,11 @@ static void cmd_op(struct userrec *u, int idx, char *par)
     if (all) goto next;
     return;
   }
-  if (channel_bitch(chan)
-      && !(chan_op(victim) || (glob_op(victim) && !chan_deop(victim)))) {
+  if (channel_bitch(chan) && !chk_op(victim, chan)) {
     dprintf(idx, "%s is not a registered op on %s.\n", m->nick, chan->dname);
     if (all) goto next;
     return;
   }
-  if (channel_bitch(chan) && channel_private(chan) && !chan_op(victim) && !glob_owner(victim)) {
-    if (!all)
-      dprintf(idx, "%s is not a registered op on %s.\n", m->nick, chan->dname);
-    goto next;
-  }
 
 //  add_mode(chan, '+', 'o', nick);
   if (!chan_hasop(m)) {
@@ -787,103 +824,93 @@ static void cmd_deop(struct userrec *u, int idx, char *par)
 
   while (chan) {
 
-  get_user_flagrec(dcc[idx].user, &user, chan->dname);
-  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
-    if (all) goto next;  
-    dprintf(idx, "Usage: deop <nick> [channel]\n");
-    return;
-  }
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
-    if (!all)
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+    if (!nick[0] && !(nick = getnick(u->handle, chan))) {
+      if (all) goto next;  
+      dprintf(idx, "Usage: deop <nick> [channel|*]\n");
+      return;
+    }
+    if (private(user, chan, PRIV_OP)) {
+      if (all) goto next;
       dprintf(idx, "No such channel.\n");
-    goto next;
-  }
-  if (!channel_active(chan)) {
-    if (all) goto next;  
-    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
-    return;
-  }
-  if (!me_op(chan)) {
-    if (all) goto next;  
-    dprintf(idx, "I can't help you now because I'm not a chan op on %s.\n",
-	    chan->dname);
-    return;
-  }
-  m = ismember(chan, nick);
-  if (!m) {
-    if (all) goto next;  
-    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
-    return;
-  }
-  if (match_my_nick(nick)) {
-    if (all) goto next;  
-    dprintf(idx, "I'm not going to deop myself.\n");
-    return;
-  }
-  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-  u = get_user_by_host(s);
-  get_user_flagrec(u, &victim, chan->dname);
+    }
+    if (!channel_active(chan)) {
+      if (all) goto next;  
+      dprintf(idx, "I'm not on %s right now!\n", chan->dname);
+      return;
+    }
+    if (!me_op(chan)) {
+      if (all) goto next;  
+      dprintf(idx, "I can't help you now because I'm not a chan op on %s.\n",
+  	    chan->dname);
+      return;
+    }
+    m = ismember(chan, nick);
+    if (!m) {
+      if (all) goto next;  
+      dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
+      return;
+    }
+    if (match_my_nick(nick)) {
+      if (all) goto next;  
+      dprintf(idx, "I'm not going to deop myself.\n");
+      return;
+    }
+    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
+    u = get_user_by_host(s);
+    get_user_flagrec(u, &victim, chan->dname);
 
-  if ((chan_master(victim) || glob_master(victim)) &&
-      !(chan_owner(user) || glob_owner(user))) {
-    dprintf(idx, "%s is a master for %s.\n", m->nick, chan->dname);
-    if (all) goto next;  
-    return;
-  }
-  if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
-      !(chan_master(user) || glob_master(user))) {
-    dprintf(idx, "%s has the op flag for %s.\n", m->nick, chan->dname);
-    if (all) goto next;  
-    return;
-  }
-  add_mode(chan, '-', 'o', nick);
-  dprintf(idx, "Took op from %s on %s.\n", nick, chan->dname);
-  next:;
+    if ((chan_master(victim) || glob_master(victim)) &&
+        !(chan_owner(user) || glob_owner(user))) {
+      dprintf(idx, "%s is a master for %s.\n", m->nick, chan->dname);
+      if (all) goto next;  
+      return;
+    }
+    if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
+        !(chan_master(user) || glob_master(user))) {
+      dprintf(idx, "%s has the op flag for %s.\n", m->nick, chan->dname);
+      if (all) goto next;  
+      return;
+    }
+    add_mode(chan, '-', 'o', nick);
+    dprintf(idx, "Deopped %s on %s.\n", nick, chan->dname);
+    next:;
     if (!all)
       chan = NULL;
     else
       chan = chan->next;
   }
-
 }
 
 static void cmd_kick(struct userrec *u, int idx, char *par)
 {
-  struct chanset_t *chan;
+  struct chanset_t *chan = NULL;
   char *chname, *nick;
+  int all = 0;
   memberlist *m;
   char s[UHOSTLEN];
 
   if (!par[0]) {
-    dprintf(idx, "Usage: kick [channel] <nick> [reason]\n");
+    dprintf(idx, "Usage: kick [channel|*] <nick> [reason]\n");
     return;
   }
-  if (strchr(CHANMETA, par[0]) != NULL)
-    chname = newsplit(&par);
-  else
-    chname = 0;
-  chan = get_channel(idx, chname);
-  if (!chan || !has_op(idx, chan))
-    return;
-
-  get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
-    dprintf(idx, "No such channel.\n");
-    return;
+  if (par[0] == '*' && par[1] == ' ') {
+    all = 1;
+    newsplit(&par);
+  } else {
+    if (strchr(CHANMETA, par[0]) != NULL)
+      chname = newsplit(&par);
+    else
+      chname = 0;
+    chan = get_channel(idx, chname);
+    if (!chan || !has_op(idx, chan))
+      return;
   }
 
-  if (!channel_active(chan)) {
-    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
-    return;
-  }
-  if (!me_op(chan)) {
-    dprintf(idx, "I can't help you now because I'm not a channel op %s",
-	    "on %s.\n", chan->dname);
-    return;
-  }
   putlog(LOG_CMDS, "*", "#%s# (%s) kick %s", dcc[idx].nick,
-	 chan->dname, par);
+	 all ? "*" : chan->dname, par);
+
   nick = newsplit(&par);
   if (!par[0])
     par = "request";
@@ -891,38 +918,69 @@ static void cmd_kick(struct userrec *u, int idx, char *par)
     dprintf(idx, "I'm not going to kick myself.\n");
     return;
   }
-  m = ismember(chan, nick);
-  if (!m) {
-    dprintf(idx, "%s is not on %s\n", nick, chan->dname);
-    return;
-  }
-  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-  u = get_user_by_host(s);
-  get_user_flagrec(u, &victim, chan->dname);
-  if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
-      !(chan_master(user) || glob_master(user))) {
-    dprintf(idx, "%s is a legal op.\n", nick);
-    return;
-  }
-  if ((chan_master(victim) || glob_master(victim)) &&
-      !(glob_owner(user) || chan_owner(user))) {
-    dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
-    return;
-  }
-  if (glob_bot(victim) && !(glob_owner(user) || chan_owner(user))) {
-    dprintf(idx, "%s is another channel bot!\n", nick);
-    return;
+  if (all)
+    chan = chanset;
+  while (chan) {
+
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+
+    if (private(user, chan, PRIV_OP)) {
+      if (all) goto next;
+      dprintf(idx, "No such channel.\n");
+      return;
+    }
+
+    if (!channel_active(chan)) {
+      if (all) goto next;
+      dprintf(idx, "I'm not on %s right now!\n", chan->dname);
+      return;
+    }
+    if (!me_op(chan)) {
+      if (all) goto next;
+      dprintf(idx, "I can't help you now because I'm not a channel op %s",
+  	    "on %s.\n", chan->dname);
+      return;
+    }
+
+    m = ismember(chan, nick);
+    if (!m) {
+      if (all) goto next;
+      dprintf(idx, "%s is not on %s\n", nick, chan->dname);
+      return;
+    }
+    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
+    u = get_user_by_host(s);
+    get_user_flagrec(u, &victim, chan->dname);
+    if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
+        !(chan_master(user) || glob_master(user))) {
+      if (all) goto next;
+      dprintf(idx, "%s is a legal op.\n", nick);
+      return;
+    }
+    if ((chan_master(victim) || glob_master(victim)) &&
+        !(glob_owner(user) || chan_owner(user))) {
+      if (all) goto next;
+      dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
+      return;
+    }
+    if (glob_bot(victim) && !(glob_owner(user) || chan_owner(user))) {
+      dprintf(idx, "%s is another channel bot!\n", nick);
+      return;
+    }
+    dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, par);
+    m->flags |= SENTKICK;
+    dprintf(idx, "Kicked %s on %s.\n", nick, chan->dname);
+    next:;
+    if (!all)
+      chan = NULL;
+    else
+      chan = chan->next;
   }
-  dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, par);
-  m->flags |= SENTKICK;
-  dprintf(idx, "Okay, done.\n");
 }
 
 static void cmd_getkey(struct userrec *u, int idx, char *par)
 {
   struct chanset_t *chan;
-  char s[256];
-  char *p, *p2, *p3;
 
   chan = get_channel(idx, par);
   if (!chan || !has_op(idx, chan))
@@ -932,7 +990,7 @@ static void cmd_getkey(struct userrec *u, int idx, char *par)
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
@@ -947,22 +1005,13 @@ static void cmd_getkey(struct userrec *u, int idx, char *par)
     return;
   }
 
-  strcpy(s, getchanmode(chan));
-  p = (char *) &s;
-  p2 = newsplit(&p);
-  p3 = newsplit(&p);
-
-
-  if (!strchr(p2, 'k'))
-    dprintf(idx, "%s has no key set\n", chan->dname);
-  else {
-    if (p3[0])
-      dprintf(idx, "Key for %s is: %s\n", chan->dname, p3);
-    else
-      dprintf(idx, "No key set in %s\n", chan->dname);
-  }
+  if (!chan->channel.key[0])
+    dprintf(idx, "%s has no key set.", chan->dname);
+  else
+    dprintf(idx, "Key for %s is: %s", chan->dname, chan->channel.key);
   if (chan->key_prot[0])
-    dprintf(idx, " Enforcing +k %s\n", chan->key_prot);
+    dprintf(idx, " (Enforcing +k %s)", chan->key_prot);
+  dprintf(idx, "\n");
 }
 
 static void cmd_find(struct userrec *u, int idx, char *par)
@@ -983,7 +1032,7 @@ static void cmd_find(struct userrec *u, int idx, char *par)
   for (chan = chanset; chan; chan = chan->next) {
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
-    if (!channel_private(chan) || (channel_private(chan) && (chan_op(user) || glob_owner(user)))) {
+    if (!private(user, chan, PRIV_OP)) {
 
       for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
         char tmp[256];
@@ -1065,40 +1114,37 @@ static void cmd_invite(struct userrec *u, int idx, char *par)
 
   while (chan) {
 
-  get_user_flagrec(dcc[idx].user, &user, chan->dname);
-
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
-    if (!all)
+    get_user_flagrec(dcc[idx].user, &user, chan->dname);
+    if (private(user, chan, PRIV_OP)) {
+      if (all) goto next;
       dprintf(idx, "No such channel.\n");
-    goto next;
-  }
+    }
 
-  if (!me_op(chan)) {
-    if (all) goto next;
-    if (chan->channel.mode & CHANINV) {
-      dprintf(idx, "I can't help you now because I'm not a channel op on %s", chan->dname);
-      return;
+    if (!me_op(chan)) {
+      if (all) goto next;
+      if (chan->channel.mode & CHANINV) {
+        dprintf(idx, "I can't help you now because I'm not a channel op on %s", chan->dname);
+        return;
+      }
+      if (!channel_active(chan)) {
+        dprintf(idx, "I'm not on %s right now!\n", chan->dname);
+        return;
+      }
     }
-    if (!channel_active(chan)) {
-      dprintf(idx, "I'm not on %s right now!\n", chan->dname);
+    m = ismember(chan, nick);
+    if (m && !chan_issplit(m)) {
+      if (all) goto next;
+      dprintf(idx, "%s is already on %s!\n", nick, chan->dname);
       return;
     }
-  }
-  m = ismember(chan, nick);
-  if (m && !chan_issplit(m)) {
-    if (all) goto next;
-    dprintf(idx, "%s is already on %s!\n", nick, chan->dname);
-    return;
-  }
-  dprintf(DP_SERVER, "INVITE %s %s\n", nick, chan->name);
-  dprintf(idx, "Inviting %s to %s.\n", nick, chan->dname);
-  next:;
+    dprintf(DP_SERVER, "INVITE %s %s\n", nick, chan->name);
+    dprintf(idx, "Inviting %s to %s.\n", nick, chan->dname);
+    next:;
     if (!all)
       chan = NULL;
     else
-      chan = chan->next;
+    chan = chan->next;
   }
-
 }
 
 #ifdef S_AUTH
@@ -1110,7 +1156,8 @@ static void cmd_authed(struct userrec *u, int idx, char *par)
 
   dprintf(idx, "Authed:\n");
   for (i = 0; i < auth_total; i++) {
-   dprintf(idx, " %d. %s!%s at %li\n", i, auth[i].nick, auth[i].host, auth[i].authtime);
+   if (auth[i].authed)
+     dprintf(idx, " %d. %s!%s at %li\n", i, auth[i].nick, auth[i].host, auth[i].authtime);
   }
 }
 #endif /* S_AUTH */
@@ -1129,19 +1176,20 @@ static void cmd_channel(struct userrec *u, int idx, char *par)
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
 
   putlog(LOG_CMDS, "*", "#%s# (%s) channel", dcc[idx].nick, chan->dname);
   strncpyz(s, getchanmode(chan), sizeof s);
-  if (channel_pending(chan))
+  if (channel_pending(chan)) {
     egg_snprintf(s1, sizeof s1, "%s %s", IRC_PROCESSINGCHAN, chan->dname);
-  else if (channel_active(chan))
+  } else if (channel_active(chan)) {
     egg_snprintf(s1, sizeof s1, "%s %s", IRC_CHANNEL, chan->dname);
-  else
+  } else {
     egg_snprintf(s1, sizeof s1, "%s %s", IRC_DESIRINGCHAN, chan->dname);
+  }
   dprintf(idx, "%s, %d member%s, mode %s:\n", s1, chan->channel.members,
 	  chan->channel.members == 1 ? "" : "s", s);
   if (chan->channel.topic)
@@ -1289,31 +1337,31 @@ static void cmd_topic(struct userrec *u, int idx, char *par)
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
-    if (!channel_active(chan)) {
-      dprintf(idx, "I'm not on %s right now!\n", chan->dname);
-      return;
-    }
-    if (!par[0]) {
-      if (chan->channel.topic) {
-	dprintf(idx, "The topic for %s is: %s\n", chan->dname,
-		chan->channel.topic);
-      } else {
-	dprintf(idx, "No topic is set for %s\n", chan->dname);
-      }
-    } else if (channel_optopic(chan) && !me_op(chan)) {
-      dprintf(idx, "I'm not a channel op on %s and the channel %s",
-		  "is +t.\n", chan->dname);
+
+  if (!channel_active(chan)) {
+    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
+    return;
+  }
+  if (!par[0]) {
+    if (chan->channel.topic) {
+      dprintf(idx, "The topic for %s is: %s\n", chan->dname,
+	chan->channel.topic);
     } else {
-      dprintf(DP_SERVER, "TOPIC %s :%s\n", chan->name, par);
-      dprintf(idx, "Changing topic...\n");
-      putlog(LOG_CMDS, "*", "#%s# (%s) topic %s", dcc[idx].nick,
-	     chan->dname, par);
+      dprintf(idx, "No topic is set for %s\n", chan->dname);
     }
-//  }
+  } else if (channel_optopic(chan) && !me_op(chan)) {
+    dprintf(idx, "I'm not a channel op on %s and the channel %s",
+	  "is +t.\n", chan->dname);
+  } else {
+    dprintf(DP_SERVER, "TOPIC %s :%s\n", chan->name, par);
+    dprintf(idx, "Changing topic...\n");
+    putlog(LOG_CMDS, "*", "#%s# (%s) topic %s", dcc[idx].nick,
+	    chan->dname, par);
+  }
 }
 
 static void cmd_resetbans(struct userrec *u, int idx, char *par)
@@ -1327,7 +1375,7 @@ static void cmd_resetbans(struct userrec *u, int idx, char *par)
 
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
@@ -1348,7 +1396,7 @@ static void cmd_resetexempts(struct userrec *u, int idx, char *par)
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
@@ -1367,7 +1415,7 @@ static void cmd_resetinvites(struct userrec *u, int idx, char *par)
     return;
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
-  if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+  if (private(user, chan, PRIV_OP)) {
     dprintf(idx, "No such channel.\n");
     return;
   }
@@ -1547,9 +1595,7 @@ static void cmd_reset(struct userrec *u, int idx, char *par)
 
     if (chan)
       get_user_flagrec(dcc[idx].user, &user, chan->dname);
-    if (!chan)
-      dprintf(idx, "%s\n", IRC_NOMONITOR);
-    else if (channel_private(chan) && !chan_op(user) && !glob_owner(user)) {
+    if (!chan || private(user, chan, PRIV_OP)) {
       dprintf(idx, "%s\n", IRC_NOMONITOR);
     } else {
       get_user_flagrec(u, &user, par);
@@ -1604,4 +1650,4 @@ static cmd_t irc_dcc[] =
   {NULL,		NULL,	 NULL,				NULL}
 };
 
-#endif
+#endif /* LEAF */

+ 10 - 0
src/mod/irc.mod/irc.c

@@ -1055,6 +1055,15 @@ static void check_lonely_channel(struct chanset_t *chan)
   }
 }
 
+static void warn_pls_take()
+{
+  struct chanset_t *chan;
+  for (chan = chanset; chan; chan = chan->next)
+    if (channel_take(chan) && me_op(chan))
+      putlog(LOG_WARN, "*", "%s is set +take, and I'm already opped! Try +bitch instead", chan->dname);
+}
+
+
 void check_servers() {
   struct chanset_t * chan;
   memberlist * m;
@@ -1865,6 +1874,7 @@ char *irc_start(Function * global_funcs)
 #endif
   }
   add_hook(HOOK_MINUTELY, (Function) check_expired_chanstuff);
+  add_hook(HOOK_MINUTELY, (Function) warn_pls_take);
   add_hook(HOOK_MINUTELY, (Function) check_servers);
   add_hook(HOOK_ADD_MODE, (Function) real_add_mode);
   add_hook(HOOK_IDLE, (Function) flush_modes);

+ 32 - 20
src/mod/irc.mod/msgcmds.c

@@ -122,7 +122,7 @@ static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
   if (u && (u->flags & USER_BOT))
     return 1;
 
-  i = isauthed(host);
+  i = findauth(host);
 
   if (i != -1) {
     if (auth[i].authed) {
@@ -158,7 +158,7 @@ static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
   if (u && (u->flags & USER_BOT))
     return 1;
 
-  i = isauthed(host);
+  i = findauth(host);
 
   if (i == -1) 
     return 1;
@@ -196,7 +196,7 @@ static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par)
   if (u && (u->flags & USER_BOT))
     return 1;
 
-  i = isauthed(host);
+  i = findauth(host);
 
   if (i == -1)
     return 1;
@@ -231,7 +231,7 @@ static int msg_unauth(char *nick, char *host, struct userrec *u, char *par)
   if (u && (u->flags & USER_BOT))
     return 1;
 
-  i = isauthed(host);
+  i = findauth(host);
 
   if (i == -1)
     return 1;
@@ -477,7 +477,22 @@ static cmd_t C_msg[] =
 #ifdef S_AUTH
 static int msgc_test(char *nick, char *host, struct userrec *u, char *par, char *chname)
 {
-  dprintf(DP_HELP, "NOTICE %s :Works :)\n", nick);
+  char *chn, *hand;
+  struct chanset_t *chan;
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
+  struct userrec *user;
+  
+  hand = newsplit(&par);
+  user = get_user_by_handle(userlist, hand);
+  chn = newsplit(&par);
+  chan = findchan_by_dname(chn);
+  get_user_flagrec(user, &fr, chan->dname);
+
+  dprintf(DP_HELP, "PRIVMSG %s :Private-o: %d Private-v: %d canop: %d canvoice: %d deop: %d devoice: %d\n", nick, 
+  private(fr, chan, 1), private(fr, chan, 2), 
+  chk_op(fr, chan), chk_voice(fr, chan), chk_deop(fr, chan), chk_devoice(fr, chan));
+
+//  dprintf(DP_HELP, "NOTICE %s :Works :)\n", nick);
   return 0;
 }
 
@@ -499,7 +514,7 @@ static int msgc_op(char *nick, char *host, struct userrec *u, char *par, char *c
 
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %sOP %s", nick, host, u->handle, chname ? chname : "", cmdprefix, par ? par : "");
 
-  if (par[0] == '-') { //we have an option!
+  if (par[0] == '-') { /* we have an option! */
     char *tmp;
     par++;
     tmp = newsplit(&par);
@@ -637,20 +652,17 @@ static int msgc_getkey(char *nick, char *host, struct userrec *u, char *par, cha
   chan = findchan_by_dname(par);
   if (chan && channel_active(chan) && !channel_pending(chan)) {
     get_user_flagrec(u, &fr, chan->dname);
-    if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
-       (chan_op(fr) || (glob_op(fr) && !chan_deop(fr)))) {
-      char s[256];
-      char *p, *p2, *p3;
-
-      strcpy(s, getchanmode(chan));
-      p = (char *) &s;
-      p2 = newsplit(&p);
-      p3 = newsplit(&p);
-
-      if (p3[0]) {
-        dprintf(DP_HELP, "NOTICE %s :key for %s is: %s\n", nick, chan->dname, p3);
+/*    if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
+       (chan_op(fr) || (glob_op(fr) && !chan_deop(fr)))) { */
+    if (chk_op(fr, chan)) {
+/*      char buf[512];
+      if (chan->key_prot[0])
+        snprintf(buf, sizeof buf, "Enforcing +k %s", chan->key_prot); */
+
+      if (chan->channel.key[0]) {
+        dprintf(DP_HELP, "NOTICE %s :Key for %s is: %s\n", nick, chan->dname, chan->channel.key);
       } else {
-        dprintf(DP_HELP, "NOTICE %s :No key set in %s\n", nick, chan->dname);
+        dprintf(DP_HELP, "NOTICE %s :%s has no key set.\n", nick, chan->dname);
       }
     }
   }
@@ -720,7 +732,7 @@ static int msgc_invite(char *nick, char *host, struct userrec *u, char *par, cha
 
 static cmd_t C_msgc[] =
 {
-  {"test",		"",	(Function) msgc_test,		NULL},
+  {"test",		"a",	(Function) msgc_test,		NULL},
   {"op",		"",	(Function) msgc_op,		NULL},
   {"voice",		"",	(Function) msgc_voice,		NULL},
   {"channels",		"",	(Function) msgc_channels,	NULL},

+ 6 - 3
src/mod/module.h

@@ -295,9 +295,12 @@
 #define makepass ((void (*) (char *))global[152])
 #define wild_match ((int (*)(const char *, const char *))global[153])
 #define maskhost ((void (*)(const char *, char *))global[154])
-#define show_motd ((void(*)(int))global[155])
+#define private ((int (*)(struct flag_record, struct chanset_t *, int))global[155])
 /* 156 - 159 */
-
+#define chk_op ((int (*)(struct flag_record, struct chanset_t *))global[156])
+#define chk_deop ((int (*)(struct flag_record, struct chanset_t *))global[157])
+#define chk_voice ((int (*)(struct flag_record, struct chanset_t *))global[158])
+#define chk_devoice ((int (*)(struct flag_record, struct chanset_t *))global[159])
 /* 160 - 163 */
 #define touch_laston ((void (*)(struct userrec *,char *,time_t))global[160])
 #define add_mode ((void (*)(struct chanset_t *,char,char,char *))(*(Function**)(global[161])))
@@ -520,7 +523,7 @@
 #define auth_total (*(int*)global[316])
 /* 317 - 320 */
 #define new_auth ((int (*) (void))global[317])
-#define isauthed ((int (*) (char *))global[318])
+#define findauth ((int (*) (char *))global[318])
 #define removeauth ((void (*)(int))global[319])
 #define makehash ((char *(*)(struct userrec *, char *))global[320])
 /* 321 - 324 */

+ 2 - 2
src/mod/server.mod/servmsg.c

@@ -348,7 +348,7 @@ static int detect_flood(char *floodnick, char *floodhost, char *from, int which)
     return 0;
 
 #ifdef S_AUTH
-  if (isauthed(floodhost) > -1) 
+  if (findauth(floodhost) > -1) 
     return 0;
 #endif /* S_AUTH */
 
@@ -563,7 +563,7 @@ static int gotmsg(char *from, char *msg)
       code = newsplit(&msg);
       rmspace(msg);
 Context;
-      i = isauthed(uhost);
+      i = findauth(uhost);
       /* is it a cmd? */
 
 Context;

+ 6 - 6
src/modules.c

@@ -351,12 +351,12 @@ Function global_table[] =
   (Function) makepass,
   (Function) _wild_match,
   (Function) maskhost,
-  (Function) show_motd,
+  (Function) private,
   /* 156 - 159 */
-  (Function) 0,
-  (Function) 0,
-  (Function) 0,
-  (Function) 0,
+  (Function) chk_op,
+  (Function) chk_deop,
+  (Function) chk_voice,
+  (Function) chk_devoice,
   /* 160 - 163 */
   (Function) touch_laston,
   (Function) & add_mode,	/* Function *				*/
@@ -575,7 +575,7 @@ Function global_table[] =
   (Function) & auth, /* struct auth_t *auth */
   (Function) & auth_total,
   (Function) new_auth,
-  (Function) isauthed,
+  (Function) findauth,
   (Function) removeauth,
   (Function) makehash,
   (Function) & USERENTRY_SECPASS,

+ 6 - 1
src/proto.h

@@ -214,7 +214,7 @@ char *progname();
 
 /* auth.c */
 int new_auth();
-int isauthed(char *);
+int findauth(char *);
 void removeauth(int);
 char *makehash(struct userrec *, char *);
 
@@ -281,6 +281,11 @@ char *str_escape(const char *str, const char div, const char mask);
 char *strchr_unescape(char *str, const char div, register const char esc_char);
 void str_unescape(char *str, register const char esc_char);
 void kill_bot(char *, char *);
+int private(struct flag_record, struct chanset_t *, int);
+int chk_op(struct flag_record, struct chanset_t *);
+int chk_deop(struct flag_record, struct chanset_t *);
+int chk_voice(struct flag_record, struct chanset_t *);
+int chk_devoice(struct flag_record, struct chanset_t *);
 
 /* net.c */
 #ifdef HAVE_SSL