Sfoglia il codice sorgente

* Fixed ipv6 bans/invites/exempts writing to userfile.
* Bans, exempts, and invites starting with numbers can now be
removed, stuck, and unstuck.


svn: 270

Bryan Drewery 22 anni fa
parent
commit
7766df617c
6 ha cambiato i file con 150 aggiunte e 116 eliminazioni
  1. 14 0
      src/misc.c
  2. 114 101
      src/mod/channels.mod/cmdschan.c
  3. 16 10
      src/mod/channels.mod/userchan.c
  4. 1 1
      src/mod/module.h
  5. 1 1
      src/modules.c
  6. 4 3
      src/proto.h

+ 14 - 0
src/misc.c

@@ -707,6 +707,20 @@ char *str_escape(const char *str, const char div, const char mask)
   return buf;
 }
 
+/* Is every character in a string a digit? */
+int str_isdigit(const char *str)
+{
+  if (!*str)
+    return 0;
+
+  for(; *str; ++str) {
+    if (!egg_isdigit(*str))
+      return 0;
+  }
+  return 1;
+}
+
+
 /* Search for a certain character 'div' in the string 'str', while
  * ignoring escaped characters prefixed with 'mask'.
  *

+ 114 - 101
src/mod/channels.mod/cmdschan.c

@@ -462,7 +462,8 @@ static void cmd_mns_ban(struct userrec *u, int idx, char *par)
     dprintf(idx, "Invalid channel.\n");
     return;
   }
-  if ((i = atoi(ban)) > 0) {
+  if (str_isdigit(ban)) {
+    i = atoi(ban);
     /* substract the numer of global bans to get the number of the channel ban */
     egg_snprintf(s, sizeof s, "%d", i);
     j = u_delban(0, s, 0);
@@ -574,55 +575,39 @@ static void cmd_mns_exempt (struct userrec *u, int idx, char *par)
   /* Channel-specific exempt? */
   if (chname)
     chan = findchan_by_dname(chname);
-  if (chan) {
-    if ((i = atoi(exempt)) > 0) {
-      /* substract the numer of global exempts to get the number of the channel exempt */
-      egg_snprintf(s, sizeof s, "%d", i);
-      j = u_delexempt(0, s, 0);
-      if (j < 0) {
-        egg_snprintf(s, sizeof s, "%d", -j);
-        j = u_delexempt(chan, s, 1);
-        if (j > 0) {
-          if (lastdeletedmask)
-            mask = lastdeletedmask;
-          else
-            mask = s;
-          putlog(LOG_CMDS, "*", "#%s# (%s) -exempt %s", dcc[idx].nick,
-                 chan->dname, mask);
-          dprintf(idx, "Removed %s channel exempt: %s\n", chan->dname, mask);
-          add_mode(chan, '-', 'e', mask);
-          return;
-        }
-      }
-      i = 0;
-      for (e = chan->channel.exempt; e && e->mask && e->mask[0]; e = e->next) {
-        if (!u_equals_mask(global_exempts, e->mask) &&
-            !u_equals_mask(chan->exempts, e->mask)) {
-          i++;
-          if (i == -j) {
-            add_mode(chan, '-', 'e', e->mask);
-            dprintf(idx, "%s '%s' on %s.\n", IRC_REMOVEDEXEMPT,
-                    e->mask, chan->dname);
-            putlog(LOG_CMDS, "*", "#%s# (%s) -exempt %s [on channel]",
-                   dcc[idx].nick, dcc[idx].u.chat->con_chan, exempt);
-            return;
-          }
-        }
-      }
-    } else {
-      j = u_delexempt(chan, exempt, 1);
+  if (!chan) {
+    dprintf(idx, "Invalid channel.\n");
+    return;
+  }
+  if (str_isdigit(exempt)) {
+    i = atoi(exempt);
+    /* substract the numer of global exempts to get the number of the channel exempt */
+    egg_snprintf(s, sizeof s, "%d", i);
+    j = u_delexempt(0, s, 0);
+    if (j < 0) {
+      egg_snprintf(s, sizeof s, "%d", -j);
+      j = u_delexempt(chan, s, 1);
       if (j > 0) {
+        if (lastdeletedmask)
+          mask = lastdeletedmask;
+        else
+          mask = s;
         putlog(LOG_CMDS, "*", "#%s# (%s) -exempt %s", dcc[idx].nick,
-               dcc[idx].u.chat->con_chan, exempt);
-        dprintf(idx, "Removed %s channel exempt: %s\n", chname, exempt);
-        add_mode(chan, '-', 'e', exempt);
+               chan->dname, mask);
+        dprintf(idx, "Removed %s channel exempt: %s\n", chan->dname, mask);
+        add_mode(chan, '-', 'e', mask);
         return;
       }
-      for (e = chan->channel.exempt; e && e->mask && e->mask[0]; e = e->next) {
-        if (!rfc_casecmp(e->mask, exempt)) {
+    }
+    i = 0;
+    for (e = chan->channel.exempt; e && e->mask && e->mask[0]; e = e->next) {
+      if (!u_equals_mask(global_exempts, e->mask) &&
+          !u_equals_mask(chan->exempts, e->mask)) {
+        i++;
+        if (i == -j) {
           add_mode(chan, '-', 'e', e->mask);
-          dprintf(idx, "%s '%s' on %s.\n",
-                  IRC_REMOVEDEXEMPT, e->mask, chan->dname);
+          dprintf(idx, "%s '%s' on %s.\n", IRC_REMOVEDEXEMPT,
+                  e->mask, chan->dname);
           putlog(LOG_CMDS, "*", "#%s# (%s) -exempt %s [on channel]",
                  dcc[idx].nick, dcc[idx].u.chat->con_chan, exempt);
           return;
@@ -630,8 +615,24 @@ static void cmd_mns_exempt (struct userrec *u, int idx, char *par)
       }
     }
   } else {
-    dprintf(idx, "Invalid channel.\n");
-    return;
+    j = u_delexempt(chan, exempt, 1);
+    if (j > 0) {
+      putlog(LOG_CMDS, "*", "#%s# (%s) -exempt %s", dcc[idx].nick,
+             dcc[idx].u.chat->con_chan, exempt);
+      dprintf(idx, "Removed %s channel exempt: %s\n", chname, exempt);
+      add_mode(chan, '-', 'e', exempt);
+      return;
+    }
+    for (e = chan->channel.exempt; e && e->mask && e->mask[0]; e = e->next) {
+      if (!rfc_casecmp(e->mask, exempt)) {
+        add_mode(chan, '-', 'e', e->mask);
+        dprintf(idx, "%s '%s' on %s.\n",
+                IRC_REMOVEDEXEMPT, e->mask, chan->dname);
+        putlog(LOG_CMDS, "*", "#%s# (%s) -exempt %s [on channel]",
+               dcc[idx].nick, dcc[idx].u.chat->con_chan, exempt);
+        return;
+      }
+    }
   }
   dprintf(idx, "No such exemption.\n");
 }
@@ -691,57 +692,40 @@ static void cmd_mns_invite (struct userrec *u, int idx, char *par)
   /* Channel-specific invite? */
   if (chname)
     chan = findchan_by_dname(chname);
-  if (chan) {
-    if ((i = atoi(invite)) > 0) {
-      /* substract the numer of global invites to get the number of the channel invite */
-      egg_snprintf(s, sizeof s, "%d", i);
-      j = u_delinvite(0, s, 0);
-      if (j < 0) {
-        egg_snprintf(s, sizeof s, "%d", -j);
-        j = u_delinvite(chan, s, 1);
-        if (j > 0) {
-          if (lastdeletedmask)
-            mask = lastdeletedmask;
-          else
-            mask = s;
-          putlog(LOG_CMDS, "*", "#%s# (%s) -invite %s", dcc[idx].nick,
-                 chan->dname, mask);
-          dprintf(idx, "Removed %s channel invite: %s\n", chan->dname, mask);
-          add_mode(chan, '-', 'I', mask);
-          return;
-        }
-      }
-      i = 0;
-      for (inv = chan->channel.invite; inv && inv->mask && inv->mask[0];
-           inv = inv->next) {
-        if (!u_equals_mask(global_invites, inv->mask) &&
-            !u_equals_mask(chan->invites, inv->mask)) {
-          i++;
-          if (i == -j) {
-            add_mode(chan, '-', 'I', inv->mask);
-            dprintf(idx, "%s '%s' on %s.\n", IRC_REMOVEDINVITE,
-                    inv->mask, chan->dname);
-            putlog(LOG_CMDS, "*", "#%s# (%s) -invite %s [on channel]",
-                   dcc[idx].nick, dcc[idx].u.chat->con_chan, invite);
-            return;
-          }
-        }
-      }
-    } else {
-      j = u_delinvite(chan, invite, 1);
+  if (!chan) {
+    dprintf(idx, "Invalid channel.\n");
+    return;
+  }
+  if (str_isdigit(invite)) {
+    i = atoi(invite);
+    /* substract the numer of global invites to get the number of the channel invite */
+    egg_snprintf(s, sizeof s, "%d", i);
+    j = u_delinvite(0, s, 0);
+    if (j < 0) {
+      egg_snprintf(s, sizeof s, "%d", -j);
+      j = u_delinvite(chan, s, 1);
       if (j > 0) {
+        if (lastdeletedmask)
+          mask = lastdeletedmask;
+        else
+          mask = s;
         putlog(LOG_CMDS, "*", "#%s# (%s) -invite %s", dcc[idx].nick,
-               dcc[idx].u.chat->con_chan, invite);
-        dprintf(idx, "Removed %s channel invite: %s\n", chname, invite);
-        add_mode(chan, '-', 'I', invite);
+               chan->dname, mask);
+        dprintf(idx, "Removed %s channel invite: %s\n", chan->dname, mask);
+        add_mode(chan, '-', 'I', mask);
         return;
       }
-      for (inv = chan->channel.invite; inv && inv->mask && inv->mask[0];
-           inv = inv->next) {
-        if (!rfc_casecmp(inv->mask, invite)) {
+    }
+    i = 0;
+    for (inv = chan->channel.invite; inv && inv->mask && inv->mask[0];
+         inv = inv->next) {
+      if (!u_equals_mask(global_invites, inv->mask) &&
+          !u_equals_mask(chan->invites, inv->mask)) {
+        i++;
+        if (i == -j) {
           add_mode(chan, '-', 'I', inv->mask);
-          dprintf(idx, "%s '%s' on %s.\n",
-                  IRC_REMOVEDINVITE, inv->mask, chan->dname);
+          dprintf(idx, "%s '%s' on %s.\n", IRC_REMOVEDINVITE,
+                  inv->mask, chan->dname);
           putlog(LOG_CMDS, "*", "#%s# (%s) -invite %s [on channel]",
                  dcc[idx].nick, dcc[idx].u.chat->con_chan, invite);
           return;
@@ -749,8 +733,25 @@ static void cmd_mns_invite (struct userrec *u, int idx, char *par)
       }
     }
   } else {
-    dprintf(idx, "Invalid channel.\n");
-    return;
+    j = u_delinvite(chan, invite, 1);
+    if (j > 0) {
+      putlog(LOG_CMDS, "*", "#%s# (%s) -invite %s", dcc[idx].nick,
+             dcc[idx].u.chat->con_chan, invite);
+      dprintf(idx, "Removed %s channel invite: %s\n", chname, invite);
+      add_mode(chan, '-', 'I', invite);
+      return;
+    }
+    for (inv = chan->channel.invite; inv && inv->mask && inv->mask[0];
+         inv = inv->next) {
+      if (!rfc_casecmp(inv->mask, invite)) {
+        add_mode(chan, '-', 'I', inv->mask);
+        dprintf(idx, "%s '%s' on %s.\n",
+                IRC_REMOVEDINVITE, inv->mask, chan->dname);
+        putlog(LOG_CMDS, "*", "#%s# (%s) -invite %s [on channel]",
+               dcc[idx].nick, dcc[idx].u.chat->con_chan, invite);
+        return;
+      }
+    }
   }
   dprintf(idx, "No such invite.\n");
 }
@@ -1134,8 +1135,12 @@ static void cmd_stick_yn(int idx, char *par, int yn)
       dprintf(idx, "No such channel.\n");
       return;
     }
-    if (i)
-      egg_snprintf(s, sizeof s, "%d", -i);
+    if (str_isdigit(s)) {
+      /* substract the numer of global exempts to get the number of the channel exempt */
+      j = u_setsticky_exempt(NULL, s, -1);
+      if (j < 0)
+        egg_snprintf(s, sizeof s, "%d", -j);
+    }
     j = u_setsticky_exempt(chan, s, yn);
     if (j > 0) {
       putlog(LOG_CMDS, "*", "#%s# %sstick exempt %s %s", dcc[idx].nick,
@@ -1172,8 +1177,12 @@ static void cmd_stick_yn(int idx, char *par, int yn)
       dprintf(idx, "No such channel.\n");
       return;
     }
-    if (i)
-      egg_snprintf(s, sizeof s, "%d", -i);
+    if (str_isdigit(s)) {
+      /* substract the numer of global invites to get the number of the channel invite */
+      j = u_setsticky_invite(NULL, s, -1);
+      if (j < 0)
+        egg_snprintf(s, sizeof s, "%d", -j);
+    }
     j = u_setsticky_invite(chan, s, yn);
     if (j > 0) {
       putlog(LOG_CMDS, "*", "#%s# %sstick invite %s %s", dcc[idx].nick,
@@ -1209,8 +1218,12 @@ static void cmd_stick_yn(int idx, char *par, int yn)
     dprintf(idx, "No such channel.\n");
     return;
   }
-  if (i)
-    egg_snprintf(s, sizeof s, "%d", -i);
+  if (str_isdigit(s)) {
+    /* substract the numer of global bans to get the number of the channel ban */
+    j = u_setsticky_ban(NULL, s, -1);
+    if (j < 0)
+      egg_snprintf(s, sizeof s, "%d", -j);
+  }
   j = u_setsticky_ban(chan, s, yn);
   if (j > 0) {
     putlog(LOG_CMDS, "*", "#%s# %sstick ban %s %s", dcc[idx].nick,

+ 16 - 10
src/mod/channels.mod/userchan.c

@@ -157,9 +157,11 @@ static int u_setsticky_mask(struct chanset_t *chan, maskrec *u, char *uhost,
 {
   int j;
 
-  j = atoi(uhost);
-  if (!j)
+  if (str_isdigit(uhost))
+    j = atoi(uhost);
+  else
     j = (-1);
+
   while(u) {
     if (j >= 0)
       j--;
@@ -169,7 +171,7 @@ static int u_setsticky_mask(struct chanset_t *chan, maskrec *u, char *uhost,
 	u->flags |= MASKREC_STICKY;
       else if (!sticky)
 	u->flags &= ~MASKREC_STICKY;
-      else	/* We don't actually want to change, just skip over */
+      else				/* We don't actually want to change, just skip over */
 	return 0;
       if (!j)
 	strcpy(uhost, u->mask);
@@ -182,6 +184,7 @@ static int u_setsticky_mask(struct chanset_t *chan, maskrec *u, char *uhost,
 
     u = u->next;
   }
+
   if (j >= 0)
     return -j;
 
@@ -222,7 +225,8 @@ static int u_delban(struct chanset_t *c, char *who, int doit)
   maskrec **u = (c) ? &c->bans : &global_bans;
   char temp[256];
 
-  if (!strchr(who, '!') && (j = atoi(who))) {
+  if (!strchr(who, '!') && str_isdigit(who)) {
+    j = atoi(who);
     j--;
     for (; (*u) && j; u = &((*u)->next), j--);
     if (*u) {
@@ -276,7 +280,8 @@ static int u_delexempt (struct chanset_t * c, char * who, int doit)
   maskrec *t;
   maskrec **u = c ? &(c->exempts) : &global_exempts;
 
-  if (!strchr(who,'!') && (j = atoi(who))) {
+  if (!strchr(who, '!') && str_isdigit(who)) {
+    j = atoi(who);
     j--;
     for (;(*u) && j;u=&((*u)->next),j--);
     if (*u) {
@@ -325,7 +330,8 @@ static int u_delinvite(struct chanset_t *c, char *who, int doit)
   maskrec *t;
   maskrec **u = c ? &(c->invites) : &global_invites;
 
-  if (!strchr(who,'!') && (j = atoi(who))) {
+  if (!strchr(who, '!') && str_isdigit(who)) {
+    j = atoi(who);
     j--;
     for (;(*u) && j;u=&((*u)->next),j--);
     if (*u) {
@@ -1171,7 +1177,7 @@ static int write_exempts(FILE *f, int idx)
   for (e = global_exempts; e; e = e->next) {
     mask = str_escape(e->mask, ':', '\\');
     if (!mask ||
-	lfprintf(f, "%s %s:%s%lu%s:+%lu:%lu:%s:%s\n", "%", e->mask,
+        lfprintf(f, "%s %s:%s%lu%s:+%lu:%lu:%s:%s\n", "%", mask,
 		(e->flags & MASKREC_PERM) ? "+" : "", e->expire,
 		(e->flags & MASKREC_STICKY) ? "*" : "", e->added,
 		e->lastactive, e->user ? e->user : botnetnick,
@@ -1196,7 +1202,7 @@ static int write_exempts(FILE *f, int idx)
 	for (e = chan->exempts; e; e = e->next) {
 	  mask = str_escape(e->mask, ':', '\\');
 	  if (!mask ||
-	      lfprintf(f,"%s %s:%s%lu%s:+%lu:%lu:%s:%s\n","%",e->mask,
+	      lfprintf(f,"%s %s:%s%lu%s:+%lu:%lu:%s:%s\n","%", mask,
 		      (e->flags & MASKREC_PERM) ? "+" : "", e->expire,
 		      (e->flags & MASKREC_STICKY) ? "*" : "", e->added,
 		      e->lastactive, e->user ? e->user : botnetnick,
@@ -1226,7 +1232,7 @@ static int write_invites(FILE *f, int idx)
   for (ir = global_invites; ir; ir = ir->next)  {
     mask = str_escape(ir->mask, ':', '\\');
     if (!mask ||
-	lfprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n",ir->mask,
+	lfprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
 		(ir->flags & MASKREC_PERM) ? "+" : "", ir->expire,
 		(ir->flags & MASKREC_STICKY) ? "*" : "", ir->added,
 		ir->lastactive, ir->user ? ir->user : botnetnick,
@@ -1251,7 +1257,7 @@ static int write_invites(FILE *f, int idx)
 	for (ir = chan->invites; ir; ir = ir->next) {
 	  mask = str_escape(ir->mask, ':', '\\');
 	  if (!mask ||
-	      lfprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n",ir->mask,
+	      lfprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
 		      (ir->flags & MASKREC_PERM) ? "+" : "", ir->expire,
 		      (ir->flags & MASKREC_STICKY) ? "*" : "", ir->added,
 		      ir->lastactive, ir->user ? ir->user : botnetnick,

+ 1 - 1
src/mod/module.h

@@ -238,7 +238,7 @@
 #define noshare (*(int *)(global[107]))
 /* 108 - 111 */
 #define do_chanset ((void (*)(struct chanset_t *, char *, int))global[108])
-/* 109: make_userfile -- UNUED (bryan) */
+#define str_isdigit ((int (*) (const char *))global[109])
 #define default_flags (*(int*)global[110])
 #define dcc_total (*(int*)global[111])
 /* 112 - 115 */

+ 1 - 1
src/modules.c

@@ -294,7 +294,7 @@ Function global_table[] =
   (Function) & noshare,		 /* int					*/
   /* 108 - 111 */
   (Function) do_chanset, 
-  (Function) 0,	 /* int					*/
+  (Function) str_isdigit,
   (Function) & default_flags,	 /* int					*/
   (Function) & dcc_total,	 /* int					*/
   /* 112 - 115 */

+ 4 - 3
src/proto.h

@@ -277,9 +277,10 @@ void show_banner(int);
 char *extracthostname(char *);
 void make_rand_str(char *, int);
 int oatoi(const char *);
-char *str_escape(const char *str, const char div, const char mask);
-char *strchr_unescape(char *str, const char div, register const char esc_char);
-void str_unescape(char *str, register const char esc_char);
+char *str_escape(const char *, const char, const char);
+char *strchr_unescape(char *, const char, register const char);
+void str_unescape(char *, register const char);
+int str_isdigit(const char *);
 void kill_bot(char *, char *);
 int private(struct flag_record, struct chanset_t *, int);
 int chk_op(struct flag_record, struct chanset_t *);