Re-fix compilation of src/modcmd.c.
[srvx.git] / src / opserv.c
index 30ef2f02d3fe2d4621455d2d2340b3ae1bdfd3a8..38ad356ee2d84bbc14fbe97b3156460d054ed2da 100644 (file)
@@ -201,7 +201,9 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_GLINE_SEARCH_RESULTS", "The following glines were found:" },
     { "OSMSG_LOG_SEARCH_RESULTS", "The following log entries were found:" },
     { "OSMSG_GSYNC_RUNNING", "Synchronizing glines from %s." },
-    { "OSMSG_GTRACE_FORMAT", "%s (issued %s by %s, lastmod %s, expires %s): %s" },
+    { "OSMSG_GTRACE_FORMAT", "%1$s (issued %2$s ago by %3$s, lastmod %4$s ago, expires %5$s, lifetime %7$s): %6$s" },
+    { "OSMSG_GTRACE_FOREVER", "%1$s (issued %2$s ago by %3$s, lastmod %4$s ago, never expires, lifetime %7$s): %6$s" },
+    { "OSMSG_GTRACE_EXPIRED", "%1$s (issued %2$s ago by %3$s, lastmod %4$s ago, expired %5$s ago, lifetime %7$s): %6$s" },
     { "OSMSG_GAG_APPLIED", "Gagged $b%s$b, affecting %d users." },
     { "OSMSG_GAG_ADDED", "Gagged $b%s$b." },
     { "OSMSG_REDUNDANT_GAG", "Gag $b%s$b is redundant." },
@@ -442,8 +444,10 @@ static MODCMD_FUNC(cmd_chaninfo)
     const char *fmt;
     struct banNode *ban;
     struct modeNode *moden;
+    struct modeNode **members;
     time_t feh;
     unsigned int n;
+    int show_oplevels;
 
     reply("OSMSG_CHANINFO_HEADER", channel->name);
     fmt = user_find_message(user, "OSMSG_CHANINFO_TIMESTAMP");
@@ -480,25 +484,30 @@ static MODCMD_FUNC(cmd_chaninfo)
         return 1;
     }
     reply("OSMSG_CHANINFO_USER_COUNT", channel->members.used);
+
+    /* Create and sort the members array. */
+    members = alloca(channel->members.used * sizeof(members[0]));
+    for (n=0; n<channel->members.used; n++)
+        members[n] = channel->members.list[n];
+    qsort(members, channel->members.used, sizeof(members[0]), modeNode_sort);
+
+    /* Display the array. */
+    show_oplevels = (channel->members.used != 0)
+        && (members[0]->modes & MODE_CHANOP)
+        && (members[0]->oplevel < MAXOPLEVEL);
     for (n=0; n<channel->members.used; n++) {
-        moden = channel->members.list[n];
+        moden = members[n];
         if (moden->modes & MODE_CHANOP) {
-            if (moden->oplevel >= 0)
+            if (show_oplevels)
                 send_message_type(4, user, cmd->parent->bot, " @%s:%d (%s@%s)", moden->user->nick, moden->oplevel, moden->user->ident, moden->user->hostname);
             else
                 send_message_type(4, user, cmd->parent->bot, " @%s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname);
-        }
-    }
-    for (n=0; n<channel->members.used; n++) {
-        moden = channel->members.list[n];
-        if ((moden->modes & (MODE_CHANOP|MODE_VOICE)) == MODE_VOICE)
+        } else if (moden->modes & MODE_VOICE)
             send_message_type(4, user, cmd->parent->bot, " +%s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname);
-    }
-    for (n=0; n<channel->members.used; n++) {
-        moden = channel->members.list[n];
-        if ((moden->modes & (MODE_CHANOP|MODE_VOICE)) == 0)
+        else
             send_message_type(4, user, cmd->parent->bot, "  %s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname);
     }
+
     return 1;
 }
 
@@ -570,7 +579,7 @@ static MODCMD_FUNC(cmd_clearmodes)
         return 0;
     }
     mod_chanmode_init(&change);
-    change.modes_clear = channel->modes;
+    change.modes_clear = channel->modes & ~MODE_REGISTERED;
     modcmd_chanmode_announce(&change);
     reply("OSMSG_CLEARMODES_DONE", channel->name);
     return 1;
@@ -782,7 +791,7 @@ opserv_block(struct userNode *target, char *src_handle, char *reason, unsigned l
                  "G-line requested by %s.", src_handle);
     if (!duration)
         duration = opserv_conf.block_gline_duration;
-    return gline_add(src_handle, mask, duration, reason, now, now, 1);
+    return gline_add(src_handle, mask, duration, reason, now, now, 0, 1);
 }
 
 static MODCMD_FUNC(cmd_block)
@@ -856,7 +865,7 @@ static MODCMD_FUNC(cmd_gline)
         reply("MSG_INVALID_DURATION", argv[2]);
         return 0;
     }
-    gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, now, 1);
+    gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, now, 0, 1);
     reply("OSMSG_GLINE_ISSUED", gline->target);
     return 1;
 }
@@ -1015,6 +1024,10 @@ static MODCMD_FUNC(cmd_kick)
         reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name);
         return 0;
     }
+    if (IsService(target)) {
+        reply("MSG_SERVICE_IMMUNE", target->nick);
+        return 0;
+    }
     KickChannelUser(target, channel, cmd->parent->bot, reason);
     return 1;
 }
@@ -1871,7 +1884,7 @@ opserv_new_user_check(struct userNode *user)
         } else if (ohi->clients.used > limit) {
             char target[IRC_NTOP_MAX_SIZE + 3] = { '*', '@', '\0' };
             strcpy(target + 2, addr);
-            gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "AUTO Excessive connections from a single host.", now, now, 1);
+            gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "AUTO Excessive connections from a single host.", now, now, 0, 1);
         }
     }
 }
@@ -3790,17 +3803,23 @@ gtrace_print_func(struct gline *gline, void *extra)
     char issued[INTERVALLEN];
     char lastmod[INTERVALLEN];
     char expires[INTERVALLEN];
+    char lifetime[INTERVALLEN];
 
     intervalString(issued, now - gline->issued, xtra->user->handle_info);
     if (gline->lastmod)
         intervalString(lastmod, now - gline->lastmod, xtra->user->handle_info);
     else
         strcpy(lastmod, "<unknown>");
-    if (gline->expires)
+    intervalString(lifetime, gline->lifetime - now, xtra->user->handle_info);
+    if (!gline->expires) {
+        send_message(xtra->user, opserv, "OSMSG_GTRACE_FOREVER", gline->target, issued, gline->issuer, lastmod, NULL, gline->reason, lifetime);
+    } else if (gline->expires < now) {
+        intervalString(expires, now - gline->expires, xtra->user->handle_info);
+        send_message(xtra->user, opserv, "OSMSG_GTRACE_EXPIRED", gline->target, issued, gline->issuer, lastmod, expires, gline->reason, lifetime);
+    } else { /* must be in the future */
         intervalString(expires, gline->expires - now, xtra->user->handle_info);
-    else
-        strcpy(expires, "never");
-    send_message(xtra->user, opserv, "OSMSG_GTRACE_FORMAT", gline->target, issued, gline->issuer, lastmod, expires, gline->reason);
+        send_message(xtra->user, opserv, "OSMSG_GTRACE_FORMAT", gline->target, issued, gline->issuer, lastmod, expires, gline->reason, lifetime);
+    }
 }
 
 static MODCMD_FUNC(cmd_stats_glines) {