]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/chanserv.c
added extern type to comply with gcc10 change
[irc/evilnet/x3.git] / src / chanserv.c
index 0e3c78487f04f9a1a03be8d24ef8702d7a8a0686..5931cd0fc731b9654e409ba6bd5d5cdf5bb52b34 100644 (file)
 #include "spamserv.h"
 #include "timeq.h"
 
-#define CHANSERV_CONF_NAME     "services/chanserv"
+#define CHANSERV_CONF_NAME  "services/chanserv"
 
 /* ChanServ options */
-#define KEY_SUPPORT_CHANNEL     "support_channel"
-#define KEY_SUPPORT_CHANNEL_MODES "support_channel_modes"
-#define KEY_DB_BACKUP_FREQ     "db_backup_freq"
-#define KEY_INFO_DELAY         "info_delay"
-#define KEY_MAX_GREETLEN               "max_greetlen"
-#define KEY_ADJUST_THRESHOLD           "adjust_threshold"
-#define KEY_ADJUST_DELAY       "adjust_delay"
-#define KEY_CHAN_EXPIRE_FREQ   "chan_expire_freq"
-#define KEY_CHAN_EXPIRE_DELAY  "chan_expire_delay"
-#define KEY_DNR_EXPIRE_FREQ    "dnr_expire_freq"
-#define KEY_BAN_TIMEOUT_FREQ    "ban_timeout_freq"
-#define KEY_MAX_CHAN_USERS             "max_chan_users"
-#define KEY_MAX_CHAN_BANS      "max_chan_bans"
-#define KEY_NICK               "nick"
-#define KEY_OLD_CHANSERV_NAME  "old_chanserv_name"
-#define KEY_8BALL_RESPONSES     "8ball"
-#define KEY_OLD_BAN_NAMES       "old_ban_names"
-#define KEY_REFRESH_PERIOD      "refresh_period"
+#define KEY_SUPPORT_CHANNEL         "support_channel"
+#define KEY_SUPPORT_CHANNEL_MODES   "support_channel_modes"
+#define KEY_DB_BACKUP_FREQ          "db_backup_freq"
+#define KEY_INFO_DELAY              "info_delay"
+#define KEY_MAX_GREETLEN            "max_greetlen"
+#define KEY_ADJUST_THRESHOLD        "adjust_threshold"
+#define KEY_ADJUST_DELAY            "adjust_delay"
+#define KEY_CHAN_EXPIRE_FREQ        "chan_expire_freq"
+#define KEY_CHAN_EXPIRE_DELAY       "chan_expire_delay"
+#define KEY_DNR_EXPIRE_FREQ         "dnr_expire_freq"
+#define KEY_BAN_TIMEOUT_FREQ        "ban_timeout_freq"
+#define KEY_MAX_CHAN_USERS          "max_chan_users"
+#define KEY_MAX_CHAN_BANS           "max_chan_bans"
+#define KEY_NICK                    "nick"
+#define KEY_OLD_CHANSERV_NAME       "old_chanserv_name"
+#define KEY_8BALL_RESPONSES         "8ball"
+#define KEY_OLD_BAN_NAMES           "old_ban_names"
+#define KEY_REFRESH_PERIOD          "refresh_period"
 #define KEY_CTCP_SHORT_BAN_DURATION "ctcp_short_ban_duration"
 #define KEY_CTCP_LONG_BAN_DURATION  "ctcp_long_ban_duration"
 #define KEY_MAX_OWNED               "max_owned"
 #define KEY_IRC_OPERATOR_EPITHET    "irc_operator_epithet"
 #define KEY_NETWORK_HELPER_EPITHET  "network_helper_epithet"
 #define KEY_SUPPORT_HELPER_EPITHET  "support_helper_epithet"
-#define KEY_NODELETE_LEVEL      "nodelete_level"
-#define KEY_MAX_USERINFO_LENGTH "max_userinfo_length"
-#define KEY_GIVEOWNERSHIP_PERIOD "giveownership_timeout"
-#define KEY_VALID_CHANNEL_REGEX "valid_channel_regex"
+#define KEY_NODELETE_LEVEL          "nodelete_level"
+#define KEY_MAX_USERINFO_LENGTH     "max_userinfo_length"
+#define KEY_GIVEOWNERSHIP_PERIOD    "giveownership_timeout"
+#define KEY_VALID_CHANNEL_REGEX     "valid_channel_regex"
 
 /* ChanServ database */
-#define KEY_VERSION_CONTROL     "version_control"
-#define KEY_CHANNELS           "channels"
-#define KEY_NOTE_TYPES          "note_types"
+#define KEY_VERSION_CONTROL         "version_control"
+#define KEY_CHANNELS                "channels"
+#define KEY_NOTE_TYPES              "note_types"
 
 /* version control paramiter */
-#define KEY_VERSION_NUMBER      "version_number"
+#define KEY_VERSION_NUMBER          "version_number"
 
 /* Note type parameters */
-#define KEY_NOTE_OPSERV_ACCESS  "opserv_access"
-#define KEY_NOTE_CHANNEL_ACCESS "channel_access"
-#define KEY_NOTE_SETTER_ACCESS  "setter_access"
-#define KEY_NOTE_VISIBILITY     "visibility"
-#define KEY_NOTE_VIS_PRIVILEGED "privileged"
-#define KEY_NOTE_VIS_CHANNEL_USERS "channel_users"
-#define KEY_NOTE_VIS_ALL        "all"
-#define KEY_NOTE_MAX_LENGTH     "max_length"
-#define KEY_NOTE_SETTER         "setter"
-#define KEY_NOTE_NOTE           "note"
+#define KEY_NOTE_OPSERV_ACCESS      "opserv_access"
+#define KEY_NOTE_CHANNEL_ACCESS     "channel_access"
+#define KEY_NOTE_SETTER_ACCESS      "setter_access"
+#define KEY_NOTE_VISIBILITY         "visibility"
+#define KEY_NOTE_VIS_PRIVILEGED     "privileged"
+#define KEY_NOTE_VIS_CHANNEL_USERS  "channel_users"
+#define KEY_NOTE_VIS_ALL            "all"
+#define KEY_NOTE_MAX_LENGTH         "max_length"
+#define KEY_NOTE_SETTER             "setter"
+#define KEY_NOTE_NOTE               "note"
 
 /* Do-not-register channels */
-#define KEY_DNR                 "dnr"
-#define KEY_DNR_SET             "set"
-#define KEY_DNR_SETTER          "setter"
-#define KEY_DNR_REASON          "reason"
+#define KEY_DNR                     "dnr"
+#define KEY_DNR_SET                 "set"
+#define KEY_DNR_SETTER              "setter"
+#define KEY_DNR_REASON              "reason"
 
 /* Channel data */
-#define KEY_REGISTERED         "registered"
-#define KEY_REGISTRAR          "registrar"
-#define KEY_SUSPENDED           "suspended"
-#define KEY_PREVIOUS            "previous"
-#define KEY_SUSPENDER          "suspender"
-#define KEY_ISSUED              "issued"
-#define KEY_REVOKED             "revoked"
-#define KEY_SUSPEND_EXPIRES     "suspend_expires"
-#define KEY_SUSPEND_REASON      "suspend_reason"
-#define KEY_GIVEOWNERSHIP       "giveownership"
-#define KEY_STAFF_ISSUER        "staff_issuer"
-#define KEY_OLD_OWNER           "old_owner"
-#define KEY_TARGET              "target"
-#define KEY_TARGET_ACCESS       "target_access"
-#define KEY_VISITED            "visited"
-#define KEY_TOPIC              "topic"
-#define KEY_GREETING           "greeting"
-#define KEY_USER_GREETING      "user_greeting"
-#define KEY_MODES              "modes"
-#define KEY_FLAGS              "flags"
-#define KEY_OPTIONS             "options"
-#define KEY_USERS              "users"
-#define KEY_BANS               "bans" /* for lamers */
-#define KEY_MAX                        "max"
-#define KEY_NOTES               "notes"
-#define KEY_TOPIC_MASK          "topic_mask"
-#define KEY_OWNER_TRANSFER      "owner_transfer"
-#define KEY_MAXSETINFO          "maxsetinfo"
+#define KEY_REGISTERED              "registered"
+#define KEY_REGISTRAR               "registrar"
+#define KEY_SUSPENDED               "suspended"
+#define KEY_PREVIOUS                "previous"
+#define KEY_SUSPENDER               "suspender"
+#define KEY_ISSUED                  "issued"
+#define KEY_REVOKED                 "revoked"
+#define KEY_SUSPEND_EXPIRES         "suspend_expires"
+#define KEY_SUSPEND_REASON          "suspend_reason"
+#define KEY_GIVEOWNERSHIP           "giveownership"
+#define KEY_STAFF_ISSUER            "staff_issuer"
+#define KEY_OLD_OWNER               "old_owner"
+#define KEY_TARGET                  "target"
+#define KEY_TARGET_ACCESS           "target_access"
+#define KEY_VISITED                 "visited"
+#define KEY_TOPIC                   "topic"
+#define KEY_GREETING                "greeting"
+#define KEY_USER_GREETING           "user_greeting"
+#define KEY_MODES                   "modes"
+#define KEY_FLAGS                   "flags"
+#define KEY_OPTIONS                 "options"
+#define KEY_USERS                   "users"
+#define KEY_BANS                    "bans" /* for lamers */
+#define KEY_MAX                     "max"
+#define KEY_NOTES                   "notes"
+#define KEY_TOPIC_MASK              "topic_mask"
+#define KEY_OWNER_TRANSFER          "owner_transfer"
+#define KEY_MAXSETINFO              "maxsetinfo"
 
 /* User data */
-#define KEY_LEVEL              "level"
-#define KEY_INFO               "info"
-#define KEY_SEEN               "seen"
-#define KEY_ACCESSEXPIRY       "accessexpiry"
-#define KEY_CLVLEXPIRY         "clvlexpiry"
-#define KEY_LASTLEVEL          "lastlevel"
+#define KEY_LEVEL                   "level"
+#define KEY_INFO                    "info"
+#define KEY_SEEN                    "seen"
+#define KEY_ACCESSEXPIRY            "accessexpiry"
+#define KEY_CLVLEXPIRY              "clvlexpiry"
+#define KEY_LASTLEVEL               "lastlevel"
 
 /* Ban data */
-#define KEY_OWNER              "owner"
-#define KEY_REASON             "reason"
-#define KEY_SET                        "set"
-#define KEY_DURATION           "duration"
-#define KEY_EXPIRES             "expires"
-#define KEY_TRIGGERED          "triggered"
+#define KEY_OWNER                   "owner"
+#define KEY_REASON                  "reason"
+#define KEY_SET                     "set"
+#define KEY_DURATION                "duration"
+#define KEY_EXPIRES                 "expires"
+#define KEY_TRIGGERED               "triggered"
 
-#define KEY_GOD_TIMEOUT         "god_timeout"
+#define KEY_GOD_TIMEOUT             "god_timeout"
 
 #define CHANNEL_DEFAULT_FLAGS   (CHANNEL_OFFCHANNEL | CHANNEL_UNREVIEWED)
 #define CHANNEL_PRESERVED_FLAGS (CHANNEL_UNREVIEWED)
@@ -224,7 +224,7 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_TRIMMED_USERS", "Trimmed $b%d users$b with access from %d to %d from the %s user list who were inactive for at least %s." },
     { "CSMSG_INCORRECT_ACCESS", "%s has access $b%s$b, not %s." },
     { "CSMSG_USER_EXISTS", "%s is already on the $b%s$b user list (with %s access)." },
-    { "CSMSG_ADDUSER_PENDING", "I have sent him/her a message letting them know, and if they auth or register soon, I will finish adding them automatically." },
+    { "CSMSG_ADDUSER_PENDING", "I have sent %s a message letting them know, and if they auth or register soon, I will finish adding them automatically." },
     { "CSMSG_ADDUSER_PENDING_ALREADY", "He or she is already pending addition to %s once he/she auths with $b$N$b." },
     { "CSMSG_ADDUSER_PENDING_HEADER", "Users to add to channels pending logins:" }, /* Remove after testing? */
     { "CSMSG_ADDUSER_PENDING_LIST", "Channel %s user %s" },             /* Remove after testing? */
@@ -257,10 +257,12 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_DURATION_TOO_LOW", "Timed bans must last for at least 15 seconds." },
     { "CSMSG_DURATION_TOO_HIGH", "Timed bans must last for less than 2 years." },
     { "CSMSG_LAME_MASK", "$b%s$b is a little too general. Try making it more specific." },
+    { "CSMSG_NO_EXTBANS", "$b%s$b is an extended ban, which are not allowed." },
     { "CSMSG_MASK_PROTECTED", "Sorry, ban for $b%s$b conflicts with a protected user's hostmask." },
     { "CSMSG_NO_MATCHING_USERS", "No one in $b%s$b has a hostmask matching $b%s$b." },
     { "CSMSG_BAN_NOT_FOUND", "Sorry, no ban or LAMER found: $b%s$b." },
     { "CSMSG_BANLIST_FULL", "The $b%s$b channel ban list is $bfull$b." },
+    { "CSMSG_BAD_BAN", "The given ban $b%s$b is invalid." },
 
     { "CSMSG_INVALID_TRIM", "$b%s$b isn't a valid trim target." },
 
@@ -440,7 +442,7 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_HELPER_NO_ACCESS", "%s lacks access to %s but has $bsecurity override$b enabled." },
     { "CSMSG_HELPER_HAS_ACCESS", "%s has $b%s$b access (%d) in %s and has $bsecurity override$b enabled." },
     { "CSMSG_LAZY_SMURF_TARGET", "%s is %s ($bIRCOp$b; not logged in)." },
-    { "CSMSG_SMURF_TARGET", "%s is %s ($b%s$b)." },
+    { "CSMSG_SMURF_TARGET", "%s %s ($b%s$b)." },
     { "CSMSG_OPERATOR_TITLE", "IRC operator" },
     { "CSMSG_UC_H_TITLE", "network helper" },
     { "CSMSG_LC_H_TITLE", "support helper" },
@@ -572,26 +574,26 @@ static const struct message_entry msgtab[] = {
 };
 
 /* eject_user and unban_user flags */
-#define ACTION_KICK            0x0001
-#define ACTION_BAN             0x0002
-#define ACTION_ADD_LAMER       0x0004
-#define ACTION_ADD_TIMED_LAMER         0x0008
-#define ACTION_UNBAN           0x0010
-#define ACTION_DEL_LAMER       0x0020
+#define ACTION_KICK     0x0001
+#define ACTION_BAN      0x0002
+#define ACTION_ADD_LAMER    0x0004
+#define ACTION_ADD_TIMED_LAMER  0x0008
+#define ACTION_UNBAN        0x0010
+#define ACTION_DEL_LAMER    0x0020
 
 /* The 40 allows for [+-ntlksimprD] and lots of fudge factor. */
-#define MODELEN                        40 + KEYLEN
-#define PADLEN                 21
-#define ACCESSLEN              10
+#define MODELEN         40 + KEYLEN
+#define PADLEN          21
+#define ACCESSLEN       10
 
-#define CSFUNC_ARGS            user, channel, argc, argv, cmd
+#define CSFUNC_ARGS     user, channel, argc, argv, cmd
 
 #define CHANSERV_FUNC(NAME) MODCMD_FUNC(NAME)
-#define CHANSERV_SYNTAX()      svccmd_send_help_brief(user, chanserv, cmd)
-#define REQUIRE_PARAMS(N)      if(argc < (N)) {            \
-       reply("MSG_MISSING_PARAMS", argv[0]); \
-       CHANSERV_SYNTAX(); \
-       return 0; }
+#define CHANSERV_SYNTAX()   svccmd_send_help_brief(user, chanserv, cmd)
+#define REQUIRE_PARAMS(N)   if(argc < (N)) {            \
+    reply("MSG_MISSING_PARAMS", argv[0]); \
+    CHANSERV_SYNTAX(); \
+    return 0; }
 
 DECLARE_LIST(dnrList, struct do_not_register *);
 DEFINE_LIST(dnrList, struct do_not_register *)
@@ -613,26 +615,26 @@ static struct
     struct channelList  support_channels;
     struct mod_chanmode default_modes;
 
-    unsigned long      db_backup_frequency;
-    unsigned long      channel_expire_frequency;
+    unsigned long   db_backup_frequency;
+    unsigned long   channel_expire_frequency;
     unsigned long       ban_timeout_frequency;
-    unsigned long      dnr_expire_frequency;
+    unsigned long   dnr_expire_frequency;
 
-    long               info_delay;
-    unsigned int       adjust_delay;
-    long               channel_expire_delay;
+    long        info_delay;
+    unsigned int    adjust_delay;
+    long        channel_expire_delay;
     unsigned int        nodelete_level;
 
-    unsigned int       adjust_threshold;
-    int                        join_flood_threshold;
+    unsigned int    adjust_threshold;
+    int         join_flood_threshold;
 
-    unsigned int       greeting_length;
+    unsigned int    greeting_length;
     unsigned int        refresh_period;
     unsigned int        giveownership_period;
 
     unsigned int        max_owned;
-    unsigned int       max_chan_users;
-    unsigned int       max_chan_bans; /* lamers */
+    unsigned int    max_chan_users;
+    unsigned int    max_chan_bans; /* lamers */
     unsigned int        max_userinfo_length;
     unsigned int        valid_channel_regex_set : 1;
 
@@ -677,7 +679,7 @@ enum note_visible_type
     NOTE_VIS_PRIVILEGED
 };
 
-struct io_fd *socket_io_fd;
+extern struct io_fd *socket_io_fd;
 extern struct cManagerNode cManager;
 
 struct note_type
@@ -897,52 +899,52 @@ _GetChannelUser(struct chanData *channel, struct handle_info *handle, int overri
     if(override && HANDLE_FLAGGED(handle, HELPING)
        && ((handle->opserv_level >= chanserv_conf.nodelete_level) || !IsProtected(channel)))
     {
-       for(uData = helperList;
-           uData && uData->handle != handle;
-           uData = uData->next);
+    for(uData = helperList;
+        uData && uData->handle != handle;
+        uData = uData->next);
 
-       if(!uData)
-       {
-           uData = calloc(1, sizeof(struct userData));
-           uData->handle = handle;
+    if(!uData)
+    {
+        uData = calloc(1, sizeof(struct userData));
+        uData->handle = handle;
 
-           uData->access = UL_HELPER;
-           uData->seen = 0;
+        uData->access = UL_HELPER;
+        uData->seen = 0;
 
-           uData->info = NULL;
+        uData->info = NULL;
 
-           uData->prev = NULL;
-           uData->next = helperList;
-           if(helperList)
-               helperList->prev = uData;
-           helperList = uData;
-       }
+        uData->prev = NULL;
+        uData->next = helperList;
+        if(helperList)
+        helperList->prev = uData;
+        helperList = uData;
+    }
 
-       head = &helperList;
+    head = &helperList;
     }
     else
     {
-       for(uData = channel->users; uData; uData = uData->next)
+    for(uData = channel->users; uData; uData = uData->next)
             if((uData->handle == handle) && (allow_suspended || !IsUserSuspended(uData)))
                 break;
 
-       head = &(channel->users);
+    head = &(channel->users);
     }
 
     if(uData && (uData != *head))
     {
-       /* Shuffle the user to the head of whatever list he was in. */
-       if(uData->next)
+    /* Shuffle the user to the head of whatever list he was in. */
+    if(uData->next)
             uData->next->prev = uData->prev;
-       if(uData->prev)
+    if(uData->prev)
             uData->prev->next = uData->next;
 
-       uData->prev = NULL;
-       uData->next = *head;
+    uData->prev = NULL;
+    uData->next = *head;
 
-       if(*head)
-           (**head).prev = uData;
-       *head = uData;
+    if(*head)
+        (**head).prev = uData;
+    *head = uData;
     }
 
     return uData;
@@ -993,7 +995,7 @@ scan_user_presence(struct userData *uData, struct userNode *user)
 }
 
 static void
