]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/opserv.c
fixing small memory leak
[irc/evilnet/x3.git] / src / opserv.c
index d8eed2337b8b43b070b4f0536b196b44bf40d2bf..7f3e0cc310fb19d1f7de918696f5d5ed8c75fc7f 100644 (file)
@@ -18,6 +18,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 
+#include "config.h"
+#include "chanserv.h"
 #include "conf.h"
 #include "common.h"
 #include "gline.h"
@@ -205,6 +207,7 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_WHOIS_CHANNELS",   "Channels     : %s" },
     { "OSMSG_WHOIS_HIDECHANS",  "Channel list omitted for your sanity." },
     { "OSMSG_WHOIS_VERSION",    "Version      : %s" },  
+    { "OSMSG_WHOIS_MARK",       "Mark         : %s" },  
     { "OSMSG_WHOIS_NO_NOTICE",  "No_notices   : %s" },
     { "OSMSG_UNBAN_DONE", "Ban(s) removed from channel %s." },
     { "OSMSG_CHANNEL_VOICED", "All users on %s voiced." },
@@ -523,7 +526,7 @@ opserv_free_waiting_connection(void *data)
 
 typedef struct opservDiscrim {
     struct chanNode *channel;
-    char *mask_nick, *mask_ident, *mask_host, *mask_info, *mask_version, *server, *reason, *accountmask, *chantarget, *mark;
+    char *mask_nick, *mask_ident, *mask_host, *mask_info, *mask_version, *server, *reason, *accountmask, *chantarget, *mark, *mask_mark;
     irc_in_addr_t ip_mask;
     unsigned long limit;
     time_t min_ts, max_ts;
@@ -537,6 +540,7 @@ typedef struct opservDiscrim {
     unsigned int intra_scmp : 2, intra_dcmp : 2;
     unsigned int use_regex : 1;
     unsigned int silent : 1;
+    unsigned int checkrestrictions : 2;
 } *discrim_t;
 
 struct discrim_and_source {
@@ -1370,7 +1374,7 @@ opserv_mark(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG(ch
 }
 
 static void
-opserv_svsjoin(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG(char *reason), char *channame)
+opserv_svsjoin(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG(char *reason), char *channame, unsigned int checkrestrictions)
 {
     struct chanNode *channel;
 
@@ -1387,6 +1391,26 @@ opserv_svsjoin(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG
         return;
     }
 
+    if (checkrestrictions) {
+        if (trace_check_bans(target, channel) == 1) {
+            return; /* found on lamer list */
+        }
+
+        if (channel->modes & MODE_INVITEONLY) {
+            return; /* channel is invite only */
+        }
+
+        if (channel->limit > 0) {
+            if (channel->members.used >= channel->limit) {
+                return; /* channel is invite on */
+            }
+        }
+
+        if (*channel->key) {
+            return; /* channel is password protected */
+        }
+    }
+
     irc_svsjoin(opserv, target, channel);
     /* Should we tell the user they got joined? -Rubin*/
 }
@@ -2015,6 +2039,9 @@ static MODCMD_FUNC(cmd_whois)
     if(target->version_reply) {
         reply("OSMSG_WHOIS_VERSION", target->version_reply);
     }
+    if(target->mark) {
+        reply("OSMSG_WHOIS_MARK", target->mark);
+    }
     reply("OSMSG_WHOIS_NO_NOTICE", target->no_notice ? "YES":"NO");
   
     if (target->modes) {
@@ -2784,7 +2811,7 @@ opserv_notice_handler(struct userNode *user, struct userNode *bot, char *text, U
         if(text[0] == '\001') {
             text++;
             cmd = mysep(&text, " ");
-            if(!irccasecmp(cmd, "VERSION")) {
+            if(cmd && !irccasecmp(cmd, "VERSION")) {
                 char *version = mysep(&text, "\n");
                 if(!version)
                     version = "";
@@ -5173,12 +5200,24 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int
         }
         discrim->accountmask = argv[++i];
         discrim->authed = 1;
+    } else if (irccasecmp(argv[i], "marked") == 0) {
+        discrim->mask_mark = argv[++i];
     } else if (irccasecmp(argv[i], "chantarget") == 0) {
             if(!IsChannelName(argv[i+1])) {
                 send_message(user, bot, "MSG_NOT_CHANNEL_NAME");
                 goto fail;
             }
             discrim->chantarget = argv[++i];
+    } else if (irccasecmp(argv[i], "checkrestrictions") == 0) {
+        i++;
+        if (true_string(argv[i])) {
+            discrim->checkrestrictions = 1;
+        } else if (false_string(argv[i])) {
+            discrim->checkrestrictions = 0;
+        } else {
+            send_message(user, bot, "MSG_INVALID_BINARY", argv[i]);
+            goto fail;
+        }
     } else if (irccasecmp(argv[i], "mark") == 0) {
         if(!is_valid_mark(argv[i+1])) {
             send_message(user, bot, "OSMSG_MARK_INVALID");
@@ -5458,6 +5497,7 @@ discrim_match(discrim_t discrim, struct userNode *user)
         || (discrim->info_space == 0 && user->info[0] == ' ')
         || (discrim->info_space == 1 && user->info[0] != ' ')
         || (discrim->server && !match_ircglob(user->uplink->name, discrim->server))
+        || (discrim->mask_mark && (!user->mark || !match_ircglob(user->mark, discrim->mask_mark)))
         || (discrim->accountmask && (!user->handle_info || !match_ircglob(user->handle_info->handle, discrim->accountmask)))
         || (discrim->ip_mask_bits && !irc_check_mask(&user->ip, &discrim->ip_mask, discrim->ip_mask_bits))
         )
@@ -5682,6 +5722,7 @@ trace_svsjoin_func(struct userNode *match, void *extra)
     struct discrim_and_source *das = extra;
 
     char *channame = das->discrim->chantarget;
+    int checkrestrictions = das->discrim->checkrestrictions;
     struct chanNode *channel;
 
     if(!channame || !IsChannelName(channame)) {
@@ -5692,6 +5733,27 @@ trace_svsjoin_func(struct userNode *match, void *extra)
     if (!(channel = GetChannel(channame))) {
        channel = AddChannel(channame, now, NULL, NULL, NULL);
     }
+
+    if (checkrestrictions) {
+        if (trace_check_bans(match, channel) == 1) {
+            return 1; /* found on lamer list */
+        }
+
+        if (channel->modes & MODE_INVITEONLY) {
+            return 1; /* channel is invite only */
+        }
+
+        if (channel->limit > 0) {
+            if (channel->members.used >= channel->limit) {
+                return 1; /* channel is invite on */
+            }
+        }
+
+        if (*channel->key) {
+            return 1; /* channel is password protected */
+        }
+    }
+
     if (GetUserMode(channel, match)) {
 //        reply("OSMSG_ALREADY_THERE", channel->name);
         return 1;
@@ -6366,7 +6428,7 @@ alert_check_user(const char *key, void *data, void *extra)
         opserv_shun(user, alert->owner, alert->discrim->reason, alert->discrim->duration);
         return 1;
     case REACT_SVSJOIN:
-        opserv_svsjoin(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget);
+        opserv_svsjoin(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget, alert->discrim->checkrestrictions);
         break;
     case REACT_SVSPART:
         opserv_svspart(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget);