{ "OSMSG_BADWORD_LIST", "Bad words: %s" },
{ "OSMSG_EXEMPTED_LIST", "Exempted channels: %s" },
{ "OSMSG_GLINE_COUNT", "There are %d glines active on the network." },
+ { "OSMSG_NO_GLINE", "$b%s$b is not a known G-line." },
{ "OSMSG_LINKS_SERVER", "%s%s (%u clients; %s)" },
{ "OSMSG_MAX_CLIENTS", "Max clients: %d at %s" },
{ "OSMSG_NETWORK_INFO", "Total users: %d (%d invisible, %d opers)" },
{ "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, expires %s): %s" },
+ { "OSMSG_GTRACE_FORMAT", "%s (issued %s by %s, lastmod %s, expires %s): %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." },
}
reply("OSMSG_CHANINFO_USER_COUNT", channel->members.used);
for (n=0; n<channel->members.used; n++) {
- moden = channel->members.list[n];
- if (moden->modes & MODE_CHANOP)
- send_message_type(4, user, cmd->parent->bot, " @%s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname);
+ moden = channel->members.list[n];
+ if (moden->modes & MODE_CHANOP) {
+ if (moden->oplevel >= 0)
+ 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];
return 1;
}
-static MODCMD_FUNC(cmd_warn)
+static MODCMD_FUNC(cmd_warn)
{
char *reason, *message;
static struct gline *
opserv_block(struct userNode *target, char *src_handle, char *reason, unsigned long duration)
{
- char *mask;
- mask = alloca(MAXLEN);
- snprintf(mask, MAXLEN, "*@%s", target->hostname);
- if (!reason) {
- reason = alloca(MAXLEN);
- snprintf(reason, MAXLEN, "G-line requested by %s.", src_handle);
- }
- if (!duration) duration = opserv_conf.block_gline_duration;
- return gline_add(src_handle, mask, duration, reason, now, 1);
+ char mask[IRC_NTOP_MAX_SIZE+3] = { '*', '@', '\0' };
+ irc_ntop(mask + 2, sizeof(mask) - 2, &target->ip);
+ if (!reason)
+ snprintf(reason = alloca(MAXLEN), MAXLEN,
+ "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);
}
static MODCMD_FUNC(cmd_block)
struct userNode *target;
struct gline *gline;
char *reason;
+ unsigned long duration = 0;
+ unsigned int offset = 2;
target = GetUserH(argv[1]);
if (!target) {
- reply("MSG_NICK_UNKNOWN", argv[1]);
- return 0;
+ reply("MSG_NICK_UNKNOWN", argv[1]);
+ return 0;
}
if (IsService(target)) {
- reply("MSG_SERVICE_IMMUNE", target->nick);
- return 0;
+ reply("MSG_SERVICE_IMMUNE", target->nick);
+ return 0;
+ }
+ if(argc > 2 && (duration = ParseInterval(argv[2]))) {
+ offset = 3;
}
- reason = (argc > 2) ? unsplit_string(argv+2, argc-2, NULL) : NULL;
- gline = opserv_block(target, user->handle_info->handle, reason, 0);
+ reason = (argc > offset) ? unsplit_string(argv+offset, argc-offset, NULL) : NULL;
+ gline = opserv_block(target, user->handle_info->handle, reason, duration);
reply("OSMSG_GLINE_ISSUED", gline->target);
return 1;
}
reply("MSG_INVALID_DURATION", argv[2]);
return 0;
}
- gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, 1);
+ gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, now, 1);
reply("OSMSG_GLINE_ISSUED", gline->target);
return 1;
}
if (!inchan)
DelChannelUser(bot, channel, "My work here is done", 0);
reply("OSMSG_KICKALL_DONE", channel->name);
- return 1;
+ return 1;
}
static MODCMD_FUNC(cmd_part)
if (IsWallOp(target)) buffer[bpos++] = 'w';
if (IsOper(target)) buffer[bpos++] = 'o';
if (IsGlobal(target)) buffer[bpos++] = 'g';
- if (IsServNotice(target)) buffer[bpos++] = 's';
- if (IsHelperIrcu(target)) buffer[bpos++] = 'h';
if (IsService(target)) buffer[bpos++] = 'k';
if (IsDeaf(target)) buffer[bpos++] = 'd';
+ if (IsNoChan(target)) buffer[bpos++] = 'n';
if (IsHiddenHost(target)) buffer[bpos++] = 'x';
+ if (IsNoIdle(target)) buffer[bpos++] = 'I';
if (IsGagged(target)) buffer_cat(" (gagged)");
if (IsRegistering(target)) buffer_cat(" (registered account)");
buffer[bpos] = 0;
return 1;
}
-static MODCMD_FUNC(cmd_stats_glines) {
- reply("OSMSG_GLINE_COUNT", gline_count());
- return 1;
-}
-
static void
trace_links(struct userNode *bot, struct userNode *user, struct server *server, unsigned int depth) {
unsigned int nn, pos;
}
static MODCMD_FUNC(cmd_stats_uptime) {
+ extern int lines_processed;
+ extern time_t boot_time;
+ double kernel_time;
+ double user_time;
char uptime[INTERVALLEN];
+
+#if defined(HAVE_TIMES)
+ static double clocks_per_sec;
struct tms buf;
- extern time_t boot_time;
- extern int lines_processed;
- static long clocks_per_sec;
if (!clocks_per_sec) {
#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
clocks_per_sec = CLOCKS_PER_SEC;
}
}
- intervalString(uptime, time(NULL)-boot_time, user->handle_info);
times(&buf);
- reply("OSMSG_UPTIME_STATS",
- uptime, lines_processed,
- buf.tms_utime/(double)clocks_per_sec,
- buf.tms_stime/(double)clocks_per_sec);
+ user_time = buf.tms_utime / clocks_per_sec;
+ kernel_time = buf.tms_stime / clocks_per_sec;
+#elif defined(HAVE_GETPROCESSTIMES)
+ FILETIME times[4];
+ LARGE_INTEGER li[2];
+
+ GetProcessTimes(GetCurrentProcess(), ×[0], ×[1], ×[2], ×[3]);
+ li[0].LowPart = times[2].dwLowDateTime;
+ li[0].HighPart = times[2].dwHighDateTime;
+ kernel_time = li[0].QuadPart * 1e-7;
+ li[1].LowPart = times[3].dwLowDateTime;
+ li[1].HighPart = times[3].dwHighDateTime;
+ user_time = li[1].QuadPart * 1e-7;
+#else
+ user_time = NAN;
+ system_time = NAN;
+#endif
+
+ intervalString(uptime, time(NULL)-boot_time, user->handle_info);
+ reply("OSMSG_UPTIME_STATS", uptime, lines_processed, user_time, kernel_time);
return 1;
}
return NULL;
}
}
- if ((resv = AddClone(nick, ident, host, desc))) {
+ if ((resv = AddLocalUser(nick, ident, host, desc, "+i"))) {
dict_insert(opserv_reserved_nick_dict, resv->nick, resv);
}
return resv;
/* Gag them if appropriate. */
for (gag = gagList; gag; gag = gag->next) {
- if (user_matches_glob(user, gag->mask, 1)) {
+ if (user_matches_glob(user, gag->mask, MATCH_USENICK)) {
gag_helper_func(user, NULL);
break;
}
for (nn=0; nn<ohi->clients.used; nn++)
send_message(ohi->clients.list[nn], opserv, "OSMSG_CLONE_WARNING");
} else if (ohi->clients.used > limit) {
- char target[18];
- sprintf(target, "*@%s", addr);
- gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "AUTO Excessive connections from a single host.", now, 1);
+ 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);
}
}
struct mod_chanmode change;
mod_chanmode_init(&change);
channel->join_flooded = 1;
- if (opserv_conf.join_flood_moderate && (channel->members.used > opserv_conf.join_flood_moderate_threshold)) {
+ if (opserv && opserv_conf.join_flood_moderate && (channel->members.used > opserv_conf.join_flood_moderate_threshold)) {
if (!GetUserMode(channel, opserv)) {
/* If we aren't in the channel, join it. */
change.args[0].mode = MODE_CHANOP;
reply("OSMSG_NOT_A_HOSTMASK");
return 0;
}
- if (!(clone = AddClone(argv[2], ident, argv[3]+i, userinfo))) {
+ if (!(clone = AddLocalUser(argv[2], ident, argv[3]+i, userinfo, "+i"))) {
reply("OSMSG_CLONE_FAILED", argv[2]);
return 0;
}
log_module(OS_LOG, LOG_ERROR, "Missing description for reserve of %s", key);
return 0;
}
- if ((reserve = AddClone(key, ident, hostname, desc))) {
+ if ((reserve = AddLocalUser(key, ident, hostname, desc, "+i"))) {
reserve->modes |= FLAGS_PERSISTENT;
dict_insert(extra, reserve->nick, reserve);
}
discrim->max_ts = now - (ParseInterval(cmp+1) - 1);
}
} else {
- discrim->min_ts = now - ParseInterval(cmp+2);
+ discrim->min_ts = now - ParseInterval(cmp);
}
} else if (irccasecmp(argv[i], "access") == 0) {
const char *cmp = argv[++i];
discrim->min_level = strtoul(cmp+1, NULL, 0) + 1;
}
} else {
- discrim->min_level = strtoul(cmp+2, NULL, 0);
+ discrim->min_level = strtoul(cmp, NULL, 0);
}
} else if ((irccasecmp(argv[i], "abuse") == 0)
&& (irccasecmp(argv[++i], "opers") == 0)) {
discrim = calloc(1, sizeof(*discrim));
discrim->limit = 25;
+ discrim->max_users = ~0;
+ /* So, time_t is frequently signed. Fun. */
+ discrim->max_ts = (1ul << (CHAR_BIT * sizeof(time_t) - 1)) - 1;
for (i = 0; i < argc; i++) {
/* Assume all criteria require arguments. */
else
discrim->min_users = strtoul(cmp+1, NULL, 0) + 1;
} else {
- discrim->min_users = strtoul(cmp+2, NULL, 0);
+ discrim->min_users = strtoul(cmp, NULL, 0);
}
} else if (!irccasecmp(argv[i], "timestamp")) {
const char *cmp = argv[++i];
{
if ((discrim->name && !match_ircglob(chan->name, discrim->name)) ||
(discrim->topic && !match_ircglob(chan->topic, discrim->topic)) ||
- (discrim->min_users && chan->members.used < discrim->min_users) ||
- (discrim->max_users && chan->members.used > discrim->max_users) ||
- (discrim->min_ts && chan->timestamp < discrim->min_ts) ||
- (discrim->max_ts && chan->timestamp > discrim->max_ts)) {
+ (chan->members.used < discrim->min_users) ||
+ (chan->members.used > discrim->max_users) ||
+ (chan->timestamp < discrim->min_ts) ||
+ (chan->timestamp > discrim->max_ts)) {
return 0;
}
return 1;
gtrace_print_func(struct gline *gline, void *extra)
{
struct gline_extra *xtra = extra;
- char *when_text, set_text[20];
- strftime(set_text, sizeof(set_text), "%Y-%m-%d", localtime(&gline->issued));
- when_text = asctime(localtime(&gline->expires));
- when_text[strlen(when_text)-1] = 0; /* strip lame \n */
- send_message(xtra->user, opserv, "OSMSG_GTRACE_FORMAT", gline->target, set_text, gline->issuer, when_text, gline->reason);
+ char issued[INTERVALLEN];
+ char lastmod[INTERVALLEN];
+ char expires[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(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);
+}
+
+static MODCMD_FUNC(cmd_stats_glines) {
+ if (argc < 2) {
+ reply("OSMSG_GLINE_COUNT", gline_count());
+ return 1;
+ } else if (argc < 3) {
+ struct gline_extra extra;
+ struct gline *gl;
+
+ extra.user = user;
+ gl = gline_find(argv[1]);
+ if (!gl)
+ reply("OSMSG_NO_GLINE", argv[1]);
+ else
+ gtrace_print_func(gl, &extra);
+ return 1;
+ } else return 0;
}
static void
/* Gag them if appropriate (and only if). */
user->modes &= ~FLAGS_GAGGED;
for (gag = gagList; gag; gag = gag->next) {
- if (user_matches_glob(user, gag->mask, 1)) {
+ if (user_matches_glob(user, gag->mask, MATCH_USENICK)) {
gag_helper_func(user, NULL);
break;
}
OS_LOG = log_register_type("OpServ", "file:opserv.log");
if (nick) {
const char *modes = conf_get_data("services/opserv/modes", RECDB_QSTRING);
- opserv = AddService(nick, modes ? modes : NULL, "Oper Services", NULL);
+ opserv = AddLocalUser(nick, nick, NULL, "Oper Services", modes);
}
conf_register_reload(opserv_conf_read);