-chanserv_ctcp_check(struct userNode *user, struct chanNode *channel, const char *text, UNUSED_ARG(struct userNode *bot), UNUSED_ARG(unsigned int is_notice))
+chanserv_ctcp_check(struct userNode *user, struct chanNode *channel, const char *text, UNUSED_ARG(struct userNode *bot), UNUSED_ARG(unsigned int is_notice), UNUSED_ARG(void *extra))
 {
     unsigned int eflags, argc;
     char *argv[4];
@@ -1008,12 +1010,12 @@ chanserv_ctcp_check(struct userNode *user, struct chanNode *channel, const char
     /* We dont punish people we know -Rubin 
      *    * Figure out the minimum level needed to CTCP the channel *
      *
-     *     if(check_user_level(channel, user, lvlCTCPUsers, 1, 0))
-     *         return;
+     *      if(check_user_level(channel, user, lvlCTCPUsers, 1, 0))
+     *      return;
      */
     /* If they are a user of the channel, they are exempt */
     if(_GetChannelUser(channel->channel_info, user->handle_info, 0, 0))
-           return;
+        return;
     /* We need to enforce against them; do so. */
     eflags = 0;
     argv[0] = (char*)text;
@@ -1058,7 +1060,7 @@ chanserv_deref_note_type(void *data)
     struct note_type *ntype = data;
 
     if(--ntype->refs > 0)
-       return;
+    return;
     free(ntype);
 }
 
@@ -1081,7 +1083,7 @@ chanserv_truncate_notes(struct note_type *ntype)
         note = dict_find(cData->notes, ntype->name, NULL);
         if(!note)
             continue;
-       if(strlen(note->note) <= ntype->max_length)
+    if(strlen(note->note) <= ntype->max_length)
             continue;
         dict_remove2(cData->notes, ntype->name, 1);
         note = realloc(note, size);
@@ -1126,7 +1128,7 @@ static MODCMD_FUNC(cmd_createnote) {
     if((ntype = dict_find(note_types, argv[1], NULL)))
         existed = 1;
     else
-       ntype = chanserv_create_note_type(argv[arg]);
+    ntype = chanserv_create_note_type(argv[arg]);
     if(!irccasecmp(argv[++arg], "privileged"))
     {
         arg++;
@@ -1139,7 +1141,7 @@ static MODCMD_FUNC(cmd_createnote) {
         if(!ulvl)
         {
             reply("CSMSG_INVALID_ACCESS", argv[arg]);
-           goto fail;
+        goto fail;
         }
         ntype->set_access_type = NOTE_SET_CHANNEL_ACCESS;
         ntype->set_access.min_ulevel = ulvl;
@@ -1151,7 +1153,7 @@ static MODCMD_FUNC(cmd_createnote) {
     else
     {
         reply("CSMSG_BAD_NOTE_ACCESS", argv[arg]);
-       goto fail;
+    goto fail;
     }
 
     if(!irccasecmp(argv[++arg], "privileged"))
@@ -1162,23 +1164,23 @@ static MODCMD_FUNC(cmd_createnote) {
         ntype->visible_type = NOTE_VIS_ALL;
     else {
         reply("CSMSG_BAD_NOTE_ACCESS", argv[arg]);
-       goto fail;
+    goto fail;
     }
 
     if((arg+1) >= argc) {
         reply("MSG_MISSING_PARAMS", argv[0]);
-       goto fail;
+    goto fail;
     }
     max_length = strtoul(argv[++arg], NULL, 0);
     if(max_length < 20 || max_length > 450)
     {
         reply("CSMSG_BAD_MAX_LENGTH", argv[arg]);
-       goto fail;
+    goto fail;
     }
     if(existed && (max_length < ntype->max_length))
     {
-       ntype->max_length = max_length;
-       chanserv_truncate_notes(ntype);
+    ntype->max_length = max_length;
+    chanserv_truncate_notes(ntype);
     }
     ntype->max_length = max_length;
 
@@ -1190,7 +1192,7 @@ static MODCMD_FUNC(cmd_createnote) {
 
 fail:
     if(!existed)
-       dict_remove(note_types, ntype->name);
+    dict_remove(note_types, ntype->name);
     return 0;
 }
 
@@ -1307,7 +1309,7 @@ register_channel(struct chanNode *cNode, char *registrar)
     channel->next = channelList;
 
     if(channelList)
-       channelList->prev = channel;
+    channelList->prev = channel;
     channelList = channel;
     registered_channels++;
 
@@ -1324,7 +1326,7 @@ add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned
     struct userData *ud;
 
     if(access_level > UL_OWNER)
-       return NULL;
+    return NULL;
 
     ud = calloc(1, sizeof(*ud));
     ud->channel = channel;
@@ -1339,7 +1341,7 @@ add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned
     ud->prev = NULL;
     ud->next = channel->users;
     if(channel->users)
-       channel->users->prev = ud;
+    channel->users->prev = ud;
     channel->users = ud;
 
     channel->userCount++;
@@ -1647,12 +1649,12 @@ add_channel_ban(struct chanData *channel, const char *mask, char *owner, time_t
     bd->reason = strdup(reason);
 
     if(expires)
-       timeq_add(expires, expire_ban, bd);
+    timeq_add(expires, expire_ban, bd);
 
     bd->prev = NULL;
     bd->next = channel->bans; /* lamers */
     if(channel->bans)
-       channel->bans->prev = bd;
+    channel->bans->prev = bd;
     channel->bans = bd;
     channel->banCount++;
     banCount++;
@@ -1675,7 +1677,7 @@ del_channel_ban(struct banData *ban)
         ban->next->prev = ban->prev;
 
     if(ban->expires)
-       timeq_del(0, expire_ban, ban, TIMEQ_IGNORE_WHEN);
+    timeq_del(0, expire_ban, ban, TIMEQ_IGNORE_WHEN);
 
     if(ban->reason)
         free(ban->reason);
@@ -1697,7 +1699,7 @@ expire_ban(void *data) /* lamer.. */
         for(ii=0; ii<bans.used; ii++)
         {
             if(!strcmp(bans.list[ii]->ban, bd->mask))
-           {
+        {
                 change.argc = 1;
                 change.args[0].mode = MODE_REMOVE|MODE_BAN;
                 change.args[0].u.hostmask = bd->mask;
@@ -1729,7 +1731,7 @@ unregister_channel(struct chanData *channel, const char *reason)
     */
 
     if(!channel)
-       return;
+    return;
 
     timeq_del(0, NULL, channel, TIMEQ_IGNORE_FUNC | TIMEQ_IGNORE_WHEN);
 
@@ -1743,10 +1745,10 @@ unregister_channel(struct chanData *channel, const char *reason)
     wipe_adduser_pending(channel->channel, NULL);
 
     while(channel->users)
-       del_channel_user(channel->users, 0);
+    del_channel_user(channel->users, 0);
 
     while(channel->bans)
-       del_channel_ban(channel->bans);
+    del_channel_ban(channel->bans);
 
     free(channel->topic);
     free(channel->registrar);
@@ -1764,8 +1766,8 @@ unregister_channel(struct chanData *channel, const char *reason)
 
     if(channel->suspended)
     {
-       struct chanNode *cNode = channel->channel;
-       struct suspended *suspended, *next_suspended;
+    struct chanNode *cNode = channel->channel;
+    struct suspended *suspended, *next_suspended;
 
         for(suspended = channel->suspended; suspended; suspended = next_suspended)
         {
@@ -1777,8 +1779,8 @@ unregister_channel(struct chanData *channel, const char *reason)
             free(suspended);
         }
 
-       if(cNode)
-           cNode->channel_info = NULL;
+    if(cNode)
+        cNode->channel_info = NULL;
     }
     channel->channel->channel_info = NULL;
 
@@ -1804,7 +1806,7 @@ expire_channels(UNUSED_ARG(void *data))
 
     for(channel = channelList; channel; channel = next)
     {
-       next = channel->next;
+    next = channel->next;
 
         /* See if the channel can be expired. */
         if(((now - channel->visited) <= chanserv_conf.channel_expire_delay)
@@ -1825,7 +1827,7 @@ expire_channels(UNUSED_ARG(void *data))
     }
 
     if(chanserv_conf.channel_expire_frequency)
-       timeq_add(now + chanserv_conf.channel_expire_frequency, expire_channels, NULL);
+    timeq_add(now + chanserv_conf.channel_expire_frequency, expire_channels, NULL);
 }
 
 static void
@@ -1885,7 +1887,7 @@ protect_user(const struct userNode *victim, const struct userNode *aggressor, st
         return 1;
 
     if(protect == 'n')
-       return 0;
+    return 0;
 
     if(protect != 'a' && !cs_victim)
         return 0;
@@ -1909,14 +1911,14 @@ protect_user(const struct userNode *victim, const struct userNode *aggressor, st
     switch(protect)
     {
     case 'l':
-       if(cs_victim->access > cs_aggressor->access)
+    if(cs_victim->access > cs_aggressor->access)
             return 1;
-       break;
+    break;
     case 'a':
     case 'e':
-       if(cs_victim->access >= cs_aggressor->access)
+    if(cs_victim->access >= cs_aggressor->access)
             return 1;
-       break;
+    break;
     }
 
     return 0;
@@ -1933,10 +1935,10 @@ validate_op(struct svccmd *cmd, struct userNode *user, struct chanNode *channel,
        && !check_user_level(channel, user, lvlEnfOps, 0, 0))
     {
         if(cmd)
-           reply("CSMSG_OPBY_LOCKED");
+        reply("CSMSG_OPBY_LOCKED");
         else
             send_message(user, chanserv, "CSMSG_OPBY_LOCKED");
-       return 0;
+    return 0;
     }
 
     return 1;
@@ -1965,14 +1967,14 @@ validate_deop(struct svccmd *cmd, struct userNode *user, struct chanNode *channe
 {
     if(IsService(victim))
     {
-       reply("MSG_SERVICE_IMMUNE", victim->nick);
-       return 0;
+    reply("MSG_SERVICE_IMMUNE", victim->nick);
+    return 0;
     }
 
     if(protect_user(victim, user, channel->channel_info, false))
     {
-       reply("CSMSG_USER_PROTECTED", victim->nick);
-       return 0;
+    reply("CSMSG_USER_PROTECTED", victim->nick);
+    return 0;
     }
 
     return 1;
@@ -2539,13 +2541,13 @@ static CHANSERV_FUNC(cmd_register)
 
     if(argc >= (new_channel+2))
     {
-       if(!IsHelping(user))
-       {
-           reply("CSMSG_PROXY_FORBIDDEN");
-           return 0;
-       }
+    if(!IsHelping(user))
+    {
+        reply("CSMSG_PROXY_FORBIDDEN");
+        return 0;
+    }
 
-       if(!(handle = modcmd_get_handle_info(user, argv[new_channel+1])))
+    if(!(handle = modcmd_get_handle_info(user, argv[new_channel+1])))
             return 0;
         force = (argc > (new_channel+2)) && !irccasecmp(argv[new_channel+2], "force");
         dnr = chanserv_is_dnr(chan_name, handle);
@@ -2699,11 +2701,11 @@ static CHANSERV_FUNC(cmd_unregister)
             return 0;
         }
         confirm_string = make_confirmation_string(uData);
-       if((argc < 2) || strcmp(argv[1], confirm_string))
-       {
-           reply("CSMSG_CONFIRM_UNREG", channel->name, confirm_string);
-           return 0;
-       }
+    if((argc < 2) || strcmp(argv[1], confirm_string))
+    {
+        reply("CSMSG_CONFIRM_UNREG", channel->name, confirm_string);
+        return 0;
+    }
     }
 
     sprintf(reason, "unregistered by %s.", user->handle_info->handle);
@@ -2755,8 +2757,8 @@ static CHANSERV_FUNC(cmd_move)
 
     if(IsProtected(channel->channel_info))
     {
-       reply("CSMSG_MOVE_NODELETE", channel->name);
-       return 0;
+    reply("CSMSG_MOVE_NODELETE", channel->name);
+    return 0;
     }
 
     if(!IsChannelName(argv[1]))
@@ -2795,8 +2797,8 @@ static CHANSERV_FUNC(cmd_move)
     }
     else if(target->channel_info)
     {
-       reply("CSMSG_ALREADY_REGGED", target->name);
-       return 0;
+    reply("CSMSG_ALREADY_REGGED", target->name);
+    return 0;
     }
     else if((!(mn = GetUserMode(target, user)) || !(mn->modes && MODE_CHANOP))
             && !IsHelping(user))
@@ -2857,7 +2859,7 @@ merge_users(struct chanData *source, struct chanData *target)
 
     /* Insert the source's users into the scratch area. */
     for(suData = source->users; suData; suData = suData->next)
-       dict_insert(merge, suData->handle->handle, suData);
+        dict_insert(merge, suData->handle->handle, suData);
 
     /* Iterate through the target's users, looking for
        users common to both channels. The lower access is
@@ -2865,50 +2867,50 @@ merge_users(struct chanData *source, struct chanData *target)
        list. */
     for(tuData = target->users; tuData; tuData = next)
     {
-       struct userData *choice;
+        struct userData *choice;
 
-       next = tuData->next;
+        next = tuData->next;
 
-       /* If a source user exists with the same handle as a target
-          channel's user, resolve the conflict by removing one. */
-       suData = dict_find(merge, tuData->handle->handle, NULL);
-       if(!suData)
-           continue;
+        /* If a source user exists with the same handle as a target
+           channel's user, resolve the conflict by removing one. */
+        suData = dict_find(merge, tuData->handle->handle, NULL);
+        if(!suData)
+            continue;
 
-       /* Pick the data we want to keep. */
-        /* If the access is the same, use the later seen time. */
-       if(suData->access == tuData->access)
-           choice = (suData->seen > tuData->seen) ? suData : tuData;
-       else /* Otherwise, keep the higher access level. */
-           choice = (suData->access > tuData->access) ? suData : tuData;
+        /* Pick the data we want to keep. */
+            /* If the access is the same, use the later seen time. */
+        if(suData->access == tuData->access)
+            choice = (suData->seen > tuData->seen) ? suData : tuData;
+        else /* Otherwise, keep the higher access level. */
+            choice = (suData->access > tuData->access) ? suData : tuData;
 
-       /* Remove the user that wasn't picked. */
-       if(choice == tuData)
-       {
-           dict_remove(merge, suData->handle->handle);
-           del_channel_user(suData, 0);
-       }
-       else
-           del_channel_user(tuData, 0);
+        /* Remove the user that wasn't picked. */
+        if(choice == tuData)
+        {
+            dict_remove(merge, suData->handle->handle);
+            del_channel_user(suData, 0);
+        }
+        else
+            del_channel_user(tuData, 0);
     }
 
     /* Move the remaining users to the target channel. */
     for(it = dict_first(merge); it; it = iter_next(it))
     {
-       suData = iter_data(it);
+        suData = iter_data(it);
 
-       /* Insert the user into the target channel's linked list. */
-       suData->prev = NULL;
-       suData->next = target->users;
+        /* Insert the user into the target channel's linked list. */
+        suData->prev = NULL;
+        suData->next = target->users;
         suData->channel = target;
 
-       if(target->users)
-           target->users->prev = suData;
-       target->users = suData;
+        if(target->users)
+            target->users->prev = suData;
+        target->users = suData;
 
-       /* Update the user counts for the target channel; the
-          source counts are left alone. */
-       target->userCount++;
+        /* Update the user counts for the target channel; the
+       source counts are left alone. */
+        target->userCount++;
     }
 
     /* Possible to assert (source->users == NULL) here. */
@@ -2928,72 +2930,72 @@ merge_bans(struct chanData *source, struct chanData *target)
     /* Perform a totally expensive O(n*m) merge, ick. */
     for(sbData = source->bans; sbData; sbData = sNext)
     {
-       /* Flag to track whether the ban's been moved
-          to the destination yet. */
-       int moved = 0;
-
-       /* Possible to assert (sbData->prev == NULL) here. */
-       sNext = sbData->next;
-
-       for(tbData = tFront; tbData; tbData = tNext)
-       {
-           tNext = tbData->next;
-
-           /* Perform two comparisons between each source
-              and target ban, conflicts are resolved by
-              keeping the broader ban and copying the later
-              expiration and triggered time. */
-           if(match_ircglobs(tbData->mask, sbData->mask))
-           {
-               /* There is a broader ban in the target channel that
-                  overrides one in the source channel; remove the 
-                  source ban and break. */
-               if(sbData->expires > tbData->expires)
-                   tbData->expires = sbData->expires;
-               if(sbData->triggered > tbData->triggered)
-                   tbData->triggered = sbData->triggered;
-               del_channel_ban(sbData);
-               break;
-           }
-           else if(match_ircglobs(sbData->mask, tbData->mask))
-           {
-               /* There is a broader ban in the source channel that
-                  overrides one in the target channel; remove the
-                  target ban, fall through and move the source over. */
-               if(tbData->expires > sbData->expires)
-                   sbData->expires = tbData->expires;
-               if(tbData->triggered > sbData->triggered)
-                   sbData->triggered = tbData->triggered;
-               if(tbData == tFront)
-                   tFront = tNext;
-               del_channel_ban(tbData);
-           }
-
-           /* Source bans can override multiple target bans, so
-              we allow a source to run through this loop multiple
-              times, but we can only move it once. */
-           if(moved)
-               continue;
-           moved = 1;
-
-           /* Remove the source ban from the source ban list. */
-           if(sbData->next)
-               sbData->next->prev = sbData->prev;
-
-           /* Modify the source ban's associated channel. */
-           sbData->channel = target;
-
-           /* Insert the ban into the target channel's linked list. */
-           sbData->prev = NULL;
-           sbData->next = target->bans;
-
-           if(target->bans)
-               target->bans->prev = sbData;
-           target->bans = sbData;
-
-           /* Update the user counts for the target channel. */
-           target->banCount++;
-       }
+        /* Flag to track whether the ban's been moved
+           to the destination yet. */
+        int moved = 0;
+
+        /* Possible to assert (sbData->prev == NULL) here. */
+        sNext = sbData->next;
+
+        for(tbData = tFront; tbData; tbData = tNext)
+        {
+            tNext = tbData->next;
+
+            /* Perform two comparisons between each source
+               and target ban, conflicts are resolved by
+               keeping the broader ban and copying the later
+               expiration and triggered time. */
+            if(match_ircglobs(tbData->mask, sbData->mask))
+            {
+                /* There is a broader ban in the target channel that
+                   overrides one in the source channel; remove the 
+                   source ban and break. */
+                if(sbData->expires > tbData->expires)
+                    tbData->expires = sbData->expires;
+                if(sbData->triggered > tbData->triggered)
+                    tbData->triggered = sbData->triggered;
+                del_channel_ban(sbData);
+                break;
+            }
+            else if(match_ircglobs(sbData->mask, tbData->mask))
+            {
+                /* There is a broader ban in the source channel that
+                   overrides one in the target channel; remove the
+                   target ban, fall through and move the source over. */
+                if(tbData->expires > sbData->expires)
+                    sbData->expires = tbData->expires;
+                if(tbData->triggered > sbData->triggered)
+                    sbData->triggered = tbData->triggered;
+                if(tbData == tFront)
+                    tFront = tNext;
+                del_channel_ban(tbData);
+            }
+
+            /* Source bans can override multiple target bans, so
+               we allow a source to run through this loop multiple
+               times, but we can only move it once. */
+            if(moved)
+            continue;
+            moved = 1;
+
+            /* Remove the source ban from the source ban list. */
+            if(sbData->next)
+            sbData->next->prev = sbData->prev;
+
+            /* Modify the source ban's associated channel. */
+            sbData->channel = target;
+
+            /* Insert the ban into the target channel's linked list. */
+            sbData->prev = NULL;
+            sbData->next = target->bans;
+
+            if(target->bans)
+            target->bans->prev = sbData;
+            target->bans = sbData;
+
+            /* Update the user counts for the target channel. */
+            target->banCount++;
+        }
     }
 
     /* Possible to assert (source->bans == NULL) here. */
@@ -3008,7 +3010,7 @@ merge_data(struct chanData *source, struct chanData *target)
      * Do not touch last_refresh, ban count or user counts.
      */
     if(source->visited > target->visited)
-       target->visited = source->visited;
+    target->visited = source->visited;
     if(source->registered < target->registered)
         target->registered = source->registered;
     if(source->ownerTransfer > target->ownerTransfer)
@@ -3045,8 +3047,8 @@ static CHANSERV_FUNC(cmd_merge)
     }
 
     if (argc > 2) {
-      if (!irccasecmp("nodelete", argv[2]))
-        nodelete = 1;
+        if (!irccasecmp("nodelete", argv[2]))
+            nodelete = 1;
     }
 
     if(!target->channel_info)
@@ -3085,7 +3087,7 @@ static CHANSERV_FUNC(cmd_merge)
     spamserv_cs_move_merge(user, channel, target, 0);
     sprintf(reason, "merged into %s by %s.", target->name, user->handle_info->handle);
     if (!nodelete)
-      unregister_channel(channel->channel_info, reason);
+        unregister_channel(channel->channel_info, reason);
     reply("CSMSG_MERGE_SUCCESS", target->name);
     return 1;
 }
@@ -3122,22 +3124,22 @@ static CHANSERV_FUNC(cmd_adduser)
     struct userData *actee;
     struct userData *actor, *real_actor;
     struct handle_info *handle = NULL;
-    struct adduserPending *tmp;
+    //struct adduserPending *tmp;
     unsigned short access_level, override = 0;
 
     REQUIRE_PARAMS(3);
 
     if(channel->channel_info->userCount >= chanserv_conf.max_chan_users)
     {
-       reply("CSMSG_MAXIMUM_USERS", chanserv_conf.max_chan_users);
-       return 0;
+        reply("CSMSG_MAXIMUM_USERS", chanserv_conf.max_chan_users);
+        return 0;
     }
 
     access_level = user_level_from_name(argv[2], UL_OWNER);
     if(!access_level)
     {
-       reply("CSMSG_INVALID_ACCESS", argv[2]);
-       return 0;
+        reply("CSMSG_INVALID_ACCESS", argv[2]);
+        return 0;
     }
 
     actor = GetChannelUser(channel->channel_info, user->handle_info);
@@ -3145,8 +3147,8 @@ static CHANSERV_FUNC(cmd_adduser)
 
     if(actor->access <= access_level)
     {
-       reply("CSMSG_NO_BUMP_ACCESS");
-       return 0;
+        reply("CSMSG_NO_BUMP_ACCESS");
+        return 0;
     }
 
     /* Trying to add someone with equal/more access */
@@ -3165,8 +3167,8 @@ static CHANSERV_FUNC(cmd_adduser)
             }
             else {
                 if(IsInChannel(channel, unode)) {
-                   reply("CSMSG_ADDUSER_PENDING");
-                   tmp = add_adduser_pending(channel, unode, access_level);
+                   reply("CSMSG_ADDUSER_PENDING", unode->nick);
+                   add_adduser_pending(channel, unode, access_level);
                    send_message_type(1,unode, chanserv, "CSMSG_ADDUSER_PENDING_TARGET", user->nick, channel->name);
                 }
                 /* this results in user must auth AND not in chan errors. too confusing..
@@ -3181,8 +3183,8 @@ static CHANSERV_FUNC(cmd_adduser)
 
     if((actee = GetTrueChannelAccess(channel->channel_info, handle)))
     {
-       reply("CSMSG_USER_EXISTS", handle->handle, channel->name, user_level_name_from_level(actee->access));
-       return 0;
+        reply("CSMSG_USER_EXISTS", handle->handle, channel->name, user_level_name_from_level(actee->access));
+        return 0;
     }
 
     time_t accessexpiry = 0;
@@ -3220,34 +3222,34 @@ static CHANSERV_FUNC(cmd_clvl)
 
     if(handle == user->handle_info && !privileged)
     {
-       reply("CSMSG_NO_SELF_CLVL");
-       return 0;
+        reply("CSMSG_NO_SELF_CLVL");
+        return 0;
     }
 
     if(!(victim = GetTrueChannelAccess(channel->channel_info, handle)))
     {
-       reply("CSMSG_NO_CHAN_USER", handle->handle, channel->name);
-       return 0;
+        reply("CSMSG_NO_CHAN_USER", handle->handle, channel->name);
+        return 0;
     }
 
     if(actor->access <= victim->access && !privileged)
     {
-       reply("MSG_USER_OUTRANKED", handle->handle);
-       return 0;
+        reply("MSG_USER_OUTRANKED", handle->handle);
+        return 0;
     }
 
     new_access = user_level_from_name(argv[2], UL_OWNER);
 
     if(!new_access)
     {
-       reply("CSMSG_INVALID_ACCESS", argv[2]);
-       return 0;
+        reply("CSMSG_INVALID_ACCESS", argv[2]);
+        return 0;
     }
 
     if(new_access >= actor->access && !privileged)
     {
-       reply("CSMSG_NO_BUMP_ACCESS");
-       return 0;
+        reply("CSMSG_NO_BUMP_ACCESS");
+        return 0;
     }
 
     time_t clvlexpiry = 0;
@@ -3288,6 +3290,7 @@ static CHANSERV_FUNC(cmd_deluser)
     struct userData *victim;
     struct userData *actor, *real_actor;
     unsigned short access_level, override = 0;
+    unsigned short access_level_user = 0;
     char *chan_name;
 
     REQUIRE_PARAMS(2);
@@ -3300,24 +3303,25 @@ static CHANSERV_FUNC(cmd_deluser)
 
     if(!(victim = GetTrueChannelAccess(channel->channel_info, handle)))
     {
-       reply("CSMSG_NO_CHAN_USER", handle->handle, channel->name);
-       return 0;
+        reply("CSMSG_NO_CHAN_USER", handle->handle, channel->name);
+        return 0;
     }
 
     if(argc > 2)
     {
         access_level = user_level_from_name(argv[1], UL_OWNER);
         char *useraccess = user_level_name_from_level(victim->access);
+        access_level_user = user_level_from_name(useraccess, UL_OWNER);
         if(!access_level)
         {
             reply("CSMSG_INVALID_ACCESS", argv[1]);
             return 0;
         }
-       if(strcasecmp(argv[1], useraccess))
-       {
-           reply("CSMSG_INCORRECT_ACCESS", handle->handle, user_level_name_from_level(victim->access), argv[1]);
-           return 0;
-       }
+        if(access_level != access_level_user)
+        {
+            reply("CSMSG_INCORRECT_ACCESS", handle->handle, useraccess, argv[1]);
+            return 0;
+        }
     }
     else
     {
@@ -3326,8 +3330,8 @@ static CHANSERV_FUNC(cmd_deluser)
 
     if((actor->access <= victim->access) && !IsHelping(user))
     {
-       reply("MSG_USER_OUTRANKED", victim->handle->handle);
-       return 0;
+        reply("MSG_USER_OUTRANKED", victim->handle->handle);
+        return 0;
     }
 
     /* If people delete themselves it is an override, but they could've used deleteme so we don't log it as an override */
@@ -3358,8 +3362,8 @@ cmd_mdel_user(struct userNode *user, struct chanNode *channel, unsigned short mi
 
     if((actor->access <= max_access) && !IsHelping(user))
     {
-       reply("CSMSG_NO_ACCESS");
-       return 0;
+    reply("CSMSG_NO_ACCESS");
+    return 0;
     }
 
     if(!real_actor || real_actor->access <= max_access)
@@ -3367,12 +3371,14 @@ cmd_mdel_user(struct userNode *user, struct chanNode *channel, unsigned short mi
 
     for(uData = channel->channel_info->users; uData; uData = next)
     {
-       next = uData->next;
+        next = uData->next;
 
-       if((uData->access >= min_access)
-           && (uData->access <= max_access)
-           && match_ircglob(uData->handle->handle, mask))
-           del_channel_user(uData, 1);
+        if((uData->access >= min_access) 
+               && (uData->access <= max_access)
+               && match_ircglob(uData->handle->handle, mask))
+        {
+            del_channel_user(uData, 1);
+        }
     }
 
     reply("CSMSG_DELETED_USERS", mask, min_access, max_access, channel->name);
@@ -3493,7 +3499,7 @@ cmd_trim_bans(struct svccmd *cmd, struct userNode *user, struct chanNode *channe
     limit = now - duration;
     for(bData = channel->channel_info->bans; bData; bData = next)
     {
-       next = bData->next;
+        next = bData->next;
 
         if((bData->triggered && bData->triggered >= limit) || (bData->set && bData->set >= limit))
             continue;
@@ -3524,27 +3530,27 @@ cmd_trim_users(struct svccmd *cmd, struct userNode *user, struct chanNode *chann
 
     if(!actor || actor->access <= max_access)
     {
-       reply("CSMSG_NO_ACCESS");
-       return 0;
+        reply("CSMSG_NO_ACCESS");
+        return 0;
     }
 
     count = 0;
     limit = now - duration;
     for(uData = channel->channel_info->users; uData; uData = next)
     {
-       next = uData->next;
+        next = uData->next;
 
-       if((uData->seen > limit)
+        if((uData->seen > limit)
            || uData->present
            || (HANDLE_FLAGGED(uData->handle, FROZEN) && !vacation))
-           continue;
+        continue;
 
-       if(((uData->access >= min_access) && (uData->access <= max_access))
-           || (!max_access && (uData->access < actor->access)))
-       {
-           del_channel_user(uData, 1);
-           count++;
-       }
+        if(((uData->access >= min_access) && (uData->access <= max_access))
+               || (!max_access && (uData->access < actor->access)))
+        {
+            del_channel_user(uData, 1);
+            count++;
+        }
     }
 
     if(!max_access)
@@ -3568,29 +3574,29 @@ static CHANSERV_FUNC(cmd_trim)
     duration = ParseInterval(argv[2]);
     if(duration < 60)
     {
-       reply("CSMSG_CANNOT_TRIM");
-       return 0;
+        reply("CSMSG_CANNOT_TRIM");
+        return 0;
     }
 
     if(!irccasecmp(argv[1], "lamers"))
     {
-       cmd_trim_bans(cmd, user, channel, duration); /* trim_lamers.. */
-       return 1;
+        cmd_trim_bans(cmd, user, channel, duration); /* trim_lamers.. */
+        return 1;
     }
     else if(!irccasecmp(argv[1], "users"))
     {
-       cmd_trim_users(cmd, user, channel, 0, 0, duration, vacation);
-       return 1;
+        cmd_trim_users(cmd, user, channel, 0, 0, duration, vacation);
+        return 1;
     }
     else if(parse_level_range(&min_level, &max_level, argv[1]))
     {
-       cmd_trim_users(cmd, user, channel, min_level, max_level, duration, vacation);
-       return 1;
+        cmd_trim_users(cmd, user, channel, min_level, max_level, duration, vacation);
+        return 1;
     }
     else if((min_level = user_level_from_name(argv[1], UL_OWNER)))
     {
-       cmd_trim_users(cmd, user, channel, min_level, min_level, duration, vacation);
-       return 1;
+        cmd_trim_users(cmd, user, channel, min_level, min_level, duration, vacation);
+        return 1;
     }
     else
     {
@@ -3614,7 +3620,7 @@ static CHANSERV_FUNC(cmd_up)
     {
         if(argc)
             reply("MSG_CHANNEL_ABSENT", channel->name);
-       return 0;
+        return 0;
     }
 
     uData = GetChannelAccess(channel->channel_info, user->handle_info);
@@ -3667,14 +3673,14 @@ static CHANSERV_FUNC(cmd_down)
     {
         if(argc)
             reply("MSG_CHANNEL_ABSENT", channel->name);
-       return 0;
+    return 0;
     }
 
     if(!change.args[0].u.member->modes)
     {
         if(argc)
             reply("CSMSG_ALREADY_DOWN", channel->name);
-       return 0;
+    return 0;
     }
 
     change.args[0].mode = MODE_REMOVE | change.args[0].u.member->modes;
@@ -3688,12 +3694,12 @@ static int cmd_all(struct userNode *user, UNUSED_ARG(struct chanNode *channel),
 
     for(cList = user->handle_info->channels; cList; cList = cList->u_next)
     {
-       if(IsSuspended(cList->channel)
-           || IsUserSuspended(cList)
-           || !GetUserMode(cList->channel->channel, user))
-           continue;
+        if(IsSuspended(cList->channel)
+               || IsUserSuspended(cList)
+               || !GetUserMode(cList->channel->channel, user))
+            continue;
 
-       mcmd(user, cList->channel->channel, 0, NULL, cmd);
+        mcmd(user, cList->channel->channel, 0, NULL, cmd);
     }
 
     return 1;
@@ -3723,20 +3729,20 @@ modify_users(struct userNode *user, struct chanNode *channel, unsigned int argc,
 
     for(ii=valid=0; ++ii < argc; )
     {
-       if(!(victim = GetUserH(argv[ii])))
+        if(!(victim = GetUserH(argv[ii])))
             continue;
         change->args[valid].mode = mode;
         change->args[valid].u.member = GetUserMode(channel, victim);
         if(!change->args[valid].u.member)
             continue;
         if(validate && !validate(cmd, user, channel, victim))
-           continue;
+        continue;
         valid++;
     }
 
     change->argc = valid;
     if(valid < (argc-1))
-       reply("CSMSG_PROCESS_FAILED");
+    reply("CSMSG_PROCESS_FAILED");
     if(valid)
     {
         modcmd_chanmode_announce(change);
@@ -3780,6 +3786,7 @@ static int
 bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban, unsigned int *victimCount, struct modeNode **victims)
 {
     unsigned int ii;
+    int b = 0;
 
     if(victimCount)
         *victimCount = 0;
@@ -3790,7 +3797,10 @@ bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban
         if(IsService(mn->user))
             continue;
 
-        if(!user_matches_glob(mn->user, ban, MATCH_USENICK | MATCH_VISIBLE))
+        b = user_matches_glob(mn->user, ban, MATCH_USENICK | MATCH_VISIBLE, 0);
+        if (b == -1)
+            return -1;
+        else if (b == 0)
             continue;
 
         if(protect_user(mn->user, user, channel->channel_info, false))
@@ -3802,12 +3812,20 @@ bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban
     return 0;
 }
 
+int is_extban(char *b) {
+    if(*b == '~') {
+        return 1;
+    }
+    return 0;
+}
+
 static int
 eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, char *argv[], struct svccmd *cmd, int action)
 {
     struct userNode *victim;
     struct modeNode **victims;
     unsigned int offset, n, victimCount, duration = 0;
+    int b = 0;
     char *reason = "Bye.", *ban, *name;
     char interval[INTERVALLEN];
 
@@ -3815,7 +3833,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
     REQUIRE_PARAMS(offset);
     if(argc > offset)
     {
-       reason = unsplit_string(argv + offset, argc - offset, NULL);
+        reason = unsplit_string(argv + offset, argc - offset, NULL);
         if(strlen(reason) > (TOPICLEN - (NICKLEN + 3)))
         {
             /* Truncate the reason to a length of TOPICLEN, as
@@ -3834,33 +3852,33 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
          * want to allow those (e.g.  unbans) in that case.  If we add
          * some other ejection action for in-channel users, change
          * this too. */
-       victimCount = victims[0] ? 1 : 0;
+        victimCount = victims[0] ? 1 : 0;
 
-       if(IsService(victim))
-       {
-           if(cmd)
-               reply("MSG_SERVICE_IMMUNE", victim->nick);
-           return 0;
-       }
+        if(IsService(victim))
+        {
+            if(cmd)
+                reply("MSG_SERVICE_IMMUNE", victim->nick);
+            return 0;
+        }
 
         if((action == ACTION_KICK) && !victimCount)
         {
-           if(cmd)
-               reply("MSG_CHANNEL_USER_ABSENT", victim->nick, channel->name);
+            if(cmd)
+                reply("MSG_CHANNEL_USER_ABSENT", victim->nick, channel->name);
             return 0;
         }
 
-       if(protect_user(victim, user, channel->channel_info, false))
-       {
-           // This translates to  send_message(user, cmd->parent->bot, ...)
-           // if user is x3 (ctcp action) cmd is null and segfault.
-           if(cmd)
-               reply("CSMSG_USER_PROTECTED", victim->nick);
-           return 0;
-       }
+        if(protect_user(victim, user, channel->channel_info, false))
+        {
+            // This translates to  send_message(user, cmd->parent->bot, ...)
+            // if user is x3 (ctcp action) cmd is null and segfault.
+            if(cmd)
+                reply("CSMSG_USER_PROTECTED", victim->nick);
+            return 0;
+        }
 
-       ban = generate_hostmask(victim, GENMASK_STRICT_HOST|GENMASK_ANY_IDENT);
-       name = victim->nick;
+        ban = generate_hostmask(victim, GENMASK_STRICT_HOST|GENMASK_ANY_IDENT);
+        name = victim->nick;
     }
     else if(!is_ircmask(argv[1]) && (*argv[1] == '*'))
     {
@@ -3877,11 +3895,17 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
         snprintf(banmask, sizeof(banmask), "*!*@%s.*", hi->handle);
         victims = alloca(sizeof(victims[0]) * channel->members.used);
 
-        if(bad_channel_ban(channel, user, banmask, &victimCount, victims))
+        b = bad_channel_ban(channel, user, banmask, &victimCount, victims);
+        if(b == 1)
         {
             reply("CSMSG_MASK_PROTECTED", banmask);
             return 0;
         }
+        else if(b == -1)
+        {
+            reply("CSMSG_BAD_BAN", banmask);
+            return 0;
+        }
 
         if((action == ACTION_KICK) && (victimCount == 0))
         {
@@ -3893,21 +3917,24 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
     }
     else
     {
-       if(!is_ircmask(argv[1]))
-       {
-           if(cmd)
-              reply("MSG_NICK_UNKNOWN", argv[1]);
-           return 0;
-       }
+        if(!is_ircmask(argv[1]))
+        {
+            if(cmd)
+               reply("MSG_NICK_UNKNOWN", argv[1]);
+            return 0;
+        }
 
-       victims = alloca(sizeof(victims[0]) * channel->members.used);
+        victims = alloca(sizeof(victims[0]) * channel->members.used);
 
-        if(bad_channel_ban(channel, user, argv[1], &victimCount, victims))
-        {
-           if(cmd)
-               reply("CSMSG_MASK_PROTECTED", argv[1]);
-           return 0;
-       }
+        b = bad_channel_ban(channel, user, argv[1], &victimCount, victims);
+        if(cmd && (b == 1)) {
+            reply("CSMSG_MASK_PROTECTED", argv[1]);
+            return 0;
+        }
+        else if(cmd && (b == -1)) {
+            reply("CSMSG_BAD_BAN", argv[1]);
+            return 0;
+        }
 /* If i want to ban *.nl and theres 5 of them, what is it to the bot?!? 
 //      if((victimCount > 4) && ((victimCount * 3) > channel->members.used) && !IsOper(user)) 
                                                                            And, ^^^^^^^^^ BAH! 
@@ -3916,133 +3943,141 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
    some creativity, but its not x3's job to be the ban censor anyway.  */
         if(is_overmask(argv[1]))
         {
-           if(cmd)
+            if(cmd)
                 reply("CSMSG_LAME_MASK", argv[1]);
             return 0;
         }
+        //TODO: We have no support to do protection etc etc so for now we dont let you use x3 to set extended bans.
+        if(is_extban(argv[1]))
+        {
+            if(cmd)
+                reply("CSMSG_NO_EXTBANS", argv[1]);
+            return 0;
+        }
 
         if((action == ACTION_KICK) && (victimCount == 0))
         {
-           if(cmd)
+            if(cmd)
                 reply("CSMSG_NO_MATCHING_USERS", channel->name, argv[1]);
             return 0;
         }
 
-       name = ban = strdup(argv[1]);
+        name = ban = strdup(argv[1]);
     }
 
     /* Truncate the ban in place if necessary; we must ensure
        that 'ban' is a valid ban mask before sanitizing it. */
-    sanitize_ircmask(ban);
+    if (*ban != '~')
+        sanitize_ircmask(ban);
 
     if(action & ACTION_ADD_LAMER)
     {
-       struct banData *bData, *next;
-
-       if(channel->channel_info->banCount >= chanserv_conf.max_chan_bans) /* ..lamers.. */
-       {
-           if(cmd)
-               reply("CSMSG_MAXIMUM_LAMERS", chanserv_conf.max_chan_bans); /* ..lamers.. */
-           free(ban);
-           return 0;
-       }
-
-       if(action & ACTION_ADD_TIMED_LAMER)
-       {
-           duration = ParseInterval(argv[2]);
-
-           if(duration < 15)
-           {
-               if(cmd)
-                   reply("CSMSG_DURATION_TOO_LOW");
-               free(ban);
-               return 0;
-           }
-           else if(duration > (86400 * 365 * 2))
-           {
-               if(cmd)
-                   reply("CSMSG_DURATION_TOO_HIGH");
-               free(ban);
-               return 0;
-           }
-       }
+        struct banData *bData, *next;
+
+        if(channel->channel_info->banCount >= chanserv_conf.max_chan_bans) /* ..lamers.. */
+        {
+            if(cmd)
+                reply("CSMSG_MAXIMUM_LAMERS", chanserv_conf.max_chan_bans); /* ..lamers.. */
+            free(ban);
+            return 0;
+        }
+
+        if(action & ACTION_ADD_TIMED_LAMER)
+        {
+            duration = ParseInterval(argv[2]);
+
+            if(duration < 15)
+            {
+                if(cmd)
+                    reply("CSMSG_DURATION_TOO_LOW");
+                free(ban);
+                return 0;
+            }
+            else if(duration > (86400 * 365 * 2))
+            {
+                if(cmd)
+                    reply("CSMSG_DURATION_TOO_HIGH");
+                free(ban);
+                return 0;
+            }
+        }
 
         /* lamers... */
-       for(bData = channel->channel_info->bans; bData; bData = next)
-       {
-           if(match_ircglobs(bData->mask, ban))
-           {
-               int exact = !irccasecmp(bData->mask, ban);
-
-               /* The ban is redundant; there is already a ban
-                  with the same effect in place. */
-               if(exact)
-               {
-                   if(bData->reason)
+        for(bData = channel->channel_info->bans; bData; bData = next)
+        {
+            if(match_ircglobs(bData->mask, ban))
+            {
+                int exact = !irccasecmp(bData->mask, ban);
+
+                /* The ban is redundant; there is already a ban
+                   with the same effect in place. */
+                if(exact)
+                {
+                    if(bData->reason)
                         free(bData->reason);
-                   bData->reason = strdup(reason);
+                    bData->reason = strdup(reason);
                     safestrncpy(bData->owner, (user->handle_info ? user->handle_info->handle : user->nick), sizeof(bData->owner));
                     if(cmd)
                         reply("CSMSG_REASON_CHANGE", ban);
-                   if(!bData->expires)
+                    if(!bData->expires)
                         goto post_add_ban;
-               }
-               if(exact && bData->expires)
-               {
-                   int reset = 0;
-
-                   /* If the ban matches an existing one exactly,
-                      extend the expiration time if the provided
-                      duration is longer. */
-                   if(duration && ((time_t)(now + duration) > bData->expires))
-                   {
-                       bData->expires = now + duration;
-                       reset = 1;
-                   }
-                   else if(!duration)
-                   {
-                       bData->expires = 0;
-                       reset = 1;
-                   }
-
-                   if(reset)
-                   {
-                       /* Delete the expiration timeq entry and
-                          requeue if necessary. */
-                       timeq_del(0, expire_ban, bData, TIMEQ_IGNORE_WHEN);
-
-                       if(bData->expires)
-                           timeq_add(bData->expires, expire_ban, bData);
+                }
+                if(exact && bData->expires)
+                {
+                    int reset = 0;
+
+                    /* If the ban matches an existing one exactly,
+                       extend the expiration time if the provided
+                       duration is longer. */
+                    if(duration && ((time_t)(now + duration) > bData->expires))
+                    {
+                        bData->expires = now + duration;
+                        reset = 1;
+                    }
+                    else if(!duration)
+                    {
+                        bData->expires = 0;
+                        reset = 1;
+                    }
+
+                    if(reset)
+                    {
+                        /* Delete the expiration timeq entry and
+                           requeue if necessary. */
+                        timeq_del(0, expire_ban, bData, TIMEQ_IGNORE_WHEN);
+
+                        if(bData->expires)
+                            timeq_add(bData->expires, expire_ban, bData);
 
                         if(!cmd)
                         {
-                            /* automated kickban, dont reply */
+                                /* automated kickban, dont reply */
                         }
-                       else if(duration)
-                           reply("CSMSG_LAMER_EXTENDED", ban, intervalString(interval, duration, user->handle_info));
-                       else
-                           reply("CSMSG_LAMER_ADDED", name, channel->name);
-
-                       goto post_add_ban;
-                   }
-               }
+                        else if(duration)
+                            reply("CSMSG_LAMER_EXTENDED", ban, intervalString(interval, duration, user->handle_info));
+                        else
+                            reply("CSMSG_LAMER_ADDED", name, channel->name);
+
+                        goto post_add_ban;
+                    }
+                }
                 if(cmd)
                     reply("CSMSG_REDUNDANT_LAMER", name, channel->name);
 
-               free(ban);
-               return 0;
-           }
+                free(ban);
+                return 0;
+            }
 
-           next = bData->next;
-           if(match_ircglobs(ban, bData->mask))
-           {
-               /* The ban we are adding makes previously existing
-                  bans redundant; silently remove them. */
-               del_channel_ban(bData);
-           }
-       }
+            next = bData->next;
+            if(match_ircglobs(ban, bData->mask))
+            {
+                /* The ban we are adding makes previously existing
+                   bans redundant; silently remove them. */
+                del_channel_ban(bData);
+            }
+        }
 
-       bData = add_channel_ban(channel->channel_info, ban, (user->handle_info ? user->handle_info->handle : user->nick), now, (victimCount ? now : 0), (duration ? now + duration : 0), reason);
+        bData = add_channel_ban(channel->channel_info, ban, (user->handle_info ? user->handle_info->handle : user->nick), now, (victimCount ? now : 0), (duration ? now + duration : 0), reason);
         free(ban);
         name = ban = strdup(bData->mask);
     }
@@ -4069,19 +4104,19 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
         }
     }
 
-  post_add_ban:
+    post_add_ban:
     if(action & ACTION_BAN)
     {
-       unsigned int exists;
+        unsigned int exists;
         struct mod_chanmode *change;
 
-       if(channel->banlist.used >= MAXBANS)
-       {
+        if(channel->banlist.used >= MAXBANS)
+        {
             if(cmd)
                 reply("CSMSG_BANLIST_FULL", channel->name);
-           free(ban);
-           return 0;
-       }
+            free(ban);
+            return 0;
+        }
 
         exists = ChannelBanExists(channel, ban);
         change = mod_chanmode_alloc(victimCount + 1);
@@ -4103,7 +4138,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
         mod_chanmode_free(change);
 
         if(exists && (action == ACTION_BAN))
-       {
+        {
             if(cmd)
                 reply("CSMSG_REDUNDANT_BAN", name, channel->name);
             free(ban);
@@ -4114,21 +4149,24 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
     if(action & ACTION_ADD_LAMER)
     {
         char kick_reason[MAXLEN];
-       sprintf(kick_reason, "(%s) %s", user->nick, reason);
+        sprintf(kick_reason, "(%s) %s", user->nick, reason);
 
-       for(n = 0; n < victimCount; n++) {
-            if(!protect_user(victims[n]->user, user, channel->channel_info, true)) {
-               KickChannelUser(victims[n]->user, channel, chanserv, kick_reason);
+        for(n = 0; n < victimCount; n++) 
+        {
+            if(!protect_user(victims[n]->user, user, channel->channel_info, true)) 
+            {
+                KickChannelUser(victims[n]->user, channel, chanserv, kick_reason);
             }
         }
     }
     else if(action & ACTION_KICK)
     {
         char kick_reason[MAXLEN];
-       sprintf(kick_reason, "(%s) %s", user->nick, reason);
+        sprintf(kick_reason, "(%s) %s", user->nick, reason);
 
-       for(n = 0; n < victimCount; n++) {
-           KickChannelUser(victims[n]->user, channel, chanserv, kick_reason);
+        for(n = 0; n < victimCount; n++) 
+        {
+            KickChannelUser(victims[n]->user, channel, chanserv, kick_reason);
         }
     }
 
@@ -4138,17 +4176,17 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
     }
     else if(action & ACTION_ADD_LAMER)
     {
-       if(duration)
-           reply("CSMSG_TIMED_LAMER_ADDED", name, channel->name, intervalString(interval, duration, user->handle_info));
-       else
-           reply("CSMSG_LAMER_ADDED", name, channel->name);
+        if(duration)
+            reply("CSMSG_TIMED_LAMER_ADDED", name, channel->name, intervalString(interval, duration, user->handle_info));
+        else
+            reply("CSMSG_LAMER_ADDED", name, channel->name);
     }
     else if((action & (ACTION_BAN | ACTION_KICK)) == (ACTION_BAN | ACTION_KICK))
-       reply("CSMSG_KICK_BAN_DONE", name, channel->name);
+        reply("CSMSG_KICK_BAN_DONE", name, channel->name);
     else if(action & ACTION_BAN)
-       reply("CSMSG_BAN_DONE", name, channel->name);
+        reply("CSMSG_BAN_DONE", name, channel->name);
     else if(action & ACTION_KICK && victimCount)
-       reply("CSMSG_KICK_DONE", name, channel->name);
+        reply("CSMSG_KICK_DONE", name, channel->name);
 
     free(ban);
     return 1;
@@ -4192,7 +4230,7 @@ find_matching_bans(struct banList *bans, struct userNode *actee, const char *mas
         for(ii = count = 0; ii < bans->used; ++ii)
         {
             match[ii] = user_matches_glob(actee, bans->list[ii]->ban,
-                                          MATCH_USENICK | MATCH_VISIBLE);
+                                          MATCH_USENICK | MATCH_VISIBLE, 0);
             if(match[ii])
                 count++;
         }
@@ -4243,7 +4281,8 @@ void expire_bans(UNUSED_ARG(void* data)) /* Real bans, not lamers */
         count = 0;
         /* First find out how many bans were going to unset */
         for (jj=0; jj < channel->channel->banlist.used; ++jj) {
-            if(channel->channel->banlist.list[jj]->set < bantimeout)
+            //TODO: for now, were just not removing extended bans, but ultimately some types we should, some shouldn't...see below
+            if(channel->channel->banlist.list[jj]->set < bantimeout && !is_extban(channel->channel->banlist.list[jj]->ban))
                 count++;
         }
         if(count > 0) {
@@ -4253,7 +4292,8 @@ void expire_bans(UNUSED_ARG(void* data)) /* Real bans, not lamers */
             /* Walk over every ban in this channel.. */
             for (jj=0; jj < channel->channel->banlist.used; ++jj) {
                 bn = channel->channel->banlist.list[jj];
-                if (bn->set < bantimeout) {
+                //TODO: for now, were just not removing extended bans, but ultimately some types we should, some shouldn't...see above
+                if (bn->set < bantimeout && !is_extban(bn->ban)) {
                     log_module(CS_LOG, LOG_DEBUG, "Removing ban %s from %s", bn->ban, channel->channel->name);
 
                     /* Add this ban to the mode change */
@@ -4303,10 +4343,10 @@ unban_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
             mask = strdup(banmask);
         }
         else if(!is_ircmask(argv[1]))
-       {
-           reply("MSG_NICK_UNKNOWN", argv[1]);
-           return 0;
-       }
+        {
+            reply("MSG_NICK_UNKNOWN", argv[1]);
+            return 0;
+        }
         else
         {
             mask = strdup(argv[1]);
@@ -4333,30 +4373,30 @@ unban_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
 
     if(action & ACTION_DEL_LAMER)
     {
-       struct banData *ban, *next;
-
-       ban = channel->channel_info->bans; /* lamers */
-       while(ban)
-       {
-           if(actee)
-               for( ; ban && !user_matches_glob(actee, ban->mask, MATCH_USENICK | MATCH_VISIBLE);
-                    ban = ban->next);
-           else
-               for( ; ban && !match_ircglobs(mask, ban->mask);
-                    ban = ban->next);
-           if(!ban)
-                break;
-           next = ban->next;
-           del_channel_ban(ban);
-           ban = next;
-           acted = 1;
-       }
+        struct banData *ban, *next;
+
+        ban = channel->channel_info->bans; /* lamers */
+        while(ban)
+        {
+            if(actee)
+                   for( ; ban && !user_matches_glob(actee, ban->mask, MATCH_USENICK | MATCH_VISIBLE, 0);
+                 ban = ban->next);
+            else
+            for( ; ban && !match_ircglobs(mask, ban->mask);
+                 ban = ban->next);
+            if(!ban)
+                    break;
+            next = ban->next;
+            del_channel_ban(ban);
+            ban = next;
+            acted = 1;
+        }
     }
 
     if(!acted)
-       reply("CSMSG_BAN_NOT_FOUND", actee ? actee->nick : mask);
+        reply("CSMSG_BAN_NOT_FOUND", actee ? actee->nick : mask);
     else
-       reply("CSMSG_BAN_REMOVED", actee ? actee->nick : mask);
+        reply("CSMSG_BAN_REMOVED", actee ? actee->nick : mask);
     if(mask)
         free(mask);
     return 1;
@@ -4381,7 +4421,7 @@ static CHANSERV_FUNC(cmd_unbanme)
 
     /* remove permanent bans if the user has the proper access. */
     if(uData->access >= UL_MANAGER)
-       flags |= ACTION_DEL_LAMER;
+    flags |= ACTION_DEL_LAMER;
 
     argv[1] = user->nick;
     return unban_user(user, channel, 2, argv, cmd, flags);
@@ -4394,10 +4434,11 @@ static CHANSERV_FUNC(cmd_unbanall)
 
     if(!channel->banlist.used)
     {
-       reply("CSMSG_NO_BANS", channel->name);
-       return 0;
+        reply("CSMSG_NO_BANS", channel->name);
+        return 0;
     }
 
+    // TODO: dont remove some kinds of extended bans such as ~c
     change = mod_chanmode_alloc(channel->banlist.used);
     for(ii=0; ii<channel->banlist.used; ii++)
     {
@@ -4470,7 +4511,7 @@ static CHANSERV_FUNC(cmd_myaccess)
             continue;
         sbuf.used = 0;
         string_buffer_append_printf(&sbuf, "[%s (%d", cData->channel->name, uData->access);
-        if(uData->flags == USER_AUTO_OP)
+        if(uData->flags != 0)
             string_buffer_append(&sbuf, ',');
         if(IsUserSuspended(uData))
             string_buffer_append(&sbuf, 's');
@@ -4508,7 +4549,7 @@ static CHANSERV_FUNC(cmd_access)
 
     if(argc < 2)
     {
-       target = user;
+    target = user;
         target_handle = target->handle_info;
     }
     else if((target = GetUserH(argv[1])))
@@ -4533,8 +4574,8 @@ static CHANSERV_FUNC(cmd_access)
 
     if(target == chanserv)
     {
-       reply("CSMSG_IS_CHANSERV");
-       return 1;
+        reply("CSMSG_IS_CHANSERV");
+        return 1;
     }
 
     if(!target_handle)
@@ -4544,13 +4585,13 @@ static CHANSERV_FUNC(cmd_access)
             reply("CSMSG_LAZY_SMURF_TARGET", target->nick, chanserv_conf.irc_operator_epithet);
             return 0;
         }
-       if(target != user)
-       {
-           reply("MSG_USER_AUTHENTICATE", target->nick);
-           return 0;
-       }
-        reply("MSG_AUTHENTICATE");
-        return 0;
+        if(target != user)
+        {
+            reply("MSG_USER_AUTHENTICATE", target->nick);
+            return 0;
+        }
+            reply("MSG_AUTHENTICATE");
+            return 0;
     }
 
     if(target)
@@ -4803,11 +4844,11 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg
     matches = 0;
     for(uData = channel->channel_info->users; uData; uData = uData->next)
     {
-       if((uData->access < lowest)
-           || (uData->access > highest)
-           || (lData.search && !match_ircglob(uData->handle->handle, lData.search)))
-           continue;
-       lData.users[matches++] = uData;
+        if((uData->access < lowest)
+               || (uData->access > highest)
+               || (lData.search && !match_ircglob(uData->handle->handle, lData.search)))
+            continue;
+        lData.users[matches++] = uData;
     }
     qsort(lData.users, matches, sizeof(lData.users[0]), userData_access_comp);
 
@@ -4874,7 +4915,7 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg
            break;
             }
         }
-     else {
+        else {
            ary[i++] = user_level_name_from_level(uData->access);
         }
         ary[i++] = uData->handle->handle;
@@ -4905,7 +4946,8 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg
                 intervalString(delay, diff, user->handle_info);
             }
             ary[i++] = delay;
-        } else
+        } 
+        else
             ary[i++] = "Never";
     }
 
@@ -4983,7 +5025,7 @@ static CHANSERV_FUNC(cmd_lamers)
         search = NULL;
     else if(strchr(search = argv[1], '!'))
     {
-       search = argv[1];
+        search = argv[1];
         search_wilds = search[strcspn(search, "?*")];
     }
     else if(!(search_u = GetUserH(search)))
@@ -4997,16 +5039,16 @@ static CHANSERV_FUNC(cmd_lamers)
     {
         if(search_u)
         {
-            if(!user_matches_glob(search_u, ban->mask, MATCH_USENICK | MATCH_VISIBLE))
+            if(!user_matches_glob(search_u, ban->mask, MATCH_USENICK | MATCH_VISIBLE, 0))
                 continue;
         }
-       else if(search)
+        else if(search)
         {
             if(search_wilds ? !match_ircglobs(search, ban->mask) : !match_ircglob(search, ban->mask))
                 continue;
         }
-       bans[matches++] = ban;
-       if(ban->expires)
+        bans[matches++] = ban;
+        if(ban->expires)
             timed = 1;
     }
 
@@ -5029,28 +5071,28 @@ static CHANSERV_FUNC(cmd_lamers)
     if(!matches)
     {
         table_send(cmd->parent->bot, user->nick, 0, NULL, tbl);
-/*     reply("MSG_NONE"); */
+        /*  reply("MSG_NONE"); */
         free(tbl.contents[0]);
         free(tbl.contents);
-       return 0;
+        return 0;
     }
 
     msg_never = user_find_message(user, "MSG_NEVER");
     for(ii = 0; ii < matches; )
     {
-       ban = bans[ii];
+        ban = bans[ii];
 
-       if(!timed)
-           expires = "";
-       else if(ban->expires)
-           expires = intervalString(e_buffer, ban->expires - now, user->handle_info);
-       else
-           expires = msg_never;
+        if(!timed)
+            expires = "";
+        else if(ban->expires)
+            expires = intervalString(e_buffer, ban->expires - now, user->handle_info);
+        else
+            expires = msg_never;
 
-       if(ban->triggered)
-           triggered = intervalString(t_buffer, now - ban->triggered, user->handle_info);
-       else
-           triggered = msg_never;
+        if(ban->triggered)
+            triggered = intervalString(t_buffer, now - ban->triggered, user->handle_info);
+        else
+            triggered = msg_never;
 
         tbl.contents[++ii] = malloc(tbl.width * sizeof(tbl.contents[0][0]));
         tbl.contents[ii][0] = ban->mask;
@@ -5219,18 +5261,20 @@ static CHANSERV_FUNC(cmd_mode)
     
     if(argc < 2)
     {
-        if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(user)) {
+        if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(user)) 
+        {
             reply("CSMSG_DEFCON_NO_MODE_CHANGE");
             return 0;
         }
 
         change = &channel->channel_info->modes;
-       if(change->modes_set || change->modes_clear) {
+        if(change->modes_set || change->modes_clear) {
             modcmd_chanmode_announce(change);
             reply("CSMSG_DEFAULTED_MODES", channel->name);
-       } else
-           reply("CSMSG_NO_MODES", channel->name);
-       return 1;
+        } 
+        else
+            reply("CSMSG_NO_MODES", channel->name);
+        return 1;
     }
 
     uData = GetChannelUser(channel->channel_info, user->handle_info);
@@ -5244,8 +5288,8 @@ static CHANSERV_FUNC(cmd_mode)
 
     if(!change)
     {
-       reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
-       return 0;
+        reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
+        return 0;
     }
 
     if(!check_user_level(channel, user, lvlEnfModes, 1, 0)
@@ -5265,15 +5309,15 @@ static CHANSERV_FUNC(cmd_mode)
 
 static CHANSERV_FUNC(cmd_invite)
 {
-    struct userData *uData;
+    //struct userData *uData;
     struct userNode *invite;
 
-    uData = GetChannelUser(channel->channel_info, user->handle_info);
+    //uData = GetChannelUser(channel->channel_info, user->handle_info);
 
     if(argc > 1)
     {
         if(!(invite = GetUserH(argv[1])))
-       {
+        {
             reply("MSG_NICK_UNKNOWN", argv[1]);
             return 0;
         }
@@ -5283,8 +5327,8 @@ static CHANSERV_FUNC(cmd_invite)
 
     if(GetUserMode(channel, invite))
     {
-       reply("CSMSG_ALREADY_PRESENT", invite->nick, channel->name);
-       return 0;
+        reply("CSMSG_ALREADY_PRESENT", invite->nick, channel->name);
+        return 0;
     }
 
     if(user != invite)
@@ -5300,17 +5344,19 @@ static CHANSERV_FUNC(cmd_invite)
 
     if (invite->handle_info && invite->handle_info->ignores->used && (argc > 1)) {
         unsigned int i;
-        for (i=0; i < invite->handle_info->ignores->used; i++) {
-            if (user_matches_glob(user, invite->handle_info->ignores->list[i], MATCH_USENICK)) {
-              reply("CSMSG_CANNOT_INVITE", argv[1], channel->name);
-              return 0;
+        for (i=0; i < invite->handle_info->ignores->used; i++) 
+        {
+            if (user_matches_glob(user, invite->handle_info->ignores->list[i], MATCH_USENICK, 0)) 
+            {
+                reply("CSMSG_CANNOT_INVITE", argv[1], channel->name);
+                return 0;
             }
         }
     }
 
     irc_invite(chanserv, invite, channel);
     if(argc > 1)
-       reply("CSMSG_INVITED_USER", argv[1], channel->name);
+        reply("CSMSG_INVITED_USER", argv[1], channel->name);
 
     return 1;
 }
@@ -5319,8 +5365,8 @@ static CHANSERV_FUNC(cmd_inviteme)
 {
     if(GetUserMode(channel, user))
     {
-       reply("CSMSG_YOU_ALREADY_PRESENT", channel->name);
-       return 0;
+    reply("CSMSG_YOU_ALREADY_PRESENT", channel->name);
+    return 0;
     }
     if(channel->channel_info
        && !check_user_level(channel, user, lvlInviteMe, 1, 0))
@@ -5347,43 +5393,43 @@ show_suspension_info(struct svccmd *cmd, struct userNode *user, struct suspended
     combo = (suspended->issued ? 4 : 0)
         + (suspended->revoked ? 3 : suspended->expires ? ((suspended->expires < now) ? 2 : 1) : 0);
     switch(combo) {
-    case 0: /* no issue time, indefinite expiration */
-        reply("CSMSG_CHANNEL_SUSPENDED_0", suspended->suspender, suspended->reason);
-        break;
-    case 1: /* no issue time, expires in future */
-        intervalString(buf1, suspended->expires-now, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_1", suspended->suspender, buf1, suspended->reason);
-        break;
-    case 2: /* no issue time, expired */
-        intervalString(buf1, now-suspended->expires, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_2", suspended->suspender, buf1, suspended->reason);
-        break;
-    case 3: /* no issue time, revoked */
-        intervalString(buf1, now-suspended->revoked, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_3", suspended->suspender, buf1, suspended->reason);
-        break;
-    case 4: /* issue time set, indefinite expiration */
-        intervalString(buf1, now-suspended->issued, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_4", buf1, suspended->suspender, suspended->reason);
-        break;
-    case 5: /* issue time set, expires in future */
-        intervalString(buf1, now-suspended->issued, user->handle_info);
-        intervalString(buf2, suspended->expires-now, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_5", buf1, suspended->suspender, buf2, suspended->reason);
-        break;
-    case 6: /* issue time set, expired */
-        intervalString(buf1, now-suspended->issued, user->handle_info);
-        intervalString(buf2, now-suspended->expires, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_6", buf1, suspended->suspender, buf2, suspended->reason);
-        break;
-    case 7: /* issue time set, revoked */
-        intervalString(buf1, now-suspended->issued, user->handle_info);
-        intervalString(buf2, now-suspended->revoked, user->handle_info);
-        reply("CSMSG_CHANNEL_SUSPENDED_7", buf1, suspended->suspender, buf2, suspended->reason);
-        break;
-    default:
-        log_module(CS_LOG, LOG_ERROR, "Invalid combo value %d in show_suspension_info()", combo);
-        return;
+        case 0: /* no issue time, indefinite expiration */
+            reply("CSMSG_CHANNEL_SUSPENDED_0", suspended->suspender, suspended->reason);
+            break;
+        case 1: /* no issue time, expires in future */
+            intervalString(buf1, suspended->expires-now, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_1", suspended->suspender, buf1, suspended->reason);
+            break;
+        case 2: /* no issue time, expired */
+            intervalString(buf1, now-suspended->expires, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_2", suspended->suspender, buf1, suspended->reason);
+            break;
+        case 3: /* no issue time, revoked */
+            intervalString(buf1, now-suspended->revoked, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_3", suspended->suspender, buf1, suspended->reason);
+            break;
+        case 4: /* issue time set, indefinite expiration */
+            intervalString(buf1, now-suspended->issued, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_4", buf1, suspended->suspender, suspended->reason);
+            break;
+        case 5: /* issue time set, expires in future */
+            intervalString(buf1, now-suspended->issued, user->handle_info);
+            intervalString(buf2, suspended->expires-now, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_5", buf1, suspended->suspender, buf2, suspended->reason);
+            break;
+        case 6: /* issue time set, expired */
+            intervalString(buf1, now-suspended->issued, user->handle_info);
+            intervalString(buf2, now-suspended->expires, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_6", buf1, suspended->suspender, buf2, suspended->reason);
+            break;
+        case 7: /* issue time set, revoked */
+            intervalString(buf1, now-suspended->issued, user->handle_info);
+            intervalString(buf2, now-suspended->revoked, user->handle_info);
+            reply("CSMSG_CHANNEL_SUSPENDED_7", buf1, suspended->suspender, buf2, suspended->reason);
+            break;
+        default:
+            log_module(CS_LOG, LOG_ERROR, "Invalid combo value %d in show_suspension_info()", combo);
+            return;
     }
 }
 
@@ -5431,8 +5477,8 @@ static CHANSERV_FUNC(cmd_info)
     if(uData && (uData->access >= UL_OP /*cData->lvlOpts[lvlGiveOps]*/))
     {
         mod_chanmode_format(&cData->modes, modes);
-       reply("CSMSG_CHANNEL_TOPIC", cData->topic);
-       reply("CSMSG_CHANNEL_MODES", modes[0] ? modes : user_find_message(user, "MSG_NONE"));
+        reply("CSMSG_CHANNEL_TOPIC", cData->topic);
+        reply("CSMSG_CHANNEL_MODES", modes[0] ? modes : user_find_message(user, "MSG_NONE"));
     }
 
     for(it = dict_first(cData->notes); it; it = iter_next(it))
@@ -5456,9 +5502,8 @@ static CHANSERV_FUNC(cmd_info)
     reply("CSMSG_CHANNEL_VISITED", intervalString(buffer, now - cData->visited, user->handle_info));
 
     privileged = IsStaff(user);
-    /* if(privileged) */
-        reply("CSMSG_CHANNEL_REGISTERED", intervalString(buffer, now - cData->registered, user->handle_info));
-    if(/*((uData && uData->access >= UL_COOWNER) || privileged) && */cData->registrar)
+    reply("CSMSG_CHANNEL_REGISTERED", intervalString(buffer, now - cData->registered, user->handle_info));
+    if(cData->registrar)
         reply("CSMSG_CHANNEL_REGISTRAR", cData->registrar);
 
     if(privileged && (dnr = chanserv_is_dnr(channel->name, NULL)))
@@ -5499,7 +5544,7 @@ static CHANSERV_FUNC(cmd_netinfo)
     reply("CSMSG_NETWORK_INFO");
     reply("CSMSG_NETWORK_SERVERS", dict_size(servers));
     reply("CSMSG_NETWORK_USERS", dict_size(clients));
-    reply("CSMSG_NETWORK_OPERS", curr_opers.used);
+    reply("CSMSG_NETWORK_OPERS", count_opers);
     reply("CSMSG_NETWORK_CHANNELS", registered_channels);
     reply("CSMSG_NETWORK_LAMERS", banCount);
     reply("CSMSG_NETWORK_CHANUSERS", userCount);
@@ -5525,7 +5570,7 @@ send_staff_list(struct userNode *to, struct userList *list, int skip_flags)
         user = list->list[nn];
         if(user->modes & skip_flags)
             continue;
-        if(IsBot(user))
+        if(IsBot(user) || IsHideOper(user))
             continue;
         table.contents[table.length] = alloca(table.width*sizeof(**table.contents));
         if(IsAway(user))
@@ -5544,14 +5589,14 @@ send_staff_list(struct userNode *to, struct userList *list, int skip_flags)
 static CHANSERV_FUNC(cmd_ircops)
 {
     reply("CSMSG_STAFF_OPERS");
-    send_staff_list(user, &curr_opers, FLAGS_SERVICE);
+    send_staff_list(user, &curr_opers, FLAGS_SERVICE | FLAGS_BOT);
     return 1;
 }
 
 static CHANSERV_FUNC(cmd_helpers)
 {
     reply("CSMSG_STAFF_HELPERS");
-    send_staff_list(user, &curr_helpers, FLAGS_OPER);
+    send_staff_list(user, &curr_helpers, FLAGS_OPER | FLAGS_SERVICE | FLAGS_BOT);
     return 1;
 }
 
@@ -5585,9 +5630,9 @@ static CHANSERV_FUNC(cmd_peek)
     table.contents = alloca(channel->members.used*sizeof(*table.contents));
     for(n = 0; n < channel->members.used; n++)
     {
-       mn = channel->members.list[n];
-       if(!(mn->modes & MODE_CHANOP) || IsLocal(mn->user))
-            continue;
+        mn = channel->members.list[n];
+        if(!(mn->modes & MODE_CHANOP) || IsLocal(mn->user))
+                continue;
         table.contents[table.length] = alloca(sizeof(**table.contents));
         table.contents[table.length][0] = mn->user->nick;
         table.length++;
@@ -5664,7 +5709,18 @@ resync_channel(struct chanNode *channel)
         }
         else /* Give various userlevels their modes.. */
         {
-            if(uData && uData->access >= UL_OP )
+            /* If the user has autoop/autovoice disabled then ignore them */
+            if(uData && !IsUserAutoOp(uData))
+              continue;
+            if(uData && uData->access >= UL_PEON && cData->chOpts[chAutomode] == 'l')
+            {
+                if(!(mn->modes & MODE_VOICE))
+                {
+                    changes->args[used].mode = MODE_VOICE;
+                    changes->args[used++].u.member = mn;
+                }
+            }
+            else if(uData && uData->access >= UL_OP )
             {
                 if(!(mn->modes & MODE_CHANOP))
                 {
@@ -5797,24 +5853,24 @@ static CHANSERV_FUNC(cmd_seen)
 
     if(!irccasecmp(argv[1], chanserv->nick))
     {
-       reply("CSMSG_IS_CHANSERV");
-       return 1;
+        reply("CSMSG_IS_CHANSERV");
+        return 1;
     }
 
     if(!(handle = get_handle_info(argv[1])))
     {
-       reply("MSG_HANDLE_UNKNOWN", argv[1]);
-       return 0;
+        reply("MSG_HANDLE_UNKNOWN", argv[1]);
+        return 0;
     }
 
     if(!(uData = GetTrueChannelAccess(channel->channel_info, handle)))
     {
-       reply("CSMSG_NO_CHAN_USER", handle->handle, channel->name);
-       return 0;
+        reply("CSMSG_NO_CHAN_USER", handle->handle, channel->name);
+        return 0;
     }
 
     if(uData->present)
-       reply("CSMSG_USER_PRESENT", handle->handle);
+    reply("CSMSG_USER_PRESENT", handle->handle);
     else if(uData->seen)
         reply("CSMSG_USER_SEEN", handle->handle, channel->name, intervalString(seen, now - uData->seen, user->handle_info));
     else
@@ -5861,9 +5917,9 @@ note_type_visible_to_user(struct chanData *channel, struct note_type *ntype, str
 {
     switch(ntype->visible_type)
     {
-    case NOTE_VIS_ALL: return 1;
-    case NOTE_VIS_CHANNEL_USERS: return !channel || !user || (user->handle_info && GetChannelUser(channel, user->handle_info));
-    case NOTE_VIS_PRIVILEGED: default: return user && (IsOper(user) || IsSupportHelper(user) || IsNetworkHelper(user));
+        case NOTE_VIS_ALL: return 1;
+        case NOTE_VIS_CHANNEL_USERS: return !channel || !user || (user->handle_info && GetChannelUser(channel, user->handle_info));
+        case NOTE_VIS_PRIVILEGED: default: return user && (IsOper(user) || IsSupportHelper(user) || IsNetworkHelper(user));
     }
 }
 
@@ -6033,9 +6089,9 @@ static CHANSERV_FUNC(cmd_events)
         reply("CSMSG_BAR");
     matches = log_entry_search(&discrim, log_report_entry, &report);
     if(matches)
-       reply("MSG_MATCH_COUNT", matches);
+        reply("MSG_MATCH_COUNT", matches);
     else
-       reply("MSG_NO_MATCHES");
+        reply("MSG_NO_MATCHES");
     return 1;
 }
 
@@ -6185,9 +6241,9 @@ static CHANSERV_FUNC(cmd_csuspend)
         argv[1]++;
     else if(IsSuspended(channel->channel_info))
     {
-       reply("CSMSG_ALREADY_SUSPENDED", channel->name);
+        reply("CSMSG_ALREADY_SUSPENDED", channel->name);
         show_suspension_info(cmd, user, channel->channel_info->suspended);
-       return 0;
+        return 0;
     }
 
     if(!strcmp(argv[1], "0"))
@@ -6294,49 +6350,49 @@ chanserv_search_create(struct svccmd *cmd, struct userNode *user, unsigned int a
 
     for(i = 0; i < argc; i++)
     {
-       /* Assume all criteria require arguments. */
-       if(i == (argc - 1))
-       {
-           reply("MSG_MISSING_PARAMS", argv[i]);
-            goto fail;
-       }
-
-       if(!irccasecmp(argv[i], "name"))
-           search->name = argv[++i];
-       else if(!irccasecmp(argv[i], "registrar"))
-           search->registrar = argv[++i];
-       else if(!irccasecmp(argv[i], "unvisited"))
-           search->unvisited = ParseInterval(argv[++i]);
-       else if(!irccasecmp(argv[i], "registered"))
-           search->registered = ParseInterval(argv[++i]);
-       else if(!irccasecmp(argv[i], "flags"))
-       {
-           i++;
-           if(!irccasecmp(argv[i], "nodelete"))
-               search->flags |= CHANNEL_NODELETE;
-           else if(!irccasecmp(argv[i], "suspended"))
-               search->flags |= CHANNEL_SUSPENDED;
+        /* Assume all criteria require arguments. */
+        if(i == (argc - 1))
+        {
+            reply("MSG_MISSING_PARAMS", argv[i]);
+                goto fail;
+        }
+
+        if(!irccasecmp(argv[i], "name"))
+            search->name = argv[++i];
+        else if(!irccasecmp(argv[i], "registrar"))
+            search->registrar = argv[++i];
+        else if(!irccasecmp(argv[i], "unvisited"))
+            search->unvisited = ParseInterval(argv[++i]);
+        else if(!irccasecmp(argv[i], "registered"))
+            search->registered = ParseInterval(argv[++i]);
+        else if(!irccasecmp(argv[i], "flags"))
+        {
+            i++;
+            if(!irccasecmp(argv[i], "nodelete"))
+                search->flags |= CHANNEL_NODELETE;
+            else if(!irccasecmp(argv[i], "suspended"))
+                search->flags |= CHANNEL_SUSPENDED;
             else if(!irccasecmp(argv[i], "unreviewed"))
                 search->flags |= CHANNEL_UNREVIEWED;
-           else
-           {
-               reply("CSMSG_INVALID_CFLAG", argv[i]);
-               goto fail;
-           }
-       }
-       else if(!irccasecmp(argv[i], "limit"))
-           search->limit = strtoul(argv[++i], NULL, 10);
-       else
-       {
-           reply("MSG_INVALID_CRITERIA", argv[i]);
-           goto fail;
-       }
+            else
+            {
+                reply("CSMSG_INVALID_CFLAG", argv[i]);
+                goto fail;
+            }
+        }
+        else if(!irccasecmp(argv[i], "limit"))
+            search->limit = strtoul(argv[++i], NULL, 10);
+        else
+        {
+            reply("MSG_INVALID_CRITERIA", argv[i]);
+            goto fail;
+        }
     }
 
     if(search->name && !strcmp(search->name, "*"))
-       search->name = 0;
+    search->name = 0;
     if(search->registrar && !strcmp(search->registrar, "*"))
-       search->registrar = 0;
+    search->registrar = 0;
 
     return search;
   fail:
@@ -6354,7 +6410,7 @@ chanserv_channel_match(struct chanData *channel, search_t search)
        (search->unvisited && (now - channel->visited) < search->unvisited) ||
        (search->registered && (now - channel->registered) > search->registered) ||
        (search->flags && ((search->flags & channel->flags) != search->flags)))
-       return 0;
+    return 0;
 
     return 1;
 }
@@ -6367,10 +6423,10 @@ chanserv_channel_search(search_t search, channel_search_func smf, void *data)
 
     for(channel = channelList; channel && matches < search->limit; channel = channel->next)
     {
-       if(!chanserv_channel_match(channel, search))
+        if(!chanserv_channel_match(channel, search))
             continue;
-       matches++;
-       smf(channel, data);
+        matches++;
+        smf(channel, data);
     }
 
     return matches;
@@ -6396,13 +6452,13 @@ static CHANSERV_FUNC(cmd_search)
     REQUIRE_PARAMS(3);
 
     if(!irccasecmp(argv[1], "count"))
-       action = search_count;
+        action = search_count;
     else if(!irccasecmp(argv[1], "print"))
-       action = search_print;
+        action = search_print;
     else
     {
-       reply("CSMSG_ACTION_INVALID", argv[1]);
-       return 0;
+        reply("CSMSG_ACTION_INVALID", argv[1]);
+        return 0;
     }
 
     search = chanserv_search_create(cmd, user, argc - 2, argv + 2);
@@ -6410,11 +6466,11 @@ static CHANSERV_FUNC(cmd_search)
         return 0;
 
     if(action == search_count)
-       search->limit = INT_MAX;
+    search->limit = INT_MAX;
 
     if(action == search_print)
     {
-           reply("CSMSG_CHANNEL_SEARCH_RESULTS");
+        reply("CSMSG_CHANNEL_SEARCH_RESULTS");
         if(user->handle_info && user->handle_info->userlist_style != HI_STYLE_CLEAN)
             reply("CSMSG_BAR");
     }
@@ -6422,9 +6478,9 @@ static CHANSERV_FUNC(cmd_search)
     matches = chanserv_channel_search(search, action, user);
 
     if(matches)
-       reply("MSG_MATCH_COUNT", matches);
+        reply("MSG_MATCH_COUNT", matches);
     else
-       reply("MSG_NO_MATCHES");
+        reply("MSG_NO_MATCHES");
 
     free(search);
     return 1;
@@ -6439,8 +6495,8 @@ static CHANSERV_FUNC(cmd_unvisited)
 
     if(argc > 1)
     {
-       interval = ParseInterval(argv[1]);
-       if(argc > 2)
+        interval = ParseInterval(argv[1]);
+        if(argc > 2)
             limit = atoi(argv[2]);
     }
 
@@ -6449,12 +6505,12 @@ static CHANSERV_FUNC(cmd_unvisited)
 
     for(cData = channelList; cData && matches < limit; cData = cData->next)
     {
-       if((now - cData->visited) < interval)
+        if((now - cData->visited) < interval)
             continue;
 
-       intervalString(buffer, now - cData->visited, user->handle_info);
-       reply("CSMSG_UNVISITED_DATA", cData->channel->name, buffer);
-       matches++;
+        intervalString(buffer, now - cData->visited, user->handle_info);
+        reply("CSMSG_UNVISITED_DATA", cData->channel->name, buffer);
+        matches++;
     }
 
     return 1;
@@ -6475,10 +6531,10 @@ static MODCMD_FUNC(chan_opt_unreviewed)
         else if(disabled_string(argv[1]))
             new_value = 0;
         else
-       {
-           reply("MSG_INVALID_BINARY", argv[1]);
-           return 0;
-       }
+        {
+            reply("MSG_INVALID_BINARY", argv[1]);
+            return 0;
+        }
 
         if (new_value != value)
         {
@@ -6526,20 +6582,20 @@ static MODCMD_FUNC(chan_opt_defaulttopic)
             return 0;
         }
 
-       topic = unsplit_string(argv+1, argc-1, NULL);
+        topic = unsplit_string(argv+1, argc-1, NULL);
 
         free(channel->channel_info->topic);
-       if(topic[0] == '*' && topic[1] == 0)
-       {
+        if(topic[0] == '*' && topic[1] == 0)
+        {
             topic = channel->channel_info->topic = NULL;
-       }
-       else
-       {
-           topic = channel->channel_info->topic = strdup(topic);
+        }
+        else
+        {
+            topic = channel->channel_info->topic = strdup(topic);
             if(channel->channel_info->topic_mask
                && !match_ircglob(channel->channel_info->topic, channel->channel_info->topic_mask))
                 reply("CSMSG_TOPIC_MISMATCH", channel->name);
-       }
+        }
         SetChannelTopic(channel, chanserv, user, topic ? topic : "", 1);
     }
 
@@ -6563,22 +6619,22 @@ static MODCMD_FUNC(chan_opt_topicmask)
             return 0;
         }
 
-       mask = unsplit_string(argv+1, argc-1, NULL);
+        mask = unsplit_string(argv+1, argc-1, NULL);
 
         if(cData->topic_mask)
             free(cData->topic_mask);
-       if(mask[0] == '*' && mask[1] == 0)
-       {
-           cData->topic_mask = 0;
-       }
-       else
-       {
+        if(mask[0] == '*' && mask[1] == 0)
+        {
+            cData->topic_mask = 0;
+        }
+        else
+        {
             cData->topic_mask = strdup(mask);
             if(!cData->topic)
                 reply("CSMSG_MASK_BUT_NO_TOPIC", channel->name);
             else if(!match_ircglob(cData->topic, cData->topic_mask))
                 reply("CSMSG_TOPIC_MISMATCH", channel->name);
-       }
+        }
     }
 
     if(channel->channel_info->topic_mask)
@@ -6596,18 +6652,18 @@ int opt_greeting_common(struct userNode *user, struct svccmd *cmd, int argc, cha
         char *previous;
 
         previous = *data;
-       if(greeting[0] == '*' && greeting[1] == 0)
-           *data = NULL;
-       else
-       {
-           unsigned int length = strlen(greeting);
-           if(length > chanserv_conf.greeting_length)
-           {
-               reply("CSMSG_GREETING_TOO_LONG", length, chanserv_conf.greeting_length);
-               return 0;
-           }
-           *data = strdup(greeting);
-       }
+        if(greeting[0] == '*' && greeting[1] == 0)
+            *data = NULL;
+        else
+        {
+            unsigned int length = strlen(greeting);
+            if(length > chanserv_conf.greeting_length)
+            {
+                reply("CSMSG_GREETING_TOO_LONG", length, chanserv_conf.greeting_length);
+                return 0;
+            }
+            *data = strdup(greeting);
+        }
         if(previous)
             free(previous);
     }
@@ -6633,9 +6689,10 @@ static MODCMD_FUNC(chan_opt_maxsetinfo)
 {
    unsigned int charmax;
 
-   if(argc > 1) {
+   if(argc > 1) 
+   {
      charmax = atoi(argv[1]);
-     if ((charmax > 0) && (charmax < chanserv_conf.max_userinfo_length))
+     if ((charmax > 0) && (charmax <= chanserv_conf.max_userinfo_length))
        channel->channel_info->maxsetinfo = charmax;
    }
 
@@ -6660,12 +6717,12 @@ static MODCMD_FUNC(chan_opt_modes)
             reply("CSMSG_NO_ACCESS");
             return 0;
         }
-       if(argv[1][0] == '*' && argv[1][1] == 0)
-       {
-            memset(&channel->channel_info->modes, 0, sizeof(channel->channel_info->modes));
-       }
+        if(argv[1][0] == '*' && argv[1][1] == 0)
+        {
+                memset(&channel->channel_info->modes, 0, sizeof(channel->channel_info->modes));
+        }
         else if(!(new_modes = mod_chanmode_parse(channel, argv+1, argc-1,MCP_KEY_FREE|MCP_REGISTERED, 0)))
-       {
+        {
             reply("CSMSG_INVALID_MODE_LOCK", unsplit_string(argv+1, argc-1, NULL));
             return 0;
         }
@@ -6700,27 +6757,27 @@ channel_binary_option(char *name, unsigned long mask, struct userNode *user, str
 
     if(argc > 1)
     {
-       /* Set flag according to value. */
-       if(enabled_string(argv[1]))
-       {
-           cData->flags |= mask;
-           value = 1;
-       }
-       else if(disabled_string(argv[1]))
-       {
-           cData->flags &= ~mask;
-           value = 0;
-       }
-       else
-       {
-           reply("MSG_INVALID_BINARY", argv[1]);
-           return 0;
-       }
+        /* Set flag according to value. */
+        if(enabled_string(argv[1]))
+        {
+            cData->flags |= mask;
+            value = 1;
+        }
+        else if(disabled_string(argv[1]))
+        {
+            cData->flags &= ~mask;
+            value = 0;
+        }
+        else
+        {
+            reply("MSG_INVALID_BINARY", argv[1]);
+            return 0;
+        }
     }
     else
     {
-       /* Find current option value. */
-       value = (cData->flags & mask) ? 1 : 0;
+        /* Find current option value. */
+        value = (cData->flags & mask) ? 1 : 0;
     }
 
     if(value)
@@ -6734,8 +6791,8 @@ static MODCMD_FUNC(chan_opt_nodelete)
 {
     if((argc > 1) && (!IsOper(user) || !user->handle_info || (user->handle_info->opserv_level < chanserv_conf.nodelete_level)))
     {
-       reply("MSG_SETTING_PRIVILEGED", argv[0]);
-       return 0;
+        reply("MSG_SETTING_PRIVILEGED", argv[0]);
+        return 0;
     }
 
     CHANNEL_BINARY_OPTION("CSMSG_SET_NODELETE", CHANNEL_NODELETE);
@@ -6745,8 +6802,10 @@ static MODCMD_FUNC(chan_opt_dynlimit)
 {
     struct mod_chanmode change;
 
-    if (argc > 1) {
-        if (disabled_string(argv[1])) {
+    if (argc > 1) 
+    {
+        if (disabled_string(argv[1])) 
+        {
             mod_chanmode_init(&change);
             change.modes_clear |= MODE_LIMIT;
             mod_chanmode_announce(chanserv, channel, &change);
@@ -6763,38 +6822,38 @@ static MODCMD_FUNC(chan_opt_offchannel)
 
     if(argc > 1)
     {
-       /* Set flag according to value. */
-       if(enabled_string(argv[1]))
-       {
-            if(!IsOffChannel(cData))
-                DelChannelUser(chanserv, channel, "Going off-channel.", 0);
-           cData->flags |= CHANNEL_OFFCHANNEL;
-           value = 1;
-       }
-       else if(disabled_string(argv[1]))
-       {
-            if(IsOffChannel(cData))
-            {
-                struct mod_chanmode change;
-                mod_chanmode_init(&change);
-                change.argc = 1;
-                change.args[0].mode = MODE_CHANOP;
-                change.args[0].u.member = AddChannelUser(chanserv, channel);
-                mod_chanmode_announce(chanserv, channel, &change);
-            }
-           cData->flags &= ~CHANNEL_OFFCHANNEL;
-           value = 0;
-       }
-       else
-       {
-           reply("MSG_INVALID_BINARY", argv[1]);
-           return 0;
-       }
+        /* Set flag according to value. */
+        if(enabled_string(argv[1]))
+        {
+                if(!IsOffChannel(cData))
+                    DelChannelUser(chanserv, channel, "Going off-channel.", 0);
+            cData->flags |= CHANNEL_OFFCHANNEL;
+            value = 1;
+        }
+        else if(disabled_string(argv[1]))
+        {
+                if(IsOffChannel(cData))
+                {
+                    struct mod_chanmode change;
+                    mod_chanmode_init(&change);
+                    change.argc = 1;
+                    change.args[0].mode = MODE_CHANOP;
+                    change.args[0].u.member = AddChannelUser(chanserv, channel);
+                    mod_chanmode_announce(chanserv, channel, &change);
+                }
+            cData->flags &= ~CHANNEL_OFFCHANNEL;
+            value = 0;
+        }
+        else
+        {
+            reply("MSG_INVALID_BINARY", argv[1]);
+            return 0;
+        }
     }
     else
     {
-       /* Find current option value. */
-       value = (cData->flags & CHANNEL_OFFCHANNEL) ? 1 : 0;
+        /* Find current option value. */
+        value = (cData->flags & CHANNEL_OFFCHANNEL) ? 1 : 0;
     }
 
     if(value)
@@ -6852,8 +6911,8 @@ channel_level_option(enum levelOption option, struct userNode *user, struct chan
         }
         value = user_level_from_name(argv[1], UL_OWNER+1);
         if(!value && strcmp(argv[1], "0"))
-       {
-           reply("CSMSG_INVALID_ACCESS", argv[1]);
+        {
+            reply("CSMSG_INVALID_ACCESS", argv[1]);
             return 0;
         }
         uData = GetChannelUser(cData, user->handle_info);
@@ -6951,22 +7010,22 @@ channel_multiple_option(enum charOption option, struct userNode *user, struct ch
     {
         idx = atoi(argv[1]);
 
-       if(!isdigit(argv[1][0]) || (idx < 0) || (idx >= count))
-       {
-           reply("CSMSG_INVALID_NUMERIC", idx);
+    if(!isdigit(argv[1][0]) || (idx < 0) || (idx >= count))
+    {
+        reply("CSMSG_INVALID_NUMERIC", idx);
             /* Show possible values. */
             for(idx = 0; idx < count; idx++)
                 reply(charOptions[option].format_name, idx, user_find_message(user, charOptions[option].values[idx].format_name));
-           return 0;
-       }
+        return 0;
+    }
 
-       cData->chOpts[option] = charOptions[option].values[idx].value;
+    cData->chOpts[option] = charOptions[option].values[idx].value;
     }
     else
     {
-       /* Find current option value. */
+    /* Find current option value. */
       find_value:
-       for(idx = 0;
+    for(idx = 0;
             (idx < count) && (cData->chOpts[option] != charOptions[option].values[idx].value);
             idx++);
         if(idx == count)
@@ -6983,10 +7042,6 @@ channel_multiple_option(enum charOption option, struct userNode *user, struct ch
 
 static MODCMD_FUNC(chan_opt_automode)
 {
-    if(check_user_level(channel, user, lvlInviteMe, 1, 0))
-    {
-        reply("CSMSG_LOW_CHANNEL_ACCESS", channel->name);
-    }
     return channel_multiple_option(chAutomode, CSFUNC_ARGS);
 }
 
@@ -7023,7 +7078,7 @@ static MODCMD_FUNC(chan_opt_resync)
 static struct svccmd_list set_shows_list;
 
 static void
-handle_svccmd_unbind(struct svccmd *target) {
+handle_svccmd_unbind(struct svccmd *target, UNUSED_ARG(void *extra)) {
     unsigned int ii;
     for(ii=0; ii<set_shows_list.used; ++ii)
         if(target == set_shows_list.list[ii])
@@ -7060,7 +7115,7 @@ static CHANSERV_FUNC(cmd_set)
 
     if(argc < 2)
     {
-           reply("CSMSG_CHANNEL_OPTIONS", channel->name);
+        reply("CSMSG_CHANNEL_OPTIONS", channel->name);
         if(user->handle_info && user->handle_info->userlist_style != HI_STYLE_CLEAN)
             reply("CSMSG_BAR");
         for(ii = 0; ii < set_shows_list.used; ii++)
@@ -7069,7 +7124,7 @@ static CHANSERV_FUNC(cmd_set)
             subcmd->command->func(user, channel, 1, argv+1, subcmd);
         }
         reply("CSMSG_CHANNEL_OPTIONS_END");
-       return 1;
+    return 1;
     }
 
     sprintf(buf, "%s %s", argv[0], argv[1]);
@@ -7104,7 +7159,7 @@ user_binary_option(char *name, unsigned long mask, struct userNode *user, struct
 
     if(argc < 2)
     {
-       /* Just show current option value. */
+    /* Just show current option value. */
     }
     else if(enabled_string(argv[1]))
     {
@@ -7163,11 +7218,11 @@ static MODCMD_FUNC(user_opt_info)
 
     if(!uData)
     {
-       /* If they got past the command restrictions (which require access)
+        /* If they got past the command restrictions (which require access)
          * but fail this test, we have some fool with security override on.
          */
-       reply("CSMSG_NOT_USER", channel->name);
-       return 0;
+        reply("CSMSG_NOT_USER", channel->name);
+        return 0;
     }
 
     if(argc > 1)
@@ -7236,11 +7291,11 @@ static CHANSERV_FUNC(cmd_uset)
 
     if(argc < 2)
     {
-       /* Do this so options are presented in a consistent order. */
-       reply("CSMSG_USER_OPTIONS");
+    /* Do this so options are presented in a consistent order. */
+    reply("CSMSG_USER_OPTIONS");
         for(ii = 0; ii < uset_shows_list.used; ii++)
             uset_shows_list.list[ii]->command->func(user, channel, 1, argv+1, uset_shows_list.list[ii]);
-       return 1;
+    return 1;
     }
 
     sprintf(buf, "%s %s", argv[0], argv[1]);
@@ -7391,8 +7446,8 @@ chanserv_expire_user_suspension(void *data)
 {
     struct userData *target = data;
 
-       target->expires = 0;
-       target->flags &= ~USER_SUSPENDED;
+    target->expires = 0;
+    target->flags &= ~USER_SUSPENDED;
 }
 
 static CHANSERV_FUNC(cmd_suspend)
@@ -7439,10 +7494,10 @@ static CHANSERV_FUNC(cmd_suspend)
         expiry = now + duration;
     }
 
-        target->expires = expiry;
+    target->expires = expiry;
 
-        if(target->expires)
-            timeq_add(target->expires, chanserv_expire_user_suspension, target);
+    if(target->expires)
+        timeq_add(target->expires, chanserv_expire_user_suspension, target);
 
     if(!real_actor || target->access >= real_actor->access)
         override = CMD_LOG_OVERRIDE;
@@ -7458,7 +7513,9 @@ static CHANSERV_FUNC(cmd_unsuspend)
     unsigned int override = 0;
 
     REQUIRE_PARAMS(2);
-    if(!(hi = modcmd_get_handle_info(user, argv[1]))) return 0;
+    if(!(hi = modcmd_get_handle_info(user, argv[1]))) 
+        return 0;
+    actor = GetChannelUser(channel->channel_info, user->handle_info);
     real_actor = GetChannelAccess(channel->channel_info, user->handle_info);
     if(!(target = GetTrueChannelAccess(channel->channel_info, hi)))
     {
@@ -7549,11 +7606,14 @@ chanserv_auto_resync(UNUSED_ARG(void *data))
 
     for(cData = channelList; cData; cData = cData->next)
     {
-        if(IsSuspended(cData)) continue;
+        if(IsSuspended(cData)) 
+            continue;
         opt = cData->chOpts[chResync];
-        if(opt == 'n') continue;
-        if((refresh_num - cData->last_resync) < (unsigned int)(1 << (opt - '1'))) continue;
-               resync_channel(cData->channel);
+        if(opt == 'n') 
+            continue;
+        if((refresh_num - cData->last_resync) < (unsigned int)(1 << (opt - '1'))) 
+            continue;
+        resync_channel(cData->channel);
         cData->last_resync = refresh_num;
     }
     timeq_add(now + chanserv_conf.refresh_period, chanserv_auto_resync, NULL);
@@ -7603,12 +7663,15 @@ static CHANSERV_FUNC(cmd_wut)
 
 static CHANSERV_FUNC(cmd_roulette)
 {
-    if(channel) {
+    if(channel) 
+    {
         struct chanData *cData = channel->channel_info;
 
-        if (cData) {
-            if (cData->roulette_chamber) {
-               DelUser(user, chanserv, 1, "BANG - Don't stuff bullets into a loaded gun");
+        if (cData) 
+        {
+            if (cData->roulette_chamber) 
+            {
+                DelUser(user, chanserv, 1, "BANG - Don't stuff bullets into a loaded gun");
                 return 1;
             }
         
@@ -7621,12 +7684,15 @@ static CHANSERV_FUNC(cmd_roulette)
 }
 static CHANSERV_FUNC(cmd_shoot)
 {
-    if(channel) {
+    if(channel) 
+    {
         struct chanData *cData = channel->channel_info;
 
-        if (cData->roulette_chamber <= 0) {
+        if (cData->roulette_chamber <= 0) 
+        {
             struct service *service;
-            if ((service = service_find(chanserv->nick))) {
+            if ((service = service_find(chanserv->nick))) 
+            {
                 reply("CSMSG_ROULETTE_NEW", service->trigger);
             }
             return 1;
@@ -7634,11 +7700,13 @@ static CHANSERV_FUNC(cmd_shoot)
 
         cData->roulette_chamber--;
 
-        if (cData->roulette_chamber == 0) {
+        if (cData->roulette_chamber == 0) 
+        {
             reply("CSMSG_ROULETTE_BANG");
             reply("CSMSG_ROULETTE_BETTER_LUCK", user->nick);
             DelUser(user, chanserv, 1, "BANG!!!!");
-        } else
+        } 
+        else
             reply("CSMSG_ROULETTE_CLICK");
     }
 
@@ -7661,7 +7729,8 @@ int lamepart(struct userNode *nick) {
     struct modeNode *mn;
     unsigned int count, n;
 
-    for (n=count=0; n<nick->channels.used; n++) {
+    for (n=count=0; n<nick->channels.used; n++) 
+    {
         mn = nick->channels.list[n];
         irc_svspart(chanserv, nick, mn->channel);
     }
@@ -7689,7 +7758,8 @@ static CHANSERV_FUNC(cmd_spin)
     send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_WHEEL2");
     send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_WHEEL3");
 
-    if(chanserv_conf.wheel->used < 1) {
+    if(chanserv_conf.wheel->used < 1) 
+    {
         /* wheel actions not defined! eek */
         return 1;
     }
@@ -7698,15 +7768,9 @@ static CHANSERV_FUNC(cmd_spin)
     if(!wheel && *wheel) 
         return 1;
 
-/* enable this to be able to manually specify a result for testing:
-    log_module(MAIN_LOG, LOG_DEBUG,"Testing wheel randomness: %s\n", wheel);
-    if(argc > 1) {
-      wheel = argv[1];
-    }
-*/
-
     /* connection reset by peer */
-    if (!strcasecmp(wheel, "peer")) {
+    if (!strcasecmp(wheel, "peer")) 
+    {
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_PEER");
          if (type < 7)
               irc_kill(chanserv, user, "Connection reset by peer");
@@ -7714,7 +7778,8 @@ static CHANSERV_FUNC(cmd_spin)
               irc_svsquit(chanserv, user, "Connection reset by peer");
     }
     /* part all channels */
-    else if (!strcasecmp(wheel, "partall")) {
+    else if (!strcasecmp(wheel, "partall")) 
+    {
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_PARTALL");
          if (lamep)
              lamepart(user);
@@ -7722,54 +7787,64 @@ static CHANSERV_FUNC(cmd_spin)
              sputsock("%s SJ %s 0 "FMT_TIME_T, self->numeric, user->numeric, now);
     }
     /* random time gline */
-    else if (!strcasecmp(wheel, "gline")) {
-         char target[IRC_NTOP_MAX_SIZE + 3];
+    else if (!strcasecmp(wheel, "gline")) 
+    {
+         char target[HOSTLEN + 3];
          int wtime = 120 + rand() % 600;
 
          strcpy(target, "*@");
          strcat(target, user->hostname);
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_GLINE");
 
-         gline_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, now, 1, 0);
-//         irc_kill(chanserv, user, "Reward for spinning the wheel of misfortune!");
+         gline_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, 1, 0);
     }
     /* random shun */
-    else if (!strcasecmp(wheel, "shun")) {
-         char target[IRC_NTOP_MAX_SIZE + 3];
+    else if (!strcasecmp(wheel, "shun")) 
+    {
+         char target[HOSTLEN + 3];
          int wtime = 120 + rand() % 600;
 
          strcpy(target, "*@");
          strcat(target, user->hostname);
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_SHUN");
 
-         shun_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, now, 1);
+         shun_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, 1);
     }
     /* absolutely nothing */
-    else if (!strcasecmp(wheel, "nothing")) {
+    else if (!strcasecmp(wheel, "nothing")) 
+    {
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_NOTHING");
     }
     /* join random chans and part em several times */
-    else if (!strcasecmp(wheel, "randjoin")) {
+    else if (!strcasecmp(wheel, "randjoin")) 
+    {
          int complete = 0;
          int rndchans = 0;
          int chango = 0;
          int roundz0r = 0;
 
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_RANDJOIN");
-         while(complete != 1)  {
-            if (rndchans != 15) {
+         while(complete != 1)  
+         {
+            if (rndchans != 15) 
+            {
                 chango = 120 + rand() % 600;
                 sputsock("%s SJ %s #%d "FMT_TIME_T, self->numeric, user->numeric, chango, now);
                 rndchans++;
-            } else {
-                if (roundz0r != 1) {
+            } 
+            else 
+            {
+                if (roundz0r != 1) 
+                {
                      if (lamep)
                          lamepart(user);
                      else
                          sputsock("%s SJ %s 0 "FMT_TIME_T, self->numeric, user->numeric, now);
                      roundz0r = 1;
                      rndchans = 0;
-                } else {
+                } 
+                else 
+                {
                      if (lamep)
                          lamepart(user);
                      else
@@ -7780,12 +7855,14 @@ static CHANSERV_FUNC(cmd_spin)
         }
     }
     /* abuse line added to /whois */
-    else if (!strcasecmp(wheel, "abusewhois")) {
+    else if (!strcasecmp(wheel, "abusewhois")) 
+    {
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_ABUSEWHOIS");
          irc_swhois(chanserv, user, "is being defecated on by services");
     }
     /* kick from each channel your in */
-    else if (!strcasecmp(wheel, "kickall")) {
+    else if (!strcasecmp(wheel, "kickall")) 
+    {
          unsigned int count, n;
          struct modeNode *mn;
 
@@ -7797,22 +7874,22 @@ static CHANSERV_FUNC(cmd_spin)
          }
     }
     /* random nick change */
-    else if (!strcasecmp(wheel, "nickchange")) {
+    else if (!strcasecmp(wheel, "nickchange")) 
+    {
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_NICKCHANGE");
 
          char *oldnick = NULL;
          char *oldident = NULL;
-         char *oldhost = NULL;
          char abusednick[NICKLEN] = "";
          int abusednum = 1 + (int) (10000.0 * (rand() / (RAND_MAX + 1.0)));
          struct userNode *clone;
 
          oldnick = strdup(user->nick);
          oldident = strdup(user->ident);
-         oldhost = strdup(user->hostname);
 
          //snprintf(abusednick, NICKLEN, "Abused%d", abusednum+(1 + rand() % 120));
-         while (1) {
+         while (1) 
+         {
              snprintf(abusednick, NICKLEN, "Abused%d", abusednum+(1 + rand() % 120));
              log_module(MAIN_LOG, LOG_DEBUG, "Abused Nick: %s, Client Nick: %s", abusednick, user->nick);
              if(!GetUserH(abusednick))
@@ -7821,20 +7898,23 @@ static CHANSERV_FUNC(cmd_spin)
 
          SVSNickChange(user, abusednick);
          irc_svsnick(chanserv, user, abusednick);
-         clone = AddLocalUser(oldnick, oldident, oldhost, "I got abused by the wheel of misfortune :D", "+i");
+         clone = AddLocalUser(oldnick, oldident, "abused.by.wheel.of.misfortune", "I got abused by the wheel of misfortune :D", "+i");
          timeq_add(now + 300, chanserv_remove_abuse, clone->nick);
     }
     /* kill */
-    else if (!strcasecmp(wheel, "kill")) {
+    else if (!strcasecmp(wheel, "kill")) 
+    {
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_KILL");
 
-        DelUser(user, chanserv, 1, "Reward for spinning the wheel of misfortune!");
+         DelUser(user, chanserv, 1, "Reward for spinning the wheel of misfortune!");
          //irc_kill(chanserv, user, "Reward for spinning the wheel of misfortune!");
     }
     /* service ignore */
-    else if (!strcasecmp(wheel, "svsignore")) {
-         int gagged, ignoretime = 0;
-         char target[IRC_NTOP_MAX_SIZE + 13];
+    else if (!strcasecmp(wheel, "svsignore")) 
+    {
+         //int gagged;
+         int ignoretime = 0;
+         char target[HOSTLEN + 13];
 
          if(IsOper(user)) {
             /* we cant gag opers, so just verbally abuse them */
@@ -7847,63 +7927,67 @@ static CHANSERV_FUNC(cmd_spin)
          strcat(target, user->hostname);
          ignoretime = now + (1 + rand() % 120);
 
-         gagged = gag_create(target, "wheelofabuse", "Reward for spinning the wheel of misfortune!", ignoretime);
+         gag_create(target, "wheelofabuse", "Reward for spinning the wheel of misfortune!", ignoretime);
     }
     /* kick and ban from each channel your in */
-    else if (!strcasecmp(wheel, "kickbanall")) {
+    else if (!strcasecmp(wheel, "kickbanall")) 
+    {
          unsigned int count, n;
          struct modeNode *mn;
-         //char ban[IRC_NTOP_MAX_SIZE + 1];
+         //char ban[HOSTLEN + 1];
 
          send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_KICKBANALL");
 
          //snprintf(ban, sizeof(ban), "*!*@%s", user->hostname);
-         for (n=count=0; n<user->channels.used; n++) {
+         for (n=count=0; n<user->channels.used; n++) 
+         {
              struct mod_chanmode *change;
-/*             struct banData *bData; */
-            unsigned int exists;
-/*          int duration = 300; */
-            char *ban;
+/*           struct banData *bData; */
+             unsigned int exists;
+/*           int duration = 300; */
+             char *ban;
 
-            ban = generate_hostmask(user, GENMASK_STRICT_HOST|GENMASK_ANY_IDENT|GENMASK_USENICK);
+             ban = generate_hostmask(user, GENMASK_STRICT_HOST|GENMASK_ANY_IDENT|GENMASK_USENICK);
 
-            log_module(MAIN_LOG, LOG_DEBUG, "Generated ban %s", ban);
+             log_module(MAIN_LOG, LOG_DEBUG, "Generated ban %s", ban);
              mn = user->channels.list[n];
-             if(mn->channel->banlist.used >= MAXBANS) {
-               reply("CSMSG_BANLIST_FULL", mn->channel->name);
-               free(ban);
-               continue;
+             if(mn->channel->banlist.used >= MAXBANS) 
+             {
+                 reply("CSMSG_BANLIST_FULL", mn->channel->name);
+                 free(ban);
+                 continue;
              }
 
-/*             bData = add_channel_ban(mn->channel->channel_info, ban, chanserv->nick, now, now, now + duration, "Reward for spinning the wheel of misfortune!"); */
+/*           bData = add_channel_ban(mn->channel->channel_info, ban, chanserv->nick, now, now, now + duration, "Reward for spinning the wheel of misfortune!"); */
 
-            change = mod_chanmode_alloc(1);
-            change->args[0].mode = MODE_REMOVE|MODE_CHANOP|MODE_HALFOP|MODE_VOICE;
-            change->args[0].u.member = GetUserMode(mn->channel, user);
-            change->argc = 1;
+             change = mod_chanmode_alloc(1);
+             change->args[0].mode = MODE_REMOVE|MODE_CHANOP|MODE_HALFOP|MODE_VOICE;
+             change->args[0].u.member = GetUserMode(mn->channel, user);
+             change->argc = 1;
 
-            mod_chanmode_announce(chanserv, mn->channel, change);
-            mod_chanmode_free(change);
+             mod_chanmode_announce(chanserv, mn->channel, change);
+             mod_chanmode_free(change);
 
-            exists = ChannelBanExists(mn->channel, ban);
-            if(!exists) {
-               change = mod_chanmode_alloc(1);
-              change->args[0].mode = MODE_BAN;
-              change->args[0].u.hostmask = ban;
-              change->argc = 1;
-              mod_chanmode_announce(chanserv, mn->channel, change);
-              mod_chanmode_free(change);
+             exists = ChannelBanExists(mn->channel, ban);
+             if(!exists) {
+                 change = mod_chanmode_alloc(1);
+                 change->args[0].mode = MODE_BAN;
+                 change->args[0].u.hostmask = ban;
+                 change->argc = 1;
+                 mod_chanmode_announce(chanserv, mn->channel, change);
+                 mod_chanmode_free(change);
              }
 
              if(exists) {
-               reply("CSMSG_REDUNDANT_BAN", ban, mn->channel->name);
-               free(ban);
-            }
+                 reply("CSMSG_REDUNDANT_BAN", ban, mn->channel->name);
+                 free(ban);
+             }
 
              irc_kick(chanserv, user, mn->channel, "Reward for spinning the wheel of misfortune!");
          }
     }
-    else {
+    else 
+    {
        send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_UNKNOWN", wheel);
     }
 
@@ -7940,13 +8024,14 @@ void eightball(char *outcome, int method, unsigned int seed)
    int answer = 0;
 
 #define NUMOFCOLORS 18
-   char ballcolors[50][50] = {"blue", "red", "green", "yellow",
+   char ballcolors[50][50] = {
+        "blue", "red", "green", "yellow",
         "white", "black", "grey", "brown",
-        "yellow", "pink", "purple", "orange", "teal", "burgandy",
+        "yellow", "pink", "purple", "orange", "teal", "burgundy",
         "fuchsia","turquoise","magenta", "cyan"};
 #define NUMOFLOCATIONS 50
    char balllocations[50][55] = { 
-       "Locke's house", "Oregon", "California", "Indiana", "Canada",
+        "Locke's house", "Oregon", "California", "Indiana", "Canada",
         "Russia", "Japan", "Florida", "the Bahamas", "Hiroshima",
         "the Caribbean", "the Everglades", "your head", "your pants", "your school",
         "the Statue of Liberty", "Mt. Fugi", "your mother's house", "IRC", "OSU",
@@ -7954,13 +8039,13 @@ void eightball(char *outcome, int method, unsigned int seed)
         "the bathtub", "the toilet", "the sewer", "a horse", "Jupiter",
         "Uranus", "Pluto", "a dark place", "your undies", "your shirt",
         "your bra", "your hair", "your bed", "the couch", "the wall", 
-       "Reed", "here --> [X]", "your brain", "Italy", "the Netherlands", 
-       "Mars", "my hardware", "the bar", "Neverland Ranch", "Germany" };
+        "Reed", "here --> [X]", "your brain", "Italy", "the Netherlands", 
+        "Mars", "my hardware", "the bar", "Neverland Ranch", "Germany" };
 #define NUMOFPREPS 15
    char ballpreps[50][50] = { 
-       "Near", "Somewhere near", "In", "In", "In", 
-       "In", "Hiding in", "Under", "Next to", "Over", 
-       "Crying in", "Right beside", "Nowhere near", "North of", "Trying to find"};
+        "Near", "Somewhere near", "In", "In", "In", 
+        "In", "Hiding in", "Under", "Next to", "Over", 
+        "Crying in", "Right beside", "Nowhere near", "North of", "Trying to find"};
 #define NUMOFNUMS 34
    char ballnums[50][50] = { 
         "A hundred", "A thousand", "A few", "42",
@@ -7997,13 +8082,13 @@ void eightball(char *outcome, int method, unsigned int seed)
         case 4: strcpy(tmp, "A gross kind of mucky %s.");
                 break;
         case 5: strcpy(tmp, "Brilliant whiteish %s.");
-                       break;
+                break;
         case 6: case 7: case 8: case 9: strcpy(tmp, "%s.");
                 break;
         case 10: strcpy(tmp, "Solid %s.");
                 break;
         case 11: strcpy(tmp, "Transparent %s.");
-                       break;
+                break;
         default: strcpy(outcome, "An invalid random number was generated.");
                 return;
       }
@@ -8027,30 +8112,30 @@ void eightball(char *outcome, int method, unsigned int seed)
 
 static CHANSERV_FUNC(cmd_8ball)
 {
-  char *word1, *word2, *word3;
-  static char eb[MAXLEN];
-  unsigned int accum, i, j;
+    char *word1, *word2, *word3;
+    static char eb[MAXLEN];
+    unsigned int accum, i, j;
 
-  REQUIRE_PARAMS(2);
-  accum = 0;
-  for(i=1; i<argc; i++)
-    for(j=0; argv[i][j]; j++)
-      accum = (accum << 5) - accum + toupper(argv[i][j]);
+    REQUIRE_PARAMS(2);
+    accum = 0;
+    for(i=1; i<argc; i++)
+        for(j=0; argv[i][j]; j++)
+            accum = (accum << 5) - accum + toupper(argv[i][j]);
 
-  accum += time(NULL)/3600;
-  word1 = argv[1];
-  word2 = argc>2?argv[2]:"";
-  word3 = argc>3?argv[3]:"";
+    accum += time(NULL)/3600;
+    word1 = argv[1];
+    word2 = argc>2?argv[2]:"";
+    word3 = argc>3?argv[3]:"";
 
 /*** COLOR *****/
-  if((word2) && strcasecmp(word1, "what") == 0 && strcasecmp(word2, "color") == 0)
-     eightball(eb, 1, accum);
-  else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && strcasecmp(word3, "color") == 0)
-     eightball(eb, 1, accum);
-  else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && strcasecmp(word3, "color") == 0)
-     eightball(eb, 1, accum);
+    if((word2) && strcasecmp(word1, "what") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0)))
+        eightball(eb, 1, accum);
+    else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0)))
+        eightball(eb, 1, accum);
+    else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0)))
+        eightball(eb, 1, accum);
 /*** LOCATION *****/
-  else if(
+    else if(
            (
              word2 &&
              (
@@ -8064,24 +8149,24 @@ static CHANSERV_FUNC(cmd_8ball)
          )
      eightball(eb, 2, accum);
 /*** NUMBER *****/
-  else if((word2) && strcasecmp(word1, "how") == 0 && strcasecmp(word2, "many") == 0)
-     eightball(eb, 3, accum);
+    else if((word2) && strcasecmp(word1, "how") == 0 && strcasecmp(word2, "many") == 0)
+        eightball(eb, 3, accum);
 /*** GENERIC *****/
-  else
-  {
-     /* Generic 8ball question.. so pull from x3.conf srvx style */
-           const char *resp;
-
-           resp = chanserv_conf.eightball->list[accum % chanserv_conf.eightball->used];
-           if(channel)
-           {
-               char response[MAXLEN];
-               sprintf(response, "\002%s\002: %s", user->nick, resp);
-               irc_privmsg(cmd->parent->bot, channel->name, response);
-           }
-           else
-               send_message_type(4, user, cmd->parent->bot, "%s", resp);
-           return 1;
+    else
+    {
+        /* Generic 8ball question.. so pull from x3.conf srvx style */
+        const char *resp;
+
+        resp = chanserv_conf.eightball->list[accum % chanserv_conf.eightball->used];
+        if(channel)
+        {
+            char response[MAXLEN];
+            sprintf(response, "\002%s\002: %s", user->nick, resp);
+            irc_privmsg(cmd->parent->bot, channel->name, response);
+        }
+        else
+            send_message_type(4, user, cmd->parent->bot, "%s", resp);
+        return 1;
   }
 
   if(channel)
@@ -8222,7 +8307,7 @@ chanserv_adjust_limit(void *data)
 }
 
 static void
-handle_new_channel(struct chanNode *channel)
+handle_new_channel(struct chanNode *channel, UNUSED_ARG(void *extra))
 {
     struct chanData *cData;
 
@@ -8250,7 +8335,7 @@ trace_check_bans(struct userNode *user, struct chanNode *chan)
     if (chan->channel_info) {
         for(bData = chan->channel_info->bans; bData; bData = bData->next) {
 
-            if(!user_matches_glob(user, bData->mask, MATCH_USENICK))
+            if(!user_matches_glob(user, bData->mask, MATCH_USENICK, 0))
                 continue;
 
             if(bData)
@@ -8282,7 +8367,7 @@ check_bans(struct userNode *user, const char *channel)
     {
         /* Not joining through a ban. */
         for(bData = cData->bans;
-            bData && !user_matches_glob(user, bData->mask, MATCH_USENICK);
+            bData && !user_matches_glob(user, bData->mask, MATCH_USENICK, 0);
             bData = bData->next);
 
         if(bData)
@@ -8324,7 +8409,7 @@ channel_user_is_exempt(struct userNode *user, struct chanNode *channel)
    unsigned int ii;
    for(ii = 0; ii < channel->exemptlist.used; ii++)
    {
-       if(user_matches_glob(user, channel->exemptlist.list[ii]->exempt, MATCH_USENICK))
+       if(user_matches_glob(user, channel->exemptlist.list[ii]->exempt, MATCH_USENICK, 0))
            return true;
    }
    return false;
@@ -8334,7 +8419,7 @@ channel_user_is_exempt(struct userNode *user, struct chanNode *channel)
 /* Welcome to my worst nightmare. Warning: Read (or modify)
    the code below at your own risk. */
 static int
-handle_join(struct modeNode *mNode)
+handle_join(struct modeNode *mNode, UNUSED_ARG(void *extra))
 {
     struct mod_chanmode change;
     struct userNode *user = mNode->user;
@@ -8369,7 +8454,7 @@ handle_join(struct modeNode *mNode)
         unsigned int ii;
         for(ii = 0; ii < channel->banlist.used; ii++)
         {
-            if(user_matches_glob(user, channel->banlist.list[ii]->ban, MATCH_USENICK))
+            if(user_matches_glob(user, channel->banlist.list[ii]->ban, MATCH_USENICK, 0))
             {
                 /* Riding a netburst.  Naughty. */
                 KickChannelUser(user, channel, chanserv, "User from far side of netsplit should have been banned - bye.");
@@ -8400,7 +8485,7 @@ handle_join(struct modeNode *mNode)
         {
             /* Not joining through a ban. */
             for(bData = cData->bans;
-                bData && !user_matches_glob(user, bData->mask, MATCH_USENICK);
+                bData && !user_matches_glob(user, bData->mask, MATCH_USENICK, 0);
                 bData = bData->next);
 
             if(bData)
@@ -8565,14 +8650,14 @@ chanserv_autojoin_channels(struct userNode *user)
 }
 
 static void
-handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
+handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle), UNUSED_ARG(void *extra))
 {
     struct mod_chanmode change;
     struct userData *channel;
     unsigned int ii, jj, i;
 
     if(!user->handle_info)
-       return;
+    return;
 
     mod_chanmode_init(&change);
     change.argc = 1;
@@ -8599,12 +8684,14 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
             continue;
         }
 
-       if(channel->access >= UL_PRESENT)
-           channel->channel->visited = now;
+    if(channel->access >= UL_PRESENT)
+        channel->channel->visited = now;
 
         if(IsUserAutoOp(channel) && cData->chOpts[chAutomode] != 'n')
         {
-            if(channel->access >= UL_OP )
+            if (channel->access >= UL_PEON && cData->chOpts[chAutomode] == 'l')
+                change.args[0].mode = MODE_VOICE;
+            else if(channel->access >= UL_OP )
                 change.args[0].mode = MODE_CHANOP;
             else if(channel->access >= UL_HALFOP )
                 change.args[0].mode = MODE_HALFOP;
@@ -8617,8 +8704,8 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
                 mod_chanmode_announce(chanserv, cn, &change);
         }
 
-       channel->seen = now;
-       channel->present = 1;
+        channel->seen = now;
+        channel->present = 1;
     }
 
     for(ii = 0; ii < user->channels.used; ++ii)
@@ -8633,14 +8720,14 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
         if(protect_user(user, chanserv, chan->channel_info, true))
             continue;
         for(jj = 0; jj < chan->banlist.used; ++jj)
-            if(user_matches_glob(user, chan->banlist.list[jj]->ban, MATCH_USENICK))
+            if(user_matches_glob(user, chan->banlist.list[jj]->ban, MATCH_USENICK, 0))
                 break;
         if(jj < chan->banlist.used)
             continue;
         for(ban = chan->channel_info->bans; ban; ban = ban->next)
         {
             char kick_reason[MAXLEN];
-            if(!user_matches_glob(user, ban->mask,MATCH_USENICK | MATCH_VISIBLE))
+            if(!user_matches_glob(user, ban->mask,MATCH_USENICK | MATCH_VISIBLE, 0))
                 continue;
             change.args[0].mode = MODE_BAN;
             change.args[0].u.hostmask = ban->mask;
@@ -8671,16 +8758,16 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
     }
 
     if (user->handle_info->epithet)
-      irc_swhois(chanserv, user, user->handle_info->epithet);
+        irc_swhois(chanserv, user, user->handle_info->epithet);
 
-   /* process autojoin channels 5 seconds later as this sometimes 
-      happens before autohide */
-//   timeq_add(now + 5, chanserv_autojoin_channels, user);
+    /* process autojoin channels 5 seconds later as this sometimes 
+       happens before autohide */
+    //timeq_add(now + 5, chanserv_autojoin_channels, user);
     chanserv_autojoin_channels(user);
 }
 
 static void
-handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason))
+handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason), UNUSED_ARG(void *extra))
 {
     struct chanData *cData;
     struct userData *uData;
@@ -8691,36 +8778,46 @@ handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason))
 
     if((cData->flags & CHANNEL_DYNAMIC_LIMIT) && !mn->channel->join_flooded)
     {
-       /* Allow for a bit of padding so that the limit doesn't
-          track the user count exactly, which could get annoying. */
-       if((mn->channel->limit - mn->channel->members.used) > chanserv_conf.adjust_threshold + 5)
-       {
-           timeq_del(0, chanserv_adjust_limit, cData, TIMEQ_IGNORE_WHEN);
-           timeq_add(now + chanserv_conf.adjust_delay, chanserv_adjust_limit, cData);
-       }
+        /* Allow for a bit of padding so that the limit doesn't
+           track the user count exactly, which could get annoying. */
+        if((mn->channel->limit - mn->channel->members.used) > chanserv_conf.adjust_threshold + 5)
+        {
+            timeq_del(0, chanserv_adjust_limit, cData, TIMEQ_IGNORE_WHEN);
+            timeq_add(now + chanserv_conf.adjust_delay, chanserv_adjust_limit, cData);
+        }
     }
 
     if((uData = GetTrueChannelAccess(cData, mn->user->handle_info)))
     {
-       scan_user_presence(uData, mn->user);
+        scan_user_presence(uData, mn->user);
         uData->seen = now;
         if (uData->access >= UL_PRESENT)
             cData->visited = now; 
-   }
+    }
 
     if(IsHelping(mn->user) && IsSupportHelper(mn->user))
     {
         unsigned int ii;
-        for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii)
-             if(find_handle_in_channel(chanserv_conf.support_channels.list[ii], mn->user->handle_info, mn->user))
+        for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii) 
+        {
+            struct chanNode *channel;
+            struct userNode *exclude;
+            /* When looking at the channel that is being /part'ed, we
+             * have to skip over the client that is leaving.  For
+             * other channels, we must not do that.
+             */
+            channel = chanserv_conf.support_channels.list[ii];
+            exclude = (channel == mn->channel) ? mn->user : NULL;
+            if(find_handle_in_channel(channel, mn->user->handle_info, exclude))
                 break;
-         if(ii == chanserv_conf.support_channels.used)
+        }
+        if(ii == chanserv_conf.support_channels.used)
             HANDLE_CLEAR_FLAG(mn->user->handle_info, HELPING);
     }
 }
 
 static void
-handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *channel)
+handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *channel, UNUSED_ARG(void *extra))
 {
     struct userData *uData;
 
@@ -8732,7 +8829,7 @@ handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *c
     if(protect_user(victim, kicker, channel->channel_info, false))
     {
         const char *reason = user_find_message(kicker, "CSMSG_USER_PROTECTED_KICK");
-       KickChannelUser(kicker, channel, chanserv, reason);
+        KickChannelUser(kicker, channel, chanserv, reason);
     }
 
     if((uData = GetTrueChannelAccess(channel->channel_info, victim->handle_info)))
@@ -8740,7 +8837,7 @@ handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *c
 }
 
 static int
-handle_topic(struct userNode *user, struct chanNode *channel, const char *old_topic)
+handle_topic(struct userNode *user, struct chanNode *channel, const char *old_topic, UNUSED_ARG(void *extra))
 {
     struct chanData *cData;
 
@@ -8783,7 +8880,7 @@ handle_topic(struct userNode *user, struct chanNode *channel, const char *old_to
 }
 
 static void
-handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_chanmode *change)
+handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_chanmode *change, UNUSED_ARG(void *extra))
 {
     struct mod_chanmode *bounce = NULL;
     unsigned int bnc, ii;
@@ -8836,7 +8933,7 @@ handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_ch
         else if((change->args[ii].mode & (MODE_REMOVE | MODE_BAN)) == MODE_BAN)
         {
             const char *ban = change->args[ii].u.hostmask;
-            if(!bad_channel_ban(channel, user, ban, NULL, NULL))
+            if(bad_channel_ban(channel, user, ban, NULL, NULL) != 1)
                 continue;
             if(!bounce)
                 bounce = mod_chanmode_alloc(change->argc + 1 - ii);
@@ -8858,7 +8955,7 @@ handle_mode(struct chanNode *channel, struct userNode *user, const struct mod_ch
 }
 
 static void
-handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick))
+handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick), UNUSED_ARG(void *extra))
 {
     struct chanNode *channel;
     struct banData *bData;
@@ -8882,7 +8979,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick))
             continue;
         /* Look for a matching ban already on the channel. */
         for(jj = 0; jj < channel->banlist.used; ++jj)
-            if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK))
+            if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK, 0))
                 break;
         /* Need not act if we found one. */
         if(jj < channel->banlist.used)
@@ -8893,7 +8990,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick))
         /* Look for a matching ban in this channel. */
         for(bData = channel->channel_info->bans; bData; bData = bData->next)
         {
-            if(!user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE))
+            if(!user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE, 0))
                 continue;
             change.args[0].u.hostmask = bData->mask;
             mod_chanmode_announce(chanserv, channel, &change);
@@ -8905,7 +9002,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick))
     }
 }
 
-static void handle_rename(struct handle_info *handle, const char *old_handle)
+static void handle_rename(struct handle_info *handle, const char *old_handle, UNUSED_ARG(void *extra))
 {
     struct do_not_register *dnr = dict_find(handle_dnrs, old_handle, NULL);
 
@@ -8918,7 +9015,7 @@ static void handle_rename(struct handle_info *handle, const char *old_handle)
 }
 
 static void
-handle_unreg(UNUSED_ARG(struct userNode *user), struct handle_info *handle)
+handle_unreg(UNUSED_ARG(struct userNode *user), struct handle_info *handle, UNUSED_ARG(void *extra))
 {
     struct userNode *h_user;
 
@@ -8933,7 +9030,7 @@ handle_unreg(UNUSED_ARG(struct userNode *user), struct handle_info *handle)
 }
 
 static int 
-handle_server_link(UNUSED_ARG(struct server *server))
+handle_server_link(UNUSED_ARG(struct server *server), UNUSED_ARG(void *extra))
 {
     struct chanData *cData;
 
@@ -8966,8 +9063,8 @@ chanserv_conf_read(void)
 
     if(!(conf_node = conf_get_data(CHANSERV_CONF_NAME, RECDB_OBJECT)))
     {
-       log_module(CS_LOG, LOG_ERROR, "Invalid config node `%s'.", CHANSERV_CONF_NAME);
-       return;
+        log_module(CS_LOG, LOG_ERROR, "Invalid config node `%s'.", CHANSERV_CONF_NAME);
+        return;
     }
     for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii)
         UnlockChannel(chanserv_conf.support_channels.list[ii]);
@@ -9059,7 +9156,8 @@ chanserv_conf_read(void)
         int err = regcomp(&chanserv_conf.valid_channel_regex, str, REG_EXTENDED|REG_ICASE|REG_NOSUB);
         chanserv_conf.valid_channel_regex_set = !err;
         if (err) log_module(CS_LOG, LOG_ERROR, "Bad valid_channel_regex (error %d)", err);
-    } else {
+    } 
+    else {
         chanserv_conf.valid_channel_regex_set = 0;
     }
     free_string_list(chanserv_conf.wheel);
@@ -9203,15 +9301,15 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 
     if(rd->type != RECDB_OBJECT || !dict_size(rd->d.object))
     {
-       log_module(CS_LOG, LOG_ERROR, "Invalid user in %s.", chan->channel->name);
-       return;
+        log_module(CS_LOG, LOG_ERROR, "Invalid user in %s.", chan->channel->name);
+        return;
     }
 
     access_level = atoi(database_get_data(rd->d.object, KEY_LEVEL, RECDB_QSTRING));
     if(access_level > UL_OWNER)
     {
-       log_module(CS_LOG, LOG_ERROR, "Invalid access level for %s in %s.", key, chan->channel->name);
-       return;
+        log_module(CS_LOG, LOG_ERROR, "Invalid access level for %s in %s.", key, chan->channel->name);
+        return;
     }
 
     inf = database_get_data(rd->d.object, KEY_INFO, RECDB_QSTRING);
@@ -9269,14 +9367,14 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 static void
 ban_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 {
-    struct banData *bData;
+    //struct banData *bData;
     char *set, *triggered, *s_duration, *s_expires, *reason, *owner;
     time_t set_time, triggered_time, expires_time;
 
     if(rd->type != RECDB_OBJECT || !dict_size(rd->d.object))
     {
-       log_module(CS_LOG, LOG_ERROR, "Invalid ban in %s.", chan->channel->name);
-       return;
+        log_module(CS_LOG, LOG_ERROR, "Invalid ban in %s.", chan->channel->name);
+        return;
     }
 
     set = database_get_data(rd->d.object, KEY_SET, RECDB_QSTRING);
@@ -9300,7 +9398,7 @@ ban_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
     if(!reason || (expires_time && (expires_time < now)))
         return;
 
-    bData = add_channel_ban(chan, key, owner, set_time, triggered_time, expires_time, reason);
+    add_channel_ban(chan, key, owner, set_time, triggered_time, expires_time, reason);
 }
 
 static struct suspended *
@@ -9376,7 +9474,7 @@ chanserv_channel_read(const char *key, struct record_data *hir)
     if(!cData)
     {
         log_module(CS_LOG, LOG_ERROR, "Unable to register channel %s from database.", key);
-       return 0;
+        return 0;
     }
 
     if((obj = database_get_data(channel, KEY_OPTIONS, RECDB_OBJECT)))
@@ -9414,7 +9512,7 @@ chanserv_channel_read(const char *key, struct record_data *hir)
         enum charOption chOpt;
         unsigned int count;
 
-       cData->flags = base64toint(str, 5);
+        cData->flags = base64toint(str, 5);
         count = strlen(str += 5);
         for(lvlOpt = 0; lvlOpt < NUM_LEVEL_OPTIONS; ++lvlOpt)
         {
@@ -9428,14 +9526,14 @@ chanserv_channel_read(const char *key, struct record_data *hir)
             }
             else switch(((count <= levelOptions[lvlOpt].old_idx) ? str : CHANNEL_DEFAULT_OPTIONS)[levelOptions[lvlOpt].old_idx])
             {
-            case 'c': lvl = UL_COOWNER; break;
-            case 'm': lvl = UL_MANAGER; break;
-            case 'n': lvl = UL_OWNER+1; break;
-            case 'o': lvl = UL_OP; break;
-            case 'p': lvl = UL_PEON; break;
-            case 'h': lvl = UL_HALFOP; break;
-            case 'w': lvl = UL_OWNER; break;
-            default: lvl = 0; break;
+                case 'c': lvl = UL_COOWNER; break;
+                case 'm': lvl = UL_MANAGER; break;
+                case 'n': lvl = UL_OWNER+1; break;
+                case 'o': lvl = UL_OP; break;
+                case 'p': lvl = UL_PEON; break;
+                case 'h': lvl = UL_HALFOP; break;
+                case 'w': lvl = UL_OWNER; break;
+                default: lvl = 0; break;
             }
             cData->lvlOpts[lvlOpt] = lvl;
         }
@@ -9516,9 +9614,10 @@ chanserv_channel_read(const char *key, struct record_data *hir)
     if(!IsSuspended(cData)
        && (str = database_get_data(channel, KEY_MODES, RECDB_QSTRING))
        && (argc = split_line(str, 0, ArrayLength(argv), argv))
-       && (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE, 0))) {
+       && (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE, 0))) 
+    {
         cData->modes = *modes;
-       if(off_channel > 0)
+        if(off_channel > 0)
           cData->modes.modes_set |= MODE_REGISTERED;
         if(cData->modes.argc > 1)
             cData->modes.argc = 1;
@@ -9528,12 +9627,12 @@ chanserv_channel_read(const char *key, struct record_data *hir)
 
     obj = database_get_data(channel, KEY_USERS, RECDB_OBJECT);
     for(it = dict_first(obj); it; it = iter_next(it))
-       user_read_helper(iter_key(it), iter_data(it), cData);
+    user_read_helper(iter_key(it), iter_data(it), cData);
 
     if(!cData->users && !IsProtected(cData))
     {
         log_module(CS_LOG, LOG_ERROR, "Channel %s had no users in database, unregistering it.", key);
-       unregister_channel(cData, "has empty user list.");
+        unregister_channel(cData, "has empty user list.");
         return 0;
     }
 
@@ -9629,8 +9728,8 @@ chanserv_saxdb_read(struct dict *database)
             chanserv_note_type_read(iter_key(it), iter_data(it));
 
     if((section = database_get_data(database, KEY_CHANNELS, RECDB_OBJECT)))
-       for(it = dict_first(section); it; it = iter_next(it))
-           chanserv_channel_read(iter_key(it), iter_data(it));
+    for(it = dict_first(section); it; it = iter_next(it))
+        chanserv_channel_read(iter_key(it), iter_data(it));
 
     if((section = database_get_data(database, KEY_DNR, RECDB_OBJECT)))
         for(it = dict_first(section); it; it = iter_next(it))
@@ -9658,7 +9757,7 @@ chanserv_write_users(struct saxdb_context *ctx, struct userData *uData)
             saxdb_write_int(ctx, KEY_FLAGS, uData->flags);
         if(uData->expires)
             saxdb_write_int(ctx, KEY_EXPIRES, uData->expires);
-       if(uData->info)
+        if(uData->info)
             saxdb_write_string(ctx, KEY_INFO, uData->info);
         saxdb_end_record(ctx);
     }
@@ -9771,7 +9870,7 @@ chanserv_write_channel(struct saxdb_context *ctx, struct chanData *channel)
 
     if(channel->modes.modes_set || channel->modes.modes_clear)
     {
-       mod_chanmode_format(&channel->modes, buf);
+        mod_chanmode_format(&channel->modes, buf);
         saxdb_write_string(ctx, KEY_MODES, buf);
     }
 
@@ -9785,7 +9884,7 @@ chanserv_write_channel(struct saxdb_context *ctx, struct chanData *channel)
         saxdb_start_record(ctx, KEY_NOTES, 1);
         for(it = dict_first(channel->notes); it; it = iter_next(it))
         {
-           struct note *note = iter_data(it);
+        struct note *note = iter_data(it);
             saxdb_start_record(ctx, iter_key(it), 0);
             saxdb_write_string(ctx, KEY_NOTE_SETTER, note->setter);
             saxdb_write_string(ctx, KEY_NOTE_NOTE, note->note);
@@ -9864,7 +9963,7 @@ chanserv_saxdb_write(struct saxdb_context *ctx)
 
     /* Version Control*/
     saxdb_start_record(ctx, KEY_VERSION_CONTROL, 1);
-      saxdb_write_int(ctx, KEY_VERSION_NUMBER, CHANSERV_DB_VERSION);
+    saxdb_write_int(ctx, KEY_VERSION_NUMBER, CHANSERV_DB_VERSION);
     saxdb_end_record(ctx);
 
     /* Notes */
@@ -9890,9 +9989,9 @@ chanserv_saxdb_write(struct saxdb_context *ctx)
 }
 
 static void
-chanserv_db_cleanup(void) {
+chanserv_db_cleanup(UNUSED_ARG(void *extra)) {
     unsigned int ii;
-    unreg_part_func(handle_part);
+    unreg_part_func(handle_part, NULL);
     while(channelList)
         unregister_channel(channelList, "terminating.");
     for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii)
@@ -9934,19 +10033,19 @@ init_chanserv(const char *nick)
     conf_register_reload(chanserv_conf_read);
 
     if (nick) {
-        reg_server_link_func(handle_server_link);
-        reg_new_channel_func(handle_new_channel);
-        reg_join_func(handle_join);
-        reg_part_func(handle_part);
-        reg_kick_func(handle_kick);
-        reg_topic_func(handle_topic);
-        reg_mode_change_func(handle_mode);
-        reg_nick_change_func(handle_nick_change);
-        reg_auth_func(handle_auth);
+        reg_server_link_func(handle_server_link, NULL);
+        reg_new_channel_func(handle_new_channel, NULL);
+        reg_join_func(handle_join, NULL);
+        reg_part_func(handle_part, NULL);
+        reg_kick_func(handle_kick, NULL);
+        reg_topic_func(handle_topic, NULL);
+        reg_mode_change_func(handle_mode, NULL);
+        reg_nick_change_func(handle_nick_change, NULL);
+        reg_auth_func(handle_auth, NULL);
     }
 
-    reg_handle_rename_func(handle_rename);
-    reg_unreg_func(handle_unreg);
+    reg_handle_rename_func(handle_rename, NULL);
+    reg_unreg_func(handle_unreg, NULL);
 
     handle_dnrs = dict_new();
     dict_set_free_data(handle_dnrs, free);
@@ -9955,7 +10054,7 @@ init_chanserv(const char *nick)
     mask_dnrs = dict_new();
     dict_set_free_data(mask_dnrs, free);
 
-    reg_svccmd_unbind_func(handle_svccmd_unbind);
+    reg_svccmd_unbind_func(handle_svccmd_unbind, NULL);
     chanserv_module = module_register("ChanServ", CS_LOG, "chanserv.help", chanserv_expand_variable);
     DEFINE_COMMAND(register, 1, MODCMD_REQUIRE_AUTHED, "flags", "+acceptchan,+channel", NULL);
     DEFINE_COMMAND(noregister, 1, MODCMD_REQUIRE_AUTHED, "flags", "+helping", NULL);
@@ -9965,8 +10064,8 @@ init_chanserv(const char *nick)
     modcmd_register(chanserv_module, "dnrsearch remove", NULL, 0, 0, NULL);
     modcmd_register(chanserv_module, "dnrsearch count", NULL, 0, 0, NULL);
     DEFINE_COMMAND(move, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN, "template", "register", NULL);
-    DEFINE_COMMAND(csuspend, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN, "flags", "+helping", NULL);
-    DEFINE_COMMAND(cunsuspend, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN, "flags", "+helping", NULL);
+    DEFINE_COMMAND(csuspend, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN|MODCMD_IGNORE_CSUSPEND, "flags", "+helping", NULL);
+    DEFINE_COMMAND(cunsuspend, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_REGCHAN|MODCMD_IGNORE_CSUSPEND, "flags", "+helping", NULL);
     DEFINE_COMMAND(createnote, 5, 0, "level", "800", NULL);
     DEFINE_COMMAND(removenote, 2, 0, "level", "800", NULL);
 
@@ -10126,13 +10225,13 @@ init_chanserv(const char *nick)
         const char *modes = conf_get_data("services/chanserv/modes", RECDB_QSTRING);
         chanserv = AddLocalUser(nick, nick, NULL, "Channel Services", modes);
         service_register(chanserv)->trigger = '!';
-        reg_chanmsg_func('\001', chanserv, chanserv_ctcp_check);
+        reg_chanmsg_func('\001', chanserv, chanserv_ctcp_check, NULL);
     }
 
     saxdb_register("ChanServ", chanserv_saxdb_read, chanserv_saxdb_write);
 
     if(chanserv_conf.channel_expire_frequency)
-       timeq_add(now + chanserv_conf.channel_expire_frequency, expire_channels, NULL);
+    timeq_add(now + chanserv_conf.channel_expire_frequency, expire_channels, NULL);
 
     if(chanserv_conf.dnr_expire_frequency)
         timeq_add(now + chanserv_conf.dnr_expire_frequency, expire_dnrs, NULL);
@@ -10155,7 +10254,7 @@ init_chanserv(const char *nick)
         }    
     }
 
-    reg_exit_func(chanserv_db_cleanup);
+    reg_exit_func(chanserv_db_cleanup, NULL);
     message_register_table(msgtab);
 }