Merge branch 'master' into SpamServ
authorNurPech <nurpech@nurpech.de>
Mon, 20 May 2013 03:02:32 +0000 (05:02 +0200)
committerNurPech <nurpech@nurpech.de>
Mon, 20 May 2013 03:08:37 +0000 (05:08 +0200)
14 files changed:
src/Makefile.am
src/chanserv.c
src/chanserv.h
src/chanserv.help
src/hash.h
src/log.c
src/mod-watchdog.c
src/modcmd.c
src/nickserv.h
src/opserv.c
src/proto-p10.c
src/proto.h
src/spamserv.c
srvx.conf.example

index 75c599ae61c32645e8ee43dc6d45a56b1c2ae9f8..4c20c6fb4844d8be78c27f028046f6c74af9fd0a 100644 (file)
@@ -27,10 +27,13 @@ git-version.c: checkversion
 
 if HAS_GIT
 checkversion:
-       @GIT_VERSION=`$(GIT) describe`; \
+       @GIT_VERSION=`$(GIT) log -n 1 --pretty="format:%h"`; \
        [ "z$$GIT_VERSION" != "z" ] || exit 0; \
        TMPFILE=`mktemp git-version.c.XXXXXX` || exit 1 ; \
-       echo "const char git_version[] = \"$${GIT_VERSION}\";" >> $$TMPFILE ; \
+       GIT_LASTCOMMIT=$$GIT_VERSION; \
+    GIT_COMMITCOUNT=`$(GIT) rev-list --all | wc -l | sed "s/[ \t]//g"`; \
+    GIT_REVISION="git-$${GIT_COMMITCOUNT}-$${GIT_LASTCOMMIT}"; \
+    echo "const char git_version[] = \"$${GIT_REVISION}\";" >> $$TMPFILE ; \
        if diff -q git-version.c $$TMPFILE >/dev/null 2>&1 ; then \
            rm $$TMPFILE ; \
         else \
@@ -40,7 +43,7 @@ checkversion:
        fi
 else
 checkversion:
-       echo "const char git_version[] = \"\";" >> git-version.c ;
+       echo "const char git_version[] = \"git-0-0\";" >> git-version.c ;
 endif
 
 EXTRA_srvx_SOURCES = \
index 887b95aaa3c4e8ffb8b40ed44f42d253894bf04a..3ddfaf6874822d50451a596628451b53c73dcef1 100644 (file)
@@ -43,6 +43,7 @@
 #define KEY_DNR_EXPIRE_FREQ         "dnr_expire_freq"
 #define KEY_MAX_CHAN_USERS          "max_chan_users"
 #define KEY_MAX_CHAN_BANS           "max_chan_bans"
+#define KEY_MIN_TIME_BANS                      "min_time_bans"
 #define KEY_NICK                    "nick"
 #define KEY_OLD_CHANSERV_NAME       "old_chanserv_name"
 #define KEY_8BALL_RESPONSES         "8ball"
@@ -581,6 +582,7 @@ static struct
     unsigned int    max_owned;
     unsigned int    max_chan_users;
     unsigned int    max_chan_bans;
+    unsigned int    min_time_bans;
     unsigned int    max_userinfo_length;
     
     unsigned int    revoke_mode_a;
@@ -3476,7 +3478,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
         {
             duration = ParseInterval(argv[2]);
 
-            if(duration < 15)
+            if(duration < chanserv_conf.min_time_bans)
             {
                 reply("CSMSG_DURATION_TOO_LOW");
                 free(ban);
@@ -4167,6 +4169,8 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg
         ary[1] = uData->handle->handle;
         if(uData->present)
             ary[2] = "Here";
+        else if(HANDLE_FLAGGED(uData->handle, NETWORK))
+             ary[2] = "Here";
         else if(!uData->seen)
             ary[2] = "Never";
         else
@@ -4174,6 +4178,12 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg
         ary[2] = strdup(ary[2]);
         if(IsUserSuspended(uData))
             ary[3] = "Suspended";
+        else if(HANDLE_FLAGGED(uData->handle, OPER))
+            ary[3] = "Operator";
+        else if(HANDLE_FLAGGED(uData->handle, HELPING))
+            ary[3] = "Staff";
+        else if(HANDLE_FLAGGED(uData->handle, NETWORK))
+            ary[3] = "Network";
         else if(HANDLE_FLAGGED(uData->handle, FROZEN))
             ary[3] = "Vacation";
         else if(HANDLE_FLAGGED(uData->handle, BOT))
@@ -6573,13 +6583,23 @@ static CHANSERV_FUNC(cmd_giveownership)
     return 1;
 }
 
+static void
+chanserv_expire_user_suspension(void *data)
+{
+    struct userData *target = data;
+
+       target->expires = 0;
+       target->flags &= ~USER_SUSPENDED;       
+}
+
 static CHANSERV_FUNC(cmd_suspend)
 {
     struct handle_info *hi;
     struct userData *actor, *real_actor, *target;
     unsigned int override = 0;
+    time_t expiry;
 
-    REQUIRE_PARAMS(2);
+    REQUIRE_PARAMS(3);
     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);
@@ -6605,6 +6625,24 @@ static CHANSERV_FUNC(cmd_suspend)
     }
     if(!real_actor || target->access >= real_actor->access)
         override = CMD_LOG_OVERRIDE;
