+ if ((!src) || (!user) || (!Ptr) || (!reason))
+ {
+ log(DEFAULT,"*** BUG *** kick_channel was given an invalid parameter");
+ return;
+ }
+
+ log(DEBUG,"kick_channel: removing: %s %s %s",user->nick,Ptr->name,src->nick);
+
+ if (IS_LOCAL(src))
+ {
+ if (!Ptr->HasUser(user))
+ {
+ WriteServ(src->fd,"441 %s %s %s :They are not on that channel",src->nick, user->nick, Ptr->name);
+ return;
+ }
+ int MOD_RESULT = 0;
+
+ if (!is_uline(src->server))
+ {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnUserPreKick,OnUserPreKick(src,user,Ptr,reason));
+ if (MOD_RESULT == 1)
+ return;
+ }
+ /* Set to -1 by OnUserPreKick if explicit allow was set */
+ if (MOD_RESULT != -1)
+ {
+ FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(src,user,Ptr,AC_KICK));
+ if ((MOD_RESULT == ACR_DENY) && (!is_uline(src->server)))
+ return;
+
+ if ((MOD_RESULT == ACR_DEFAULT) || (!is_uline(src->server)))
+ {
+ if ((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr)))
+ {
+ if (cstatus(src,Ptr) == STATUS_HOP)
+ {
+ WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name);
+ }
+ else
+ {
+ WriteServ(src->fd,"482 %s %s :You must be at least a half-operator",src->nick, Ptr->name);
+ }
+
+ return;
+ }
+ }
+ }
+ }
+
+ FOREACH_MOD(I_OnUserKick,OnUserKick(src,user,Ptr,reason));
+
+ for (UserChanList::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
+ {
+ /* zap it from the channel list of the user */
+ if ((*i)->channel && ((*i)->channel == Ptr))
+ {
+ WriteChannel(Ptr,src,"KICK %s %s :%s",Ptr->name, user->nick, reason);
+ (*i)->uc_modes = 0;
+ (*i)->channel = NULL;
+ log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
+ break;
+ }
+ }
+
+ if (!Ptr->DelUser(user))
+ /* if there are no users left on the channel */
+ {
+ chan_hash::iterator iter = chanlist.find(Ptr->name);
+
+ log(DEBUG,"del_channel: destroying channel: %s",Ptr->name);
+
+ /* kill the record */
+ if (iter != chanlist.end())
+ {
+ log(DEBUG,"del_channel: destroyed: %s",Ptr->name);
+ FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr));
+ delete Ptr;
+ chanlist.erase(iter);
+ }
+ }