+       if(!strcmp(argv[2], "0"))
+        expiry = 0;
+    else
+    {
+        unsigned int duration;
+        if(!(duration = ParseInterval(argv[2])))
+        {
+            reply("MSG_INVALID_DURATION", argv[2]);
+            return 0;
+        }
+        expiry = now + duration;
+    }
+
+       target->expires = expiry;
+
+       if(target->expires)
+               timeq_add(target->expires, chanserv_expire_user_suspension, target);
+
     target->flags |= USER_SUSPENDED;
     reply("CSMSG_USER_SUSPENDED", hi->handle, channel->name);
     return 1 | override;
@@ -6637,6 +6675,7 @@ static CHANSERV_FUNC(cmd_unsuspend)
     }
     if(!real_actor || target->access >= real_actor->access)
         override = CMD_LOG_OVERRIDE;
+    timeq_del(target->expires, chanserv_expire_user_suspension, target, 0);
     target->flags &= ~USER_SUSPENDED;
     scan_user_presence(target, NULL);
     reply("CSMSG_USER_UNSUSPENDED", hi->handle, channel->name);
@@ -7849,6 +7888,8 @@ chanserv_conf_read(void)
     chanserv_conf.max_chan_users = str ? atoi(str) : 512;
     str = database_get_data(conf_node, KEY_MAX_CHAN_BANS, RECDB_QSTRING);
     chanserv_conf.max_chan_bans = str ? atoi(str) : 512;
+    str = database_get_data(conf_node, KEY_MIN_TIME_BANS, RECDB_QSTRING);
+    chanserv_conf.min_time_bans = str ? atoi(str) : 5;
     str = database_get_data(conf_node, KEY_MAX_USERINFO_LENGTH, RECDB_QSTRING);
     chanserv_conf.max_userinfo_length = str ? atoi(str) : 400;
     str = database_get_data(conf_node, KEY_NICK, RECDB_QSTRING);
@@ -8023,7 +8064,7 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 {
     struct handle_info *handle;
     struct userData *uData;
-    char *seen, *inf, *flags, *voted, *votefor;
+    char *seen, *inf, *flags, *voted, *votefor, *expires;
     unsigned long last_seen;
     unsigned short access_level;
 
@@ -8044,6 +8085,7 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
     seen = database_get_data(rd->d.object, KEY_SEEN, RECDB_QSTRING);
     last_seen = seen ? strtoul(seen, NULL, 0) : now;
     flags = database_get_data(rd->d.object, KEY_FLAGS, RECDB_QSTRING);
+    expires = database_get_data(rd->d.object, KEY_EXPIRES, RECDB_QSTRING);
     voted = database_get_data(rd->d.object, KEY_VOTE_VOTED, RECDB_QSTRING);
     votefor = database_get_data(rd->d.object, KEY_VOTE_VOTEDFOR, RECDB_QSTRING);
     handle = get_handle_info(key);
@@ -8055,6 +8097,15 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 
     uData = add_channel_user(chan, handle, access_level, last_seen, inf);
     uData->flags = flags ? strtoul(flags, NULL, 0) : 0;
+       uData->expires = expires ? (signed)strtoul(expires, NULL, 0) : 0;
+
+       if((uData->flags & USER_SUSPENDED) && uData->expires)
+       {
+         if(uData->expires > now)
+                 timeq_add(uData->expires, chanserv_expire_user_suspension, uData);
+         else
+                 uData->flags &= ~USER_SUSPENDED;
+       }
     if(chan->vote) {
         uData->voted = voted ? strtoul(voted, NULL, 0) : 0;
         uData->votefor = votefor ? strtoul(votefor, NULL, 0) : 0;
@@ -8472,6 +8523,8 @@ chanserv_write_users(struct saxdb_context *ctx, struct userData *uData)
         saxdb_write_int(ctx, KEY_SEEN, uData->seen);
         if(uData->flags)
             saxdb_write_int(ctx, KEY_FLAGS, uData->flags);
+        if(uData->expires)
+            saxdb_write_int(ctx, KEY_EXPIRES, uData->expires);
         if(uData->channel->vote && uData->voted)
             saxdb_write_int(ctx, KEY_VOTE_VOTED, uData->voted);
         if(uData->channel->vote && uData->votefor)
index 638a77f2777eb93582fb7852cdc73af509deaf49..336671511d7159f576eca8772f711a366a18ddc1 100644 (file)
@@ -136,6 +136,7 @@ struct userData
 
     char                *info;
     unsigned long       seen;
+    time_t             expires; /* suspend */
     unsigned short      access;
     unsigned int        present : 1;
     unsigned int        flags : USER_FLAGS_SIZE;
index 0562477130b14fe4688b19d50e54cf681b14514a..e9fb42fdff198352021e4d61197c0b0906eb95c9 100644 (file)
 "STAFF" ("/msg $C STAFF",
         "Lists all the IRC operators and helpers currently online. Nicknames enclosed in parentheses are away, and likely unavailable.",
         "$uSee Also:$u helpers, ircops, netinfo");
-"SUSPEND" ("/msg $C SUSPEND <#channel> <nick|*account>",
+"SUSPEND" ("/msg $C SUSPEND <#channel> <nick|*account> <duration>",
         "This disables the target's access to the channel.  That access can be restored using the unsuspend command.",
+        "The duration may be \"0\" to make it never expire; otherwise, $C will automatically unsuspend the user after $uduration$u.",
         "$uSee Also:$u unsuspend, deluser");
 "TOPIC" ("/msg $C TOPIC <#channel> [topic]",
         "Sets the current topic for the specified channel.  If no topic is specified, then set the current topic to the default topic.");
index dd22ad3f1dd460a6f46ee1a3d85df448cf885777..da4b40f53b2a9628e88189078ef481a360b7354f 100644 (file)
 #define MAXOPLEVEL      999
 
 #define MAXMODEPARAMS   6
-#define MAXBANS         45
+#define MAXBANS         999
 
 /* IDLEN is 6 because it takes 5.33 Base64 digits to store 32 bytes. */
 #define IDLEN           6
index 33b0a8b78709fee0763b19eb2dd497955f656964..87e4eb210b18769c0834b1b0f6c33332aa50878b 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -968,9 +968,9 @@ ldIrc_audit(struct logDestination *dest_, UNUSED_ARG(struct log_type *type), str
     struct logDest_irc *dest = (struct logDest_irc*)dest_;
 
     if (entry->channel_name) {
-        send_target_message(4, dest->target, entry->bot, "(%s", strchr(strchr(entry->default_desc, ' '), ':')+1);
+       send_target_message(5, dest->target, entry->bot, "(%s", strchr(strchr(entry->default_desc, ' '), ':')+1);
     } else {
-        send_target_message(4, dest->target, entry->bot, "%s", strchr(entry->default_desc, ')')+2);
+        send_target_message(5, dest->target, entry->bot, "%s", strchr(entry->default_desc, ')')+2);
     }
 }
 
@@ -979,7 +979,7 @@ ldIrc_module(struct logDestination *dest_, struct log_type *type, enum log_sever
     struct logDest_irc *dest = (struct logDest_irc*)dest_;
     extern struct userNode *opserv;
 
-    send_target_message(4, dest->target, opserv, "%s %s: %s\n", type->name, log_severity_names[sev], message);
+    send_target_message(5, dest->target, opserv, "%s %s: %s\n", type->name, log_severity_names[sev], message);
 }
 
 static struct logDest_vtable ldIrc_vtbl = {
index d9da25d63488c01ca5f4eacf6277089e416ea793..26bee0434ea06bcbeb4c491d8dbdca3e0e93e73e 100644 (file)
@@ -43,6 +43,7 @@
 #define KEY_BADWORD_MASK "mask"
 #define KEY_BADWORD_TRIGGERED "count"
 #define KEY_BADWORD_ACTION "action"
+#define KEY_BADWOR_ALERT "alert"
 #define KEY_CHANNELS "channel"
 #define KEY_BADWORDID "badwordid"
 
@@ -59,6 +60,7 @@ static const struct message_entry msgtab[] = {
     { "WDMSG_BADWORD_SET", "Settings for BadWord entry $b%s$b" },
     { "WDMSG_BADWORD_SET_MASK",   "$bMASK$b:   %s" },
     { "WDMSG_BADWORD_SET_ACTION", "$bACTION$b: %s" },
+    { "WDMSG_BADWORD_SET_ALERT",  "$bALERT$b:  %d" },
     { NULL, NULL }
 };
 
@@ -67,6 +69,7 @@ struct badword {
     char *badword_mask;
     unsigned int triggered : 29;
     unsigned int action : 3;
+    unsigned int alert;
 };
 
 struct watchdog_channel {
@@ -80,12 +83,15 @@ struct watchdog_channel {
 #define BADACTION_KILL   2
 #define BADACTION_GLINE  3
 
+#define WDMSG_BADWORD_ALERT "%s used badword '%s' in channel: %s"
+
 static struct {
     const char *nick;
     const char *modes;
     const char *punishment_reason;
     unsigned long ban_duration;
     unsigned long gline_duration;
+    struct chanNode *alert_channel;
 } watchdog_conf;
 
 const char *watchdog_module_deps[] = { NULL };
@@ -98,8 +104,9 @@ static struct log_type *MS_LOG;
 static unsigned int last_badword_id = 0;
 
 static struct watchdog_channel *add_channel(const char *name);
-static struct badword *add_badword(const char *badword_mask, unsigned int triggered, unsigned int action, const char *id);
+static struct badword *add_badword(const char *badword_mask, unsigned int triggered, unsigned int action, unsigned int alert, const char *id);
 #define watchdog_notice(target, format...) send_message(target , watchdog , ## format)
+#define watchdog_debug(format...) do { if(watchdog_conf.alert_channel) send_channel_message(watchdog_conf.alert_channel , watchdog , ## format); } while(0)
 
 static MODCMD_FUNC(cmd_addbad)
 {
@@ -113,7 +120,7 @@ static MODCMD_FUNC(cmd_addbad)
         }
     }
 
-    struct badword *new_badword = add_badword(mask, 0, BADACTION_KICK, NULL);
+    struct badword *new_badword = add_badword(mask, 0, BADACTION_KICK, 0, NULL);
     for (it = dict_first(shitlist); it; it = iter_next(it)) {
         struct badword *badword = iter_data(it);
         if(match_ircglob(badword->badword_mask, new_badword->badword_mask) && badword != new_badword) {
@@ -175,6 +182,17 @@ static MODCMD_FUNC(cmd_setbad)
                  } else {
                     reply("WDMSG_BADWORD_SET_INVALID", setting);
                  }
+            }
+            else if(!strcmp("ALERT",setting)) {
+                if (!strcmp("0",value)) {
+                       badword->alert = 0;
+                       reply("WDMSG_BADWORD_SET_DONE");
+                } else if (!strcmp("1",value)) {
+                       badword->alert = 1;
+                       reply("WDMSG_BADWORD_SET_DONE");
+                } else {
+                       reply("WDMSG_BADWORD_SET_INVALID", setting);
+                }
             } else {
                  reply("WDMSG_BADWORD_SETTING_INVALID", setting);
             }
@@ -198,6 +216,7 @@ static MODCMD_FUNC(cmd_setbad)
                 default:
                   reply("WDMSG_BADWORD_SET_ACTION", "*undef*");
             }
+            reply("WDMSG_BADWORD_SET_ALERT", badword->alert);
         }
     } else {
         reply("WDMSG_BADWORD_NOT_FOUND", argv[1]);
@@ -226,7 +245,7 @@ static MODCMD_FUNC(cmd_listbad)
         count++;
     }
     tbl.length = count+1;
-    tbl.width = 4;
+    tbl.width = 5;
     tbl.flags = 0;
     tbl.flags = TABLE_NO_FREE;
     tbl.contents = malloc(tbl.length * sizeof(tbl.contents[0]));
@@ -235,6 +254,7 @@ static MODCMD_FUNC(cmd_listbad)
     tbl.contents[0][1] = "Badword";
     tbl.contents[0][2] = "Action";
     tbl.contents[0][3] = "(Triggered)";
+    tbl.contents[0][4] = "Alert";
     if(!count)
     {
         table_send(cmd->parent->bot, user->nick, 0, NULL, tbl);
@@ -271,6 +291,7 @@ static MODCMD_FUNC(cmd_listbad)
               tbl.contents[ii][2] = "*undef*";
         }
         tbl.contents[ii][3] = strtab(bw->triggered);
+        tbl.contents[ii][4] = strtab(bw->alert);
     }
     table_send(cmd->parent->bot, user->nick, 0, NULL, tbl);
     for(ii = 1; ii < tbl.length; ++ii)
@@ -367,37 +388,43 @@ watchdog_detected_badword(struct userNode *user, struct chanNode *chan, struct b
     char *hostmask;
     char *reason = watchdog_conf.punishment_reason;
     char mask[IRC_NTOP_MAX_SIZE+3] = { '*', '@', '\0' };
-    switch(badword->action) {
-        case BADACTION_BAN:
-            hostmask = generate_hostmask(user, GENMASK_STRICT_HOST | GENMASK_ANY_IDENT);
-            sanitize_ircmask(hostmask);
-            if(chan->channel_info) {
-                //registered channel
-                add_channel_ban(chan->channel_info, hostmask, watchdog->nick, now, now, now + watchdog_conf.ban_duration, reason);
-            }
-            struct mod_chanmode change;
-            mod_chanmode_init(&change);
-            change.argc = 1;
-            change.args[0].mode = MODE_BAN;
-            change.args[0].u.hostmask = hostmask;
-            mod_chanmode_announce(watchdog, chan, &change);
-            free(hostmask);
-            
-        case BADACTION_KICK:
-            if(GetUserMode(chan, user))
-                KickChannelUser(user, chan, watchdog, reason); 
-            break;
-        case BADACTION_KILL:
-            DelUser(user, watchdog, 1, reason);
-            break;
-        case BADACTION_GLINE:
-            irc_ntop(mask + 2, sizeof(mask) - 2, &user->ip);
-            gline_add(watchdog->nick, mask, watchdog_conf.gline_duration, reason, now, now, 0, 1);
-            break;
-        default:
-            //error?
-            break;
-        }
+    if(!IsOper(user)) {
+       if(badword->alert == 1) {
+               log_module(MS_LOG, LOG_WARNING, "%s used badword '%s' in channel: %s", user->nick, badword->badword_mask, chan->name);
+               watchdog_debug(WDMSG_BADWORD_ALERT, user->nick, badword->badword_mask, chan->name);
+       }
+               switch(badword->action) {
+                       case BADACTION_BAN:
+                               hostmask = generate_hostmask(user, GENMASK_STRICT_HOST | GENMASK_ANY_IDENT);
+                               sanitize_ircmask(hostmask);
+                               if(chan->channel_info) {
+                                       //registered channel
+                                       add_channel_ban(chan->channel_info, hostmask, watchdog->nick, now, now, now + watchdog_conf.ban_duration, reason);
+                               }
+                               struct mod_chanmode change;
+                               mod_chanmode_init(&change);
+                               change.argc = 1;
+                               change.args[0].mode = MODE_BAN;
+                               change.args[0].u.hostmask = hostmask;
+                               mod_chanmode_announce(watchdog, chan, &change);
+                               free(hostmask);
+
+                       case BADACTION_KICK:
+                               if(GetUserMode(chan, user))
+                                       KickChannelUser(user, chan, watchdog, reason);
+                               break;
+                       case BADACTION_KILL:
+                               DelUser(user, watchdog, 1, reason);
+                               break;
+                       case BADACTION_GLINE:
+                               irc_ntop(mask + 2, sizeof(mask) - 2, &user->ip);
+                               gline_add(watchdog->nick, mask, watchdog_conf.gline_duration, reason, now, now, 0, 1);
+                               break;
+                       default:
+                               //error?
+                               break;
+                       }
+    }
 }
 
 static void
@@ -417,7 +444,7 @@ watchdog_channel_message(struct userNode *user, struct chanNode *chan, const cha
 }
 
 static struct badword*
-add_badword(const char *badword_mask, unsigned int triggered, unsigned int action, const char *id)
+add_badword(const char *badword_mask, unsigned int triggered, unsigned int action, unsigned int alert, const char *id)
 {
     struct badword *badword;
 
@@ -433,6 +460,7 @@ add_badword(const char *badword_mask, unsigned int triggered, unsigned int actio
     badword->badword_mask = strdup(badword_mask);
     badword->triggered = triggered;
     badword->action = action;
+    badword->alert = alert;
     dict_insert(shitlist, badword->id, badword);
     return badword;
 }
@@ -507,6 +535,16 @@ watchdog_conf_read(void)
     
     str = database_get_data(conf_node, "punishment_reason", RECDB_QSTRING);
        watchdog_conf.punishment_reason = (str ? str : "Your message contained a forbidden word.");
+
+       str = database_get_data(conf_node, "alert_chan", RECDB_QSTRING);
+       if(str)
+       {
+               watchdog_conf.alert_channel = AddChannel(str, now, "+tinms", NULL);
+       }
+       else
+       {
+               watchdog_conf.alert_channel = NULL;
+       }
     
 }
 
@@ -515,7 +553,7 @@ watchdog_saxdb_read_shitlist(const char *name, void *data, UNUSED_ARG(void *extr
 {
     struct record_data *rd = data;
     char *badword;
-    char *triggered, *action;
+    char *triggered, *action, *alert;
 
      if (rd->type == RECDB_OBJECT) {
         dict_t obj = GET_RECORD_OBJECT(rd);
@@ -523,8 +561,9 @@ watchdog_saxdb_read_shitlist(const char *name, void *data, UNUSED_ARG(void *extr
         badword = database_get_data(obj, KEY_BADWORD_MASK, RECDB_QSTRING);
         triggered = database_get_data(obj, KEY_BADWORD_TRIGGERED, RECDB_QSTRING);
         action = database_get_data(obj, KEY_BADWORD_ACTION, RECDB_QSTRING);
+        alert = database_get_data(obj, KEY_BADWOR_ALERT, RECDB_QSTRING);
 
-        add_badword(badword, strtoul(triggered, NULL, 0), strtoul(action, NULL, 0), name);
+        add_badword(badword, strtoul(triggered, NULL, 0), strtoul(action, NULL, 0), strtoul(alert, NULL, 0), name);
     }
     return 0;
 }
@@ -577,6 +616,7 @@ watchdog_saxdb_write(struct saxdb_context *ctx)
                 saxdb_write_string(ctx, KEY_BADWORD_MASK, badword->badword_mask);
                 saxdb_write_int(ctx, KEY_BADWORD_TRIGGERED, badword->triggered);
                 saxdb_write_int(ctx, KEY_BADWORD_ACTION, badword->action);
+                saxdb_write_int(ctx, KEY_BADWOR_ALERT, badword->alert);
                 
                 saxdb_end_record(ctx);
             }
index 2ec8c6f81cd1298c17204702460b932b687fe61f..a8e123a63dd9e285a52d050337e92c7646a12615 100644 (file)
@@ -914,7 +914,7 @@ modcmd_privmsg(struct userNode *user, struct userNode *bot, const char *text, in
              * users, except to add copyright information pertaining
              * to changes you make to srvx.
              */
-            snprintf(response, sizeof(response), "\x01VERSION %s (%s) %s\x01", PACKAGE_STRING, CODENAME, git_version);
+            snprintf(response, sizeof(response), "\x01VERSION %s (%s) GIT Revision: %s\x01", PACKAGE_STRING, CODENAME, git_version);
             irc_notice_user(bot, user, response);
         }
         return;
@@ -1598,7 +1598,7 @@ static MODCMD_FUNC(cmd_stats_services) {
 
     if (argc < 2) {
         tbl.length = dict_size(services) + 1;
-        tbl.width = 4;
+        tbl.width = 5;
         tbl.flags = TABLE_PAD_LEFT;
         tbl.contents = calloc(tbl.length, sizeof(tbl.contents[0]));
         tbl.contents[0] = calloc(tbl.width, sizeof(tbl.contents[0][0]));
@@ -1606,6 +1606,7 @@ static MODCMD_FUNC(cmd_stats_services) {
         tbl.contents[0][1] = "Commands";
         tbl.contents[0][2] = "Priv'd?";
         tbl.contents[0][3] = "Trigger";
+        tbl.contents[0][4] = "Offchannel";
         extra = calloc(2, tbl.length);
         for (ii=1, it=dict_first(services); it; it=iter_next(it), ii++) {
             service = iter_data(it);
@@ -1615,6 +1616,7 @@ static MODCMD_FUNC(cmd_stats_services) {
             tbl.contents[ii][2] = service->privileged ? "yes" : "no";
             extra[ii*2] = service->trigger;
             tbl.contents[ii][3] = extra+ii*2;
+                       tbl.contents[ii][4] = offchannel_allowed[(unsigned char)service->trigger] ? "yes" : "no";
         }
         table_send(cmd->parent->bot, user->nick, 0, 0, tbl);
         free(extra);
@@ -1939,11 +1941,8 @@ static MODCMD_FUNC(cmd_version) {
      * command or its accessibility to normal IRC users, except to add
      * copyright information pertaining to changes you make to srvx.
      */
-    send_message_type(4, user, cmd->parent->bot, "$b"PACKAGE_STRING"$b ("CODENAME"), Built: "__DATE__", "__TIME__".  Copyright 2000-2008 srvx Development Team.");
-    if (argc > 1)
-        send_message_type(4, user, cmd->parent->bot, "%s", git_version);
-    else
-        send_message_type(12, user, cmd->parent->bot, "The srvx Development Team includes Paul Chang, Adrian Dewhurst, Miles Peterson, Michael Poole and others.\nThe srvx Development Team can be reached at http://sf.net/projects/srvx/ or in #srvx on irc.gamesurge.net.\nThis version has been modified by pk910 - visit #srvx @ irc.webgamesnet.net.");
+    send_message_type(4, user, cmd->parent->bot, "$b"PACKAGE_STRING"$b ("CODENAME"), GIT Revision: %s, Built: "__DATE__", "__TIME__".  Copyright 2000-2008 srvx Development Team.", git_version);
+    send_message_type(12, user, cmd->parent->bot, "The srvx Development Team includes Paul Chang, Adrian Dewhurst, Miles Peterson, Michael Poole and others.\nThe srvx Development Team can be reached at http://sf.net/projects/srvx/ or in #srvx on irc.gamesurge.net.\nThis version has been modified by pk910 - visit #srvx @ irc.nextirc.net.\nThis version has been modified by Stricted, NurPech - visit #dev @ irc.easy-scripting.net.");
     return 1;
 }
 
index bfe7c0bcacbceb7cdcbac97f70a4cdb51758e890..322170e2825422abdfb1b805b17a7df2a0548c67 100644 (file)
@@ -40,9 +40,11 @@ struct svccmd;
 #define HI_FLAG_BOT            0x00000200
 #define HI_FLAG_AUTOHIDE       0x00000400
 #define HI_FLAG_INVI           0x00000800
+#define HI_FLAG_OPER           0x00001000
+#define HI_FLAG_NETWORK        0x00002000
 
 /* Flag characters for the above.  First char is LSB, etc. */
-#define HANDLE_FLAGS "SphgscfnHbxI"
+#define HANDLE_FLAGS "SphgscfnHbxIoN"
 
 /* HI_STYLE_* go into handle_info.userlist_style */
 #define HI_STYLE_DEF    'd'
index b4aa0d9f6542641ab97176454fd074271922547c..83eb31080107824144522160212037d488456ea6 100644 (file)
@@ -268,6 +268,8 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_SVSNICKUSED", "$b%s$b is an already used nickname." },
     { "OSMSG_SVSNICK", "You have renamed $b%s$b to $b%s$b." },
     { "OSMSG_SVSJOIN", "$b%s$b joined $b%s$b." },
+    { "OSMSG_SVSPART", "$b%s$b parted $b%s$b." },
+    { "OSMSG_SVSKILL", "$b%s$b killed: $b%s$b." },
     { "OSMSG_SVSMODE", "You have set mode $b%s$b for $b%s$b." },
     { "OSMSG_SIMUL", "You have simuled $b%s$b: %s" },
     { "OSMSG_DEVNULL_USER" , "[%s] %s  %s" },
@@ -4772,6 +4774,34 @@ static MODCMD_FUNC(cmd_svsjoin)
     return 1;
 }
 
+static MODCMD_FUNC(cmd_svspart)
+{
+    struct userNode *target;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    if(!IsChannelName(argv[2]))
+    {
+        reply("MSG_NOT_CHANNEL_NAME");
+        return 0;
+    }
+    irc_svspartchan(opserv,target,argv[2]);
+    reply("OSMSG_SVSPART",target->nick,argv[2]);
+    return 1;
+}
+
+static MODCMD_FUNC(cmd_svskill)
+{
+    struct userNode *target;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    DelUser(target, opserv, 1, argv[2]);
+    reply("OSMSG_SVSKILL",target->nick,argv[2]);
+    return 1;
+}
 static MODCMD_FUNC(cmd_svsnick)
 {
     struct userNode *target;
@@ -4807,14 +4837,17 @@ static MODCMD_FUNC(cmd_simul)
 {
     struct userNode *target;
     char *line;
-    if(!(target=GetUserH(argv[1]))) {
-        reply("OSMSG_SVSNONICK", argv[1]);
-        return 0;
+    if(argc > 2) {
+               if(!(target=GetUserH(argv[1]))) {
+                       reply("OSMSG_SVSNONICK", argv[1]);
+                       return 0;
+               }
+               line = unsplit_string(argv + 2, argc - 2, NULL);
+               irc_simul(target,line);
+               reply("OSMSG_SIMUL",target->nick,line);
+               return 1;
     }
-    line = unsplit_string(argv + 2, argc - 2, NULL);
-    irc_simul(target,line);
-    reply("OSMSG_SIMUL",target->nick,line);
-    return 1;
+    return 0;
 }
 
 static MODCMD_FUNC(cmd_relay)
@@ -5082,10 +5115,12 @@ init_opserv(const char *nick)
     opserv_define_func("DEVNULL SET", cmd_setdevnull, 200, 0, 2);
     opserv_define_func("DEVNULL LIST", cmd_listdevnull, 200, 0, 0);
     opserv_define_func("SVSJOIN", cmd_svsjoin, 800, 0, 3);
+    opserv_define_func("SVSPART", cmd_svspart, 800, 0, 3);
+    opserv_define_func("SVSKILL", cmd_svskill, 800, 0, 3);
     opserv_define_func("SVSMODE", cmd_svsmode, 800, 0, 3);
     opserv_define_func("SVSNICK", cmd_svsnick, 800, 0, 3);
     opserv_define_func("RELAY", cmd_relay, 800, 0, 0);
-    opserv_define_func("SIMUL", cmd_simul, 999, 0, 2);
+    opserv_define_func("SIMUL", cmd_simul, 999, 0, 3);
     opserv_define_func("TRACE", cmd_trace, 100, 0, 3);
     opserv_define_func("TRACE PRINT", NULL, 0, 0, 0);
     opserv_define_func("TRACE COUNT", NULL, 0, 0, 0);
index f544f9f019a2ddc3799bb19de4e0dc013e0a982a..dc0829d07e9ca6dc8776bf924441e38e0c979fed 100644 (file)
@@ -90,6 +90,7 @@
 #define CMD_SVSNICK             "SVSNICK"
 #define CMD_SVSMODE             "SVSMODE"
 #define CMD_SVSJOIN             "SVSJOIN"
+#define CMD_SVSPART             "SVSPART"
 #define CMD_TIME                "TIME"
 #define CMD_TOPIC               "TOPIC"
 #define CMD_TRACE               "TRACE"
 #define TOK_SVSNICK             "SN"
 #define TOK_SVSMODE             "SM"
 #define TOK_SVSJOIN             "SJ"
+#define TOK_SVSPART             "SP"
 #define TOK_TIME                "TI"
 #define TOK_TOPIC               "T"
 #define TOK_TRACE               "TR"
 #define P10_SVSNICK             TYPE(SVSNICK)
 #define P10_SVSMODE             TYPE(SVSMODE)
 #define P10_SVSJOIN             TYPE(SVSJOIN)
+#define P10_SVSPART             TYPE(SVSPART)
 #define P10_TIME                TYPE(TIME)
 #define P10_TOPIC               TYPE(TOPIC)
 #define P10_TRACE               TYPE(TRACE)
@@ -654,6 +657,18 @@ irc_svsjoinchan(struct userNode *from, struct userNode *user, const char *chan)
 putsock("%s " P10_SVSJOIN " %s %s", from->numeric, user->numeric, chan);
 }
 
+void
+irc_svspart(struct userNode *from, struct userNode *user, struct chanNode *chan)
+{
+putsock("%s " P10_SVSPART " %s %s", from->numeric, user->numeric, chan->name);
+}
+
+void
+irc_svspartchan(struct userNode *from, struct userNode *user, const char *chan)
+{
+putsock("%s " P10_SVSPART " %s %s", from->numeric, user->numeric, chan);
+}
+
 void
 irc_eob(void)
 {
index 36de9a8d759bea84fcf259c769509afbe1f6b2a5..94fa635a3365be3a4f4a34bfdeab3088898cf3dd 100644 (file)
@@ -157,6 +157,8 @@ void irc_keepconn(struct userNode *target, unsigned int timeout);
 void irc_svsmode(struct userNode *from, struct userNode *user, const char *modes);
 void irc_svsjoin(struct userNode *from, struct userNode *user, struct chanNode *chan);
 void irc_svsjoinchan(struct userNode *from, struct userNode *user, const char *chan);
+void irc_svspart(struct userNode *from, struct userNode *user, struct chanNode *chan);
+void irc_svspartchan(struct userNode *from, struct userNode *user, const char *chan);
 void irc_relay(char *message);
 void irc_simul(struct userNode *target, char *command);
 
index 9987398772bc4c98737380d9e018fa9b569f37c0..2cbd3e8a0bedc758a0d11e14342865bf7ab40e28 100644 (file)
@@ -76,7 +76,7 @@ dict_t connected_users_dict;
 dict_t killed_users_dict;
 
 #define spamserv_notice(target, format...) send_message(target , spamserv , ## format)
-#define spamserv_debug(format...) do { if(spamserv_conf.debug_channel) send_channel_notice(spamserv_conf.debug_channel , spamserv , ## format); } while(0)
+#define spamserv_debug(format...) do { if(spamserv_conf.debug_channel) send_channel_message(spamserv_conf.debug_channel , spamserv , ## format); } while(0)
 #define ss_reply(format...)    send_message(user , spamserv , ## format)
 
 #define SET_SUBCMDS_SIZE 10
@@ -2247,7 +2247,7 @@ spamserv_saxdb_read(struct dict *database)
                 badwordid = str ? atoi(str) : 0;
                 cInfo->last_badword_id = badwordid;
                 if ((badwords = database_get_data(hir->d.object, KEY_BADWORDS, RECDB_OBJECT)))
-                       dict_foreach(object, spamserv_saxdb_read_shitlist, cInfo);
+                       dict_foreach(badwords, spamserv_saxdb_read_shitlist, cInfo);
                        }
                }
                else
index 84409edc0479db95737f784eee4730566c922ed1..b3901c88736c238fdf77bd96d26b27c5c5302180 100644 (file)
         "max_chan_users" "512";
         // maximum bans on a channel banlist
         "max_chan_bans" "512";
+        //min time of timebans
+        "min_time_bans" "5";
         // maximum length of a user's infoline
         "max_userinfo_length" "400";
         // If DynLimit is on and there are N users in the channel, ChanServ will
         "ban_duration" "2h"; //only if the channel is registered with chanserv
         "gline_duration" "1h";
         "punishment_reason" "Your message contained a forbidden word.";
+        "alert_chan" "#opers";
     };
        
        "hostserv" {