Committer  : entrope
CVSROOT    : /cvsroot/undernet-ircu
Module     : ircu2.10
Commit time: 2005-10-18 03:21:03 UTC

Modified files:
     ChangeLog include/s_user.h ircd/ircd.c ircd/ircd_features.c
     ircd/m_defaults.c ircd/m_proto.c ircd/m_version.c ircd/s_user.c

Removed files:
     include/supported.h

Log message:

Implement dynamic updates of the ISUPPORT line(s).

---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.726 ircu2.10/ChangeLog:1.727
--- ircu2.10/ChangeLog:1.726    Mon Oct 17 10:16:56 2005
+++ ircu2.10/ChangeLog  Mon Oct 17 20:20:52 2005
@@ -1,3 +1,36 @@
+2005-10-17  Michael Poole <[EMAIL PROTECTED]>
+       This code inspired by ircd-hybrid's implementation of the same
+       idea.  Thanks, Dianora!
+
+       * include/s_user.h: Declare isupport manipulation functions.
+
+       * include/supported.h: Delete.
+
+       * ircd/ircd.c (main): Call init_isupport().
+
+       * ircd/ircd_features.c (set_isupport_*): New functions to set
+       feature-based isupport settings.
+
+       * ircd/m_defaults.c: Remove unused #include "supported.h".
+
+       * ircd/m_proto.c: Likewise.
+
+       * ircd/m_version.c: Likewise.
+
+       * ircd/s_user.c: Remove #include "supported.h".  Declare new
+       struct ISupport.
+       (isupport): New file-scope variable.
+       (isupport_lines): Likewise.
+       (touch_isupport): New function.
+       (get_clean_isupport): New function.
+       (add_isupport*): New functions.
+       (del_isupport): New function.
+       (build_isupport_lines): New function.
+       (init_isupport): New function.
+       (send_supported): Rewrite to use the above.
+
+       * ircd/Makefile.in: Update dependencies.
+
 2005-10-17  Diane Bruce  <[EMAIL PROTECTED]>
 
        * ircd/ircd_res.c: Don't send retries if the client did
Index: ircu2.10/include/s_user.h
diff -u ircu2.10/include/s_user.h:1.20 ircu2.10/include/s_user.h:1.21
--- ircu2.10/include/s_user.h:1.20      Sun Nov  7 11:34:15 2004
+++ ircu2.10/include/s_user.h   Mon Oct 17 20:20:53 2005
@@ -1,6 +1,6 @@
 /** @file s_user.h
  * @brief Miscellaneous user-related helper functions.
- * @version $Id: s_user.h,v 1.20 2004/11/07 19:34:15 entrope Exp $
+ * @version $Id: s_user.h,v 1.21 2005/10/18 03:20:53 entrope Exp $
  */
 #ifndef INCLUDED_s_user_h
 #define INCLUDED_s_user_h
@@ -101,6 +101,12 @@
 extern void add_target(struct Client *sptr, void *target);
 extern unsigned int umode_make_snomask(unsigned int oldmask, char *arg,
                                        int what);
+
+extern void init_isupport(void);
+extern void add_isupport(const char *name);
+extern void add_isupport_i(const char *name, int value);
+extern void add_isupport_s(const char *name, const char *value);
+extern void del_isupport(const char *name);
 extern int send_supported(struct Client *cptr);
 
 #define NAMES_ALL 1 /**< List all users in channel */
Index: ircu2.10/include/supported.h
diff -u ircu2.10/include/supported.h:1.20 ircu2.10/include/supported.h:removed
--- ircu2.10/include/supported.h:1.20   Mon Aug 15 16:22:50 2005
+++ ircu2.10/include/supported.h        Mon Oct 17 20:21:04 2005
@@ -1,71 +0,0 @@
-/*
- * IRC - Internet Relay Chat, include/supported.h
- * Copyright (C) 1999 Perry Lorier.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: supported.h,v 1.20 2005/08/15 23:22:50 entrope Exp $
- *
- * Description: This file has the featureset that ircu announces on connecting
- *              a client.  It's in this .h because it's likely to be appended
- *              to frequently and s_user.h is included by basically everyone.
- */
-#ifndef INCLUDED_supported_h
-#define INCLUDED_supported_h
-
-#include "channel.h"
-#include "ircd_defs.h"
-
-/* 
- * 'Features' supported by this ircd
- */
-#define FEATURES1 \
-                "WHOX"\
-                " WALLCHOPS"\
-                " WALLVOICES"\
-                " USERIP"\
-                " CPRIVMSG"\
-                " CNOTICE"\
-                " SILENCE=%i" \
-                " MODES=%i" \
-                " MAXCHANNELS=%i" \
-                " MAXBANS=%i" \
-                " NICKLEN=%i" \
-                " MAXNICKLEN=%i" \
-                " TOPICLEN=%i" \
-                " AWAYLEN=%i" \
-                " KICKLEN=%i" \
-                " CHANNELLEN=%i" \
-                " MAXCHANNELLEN=%i"
-
-#define FEATURES2 "CHANTYPES=%s" \
-                " PREFIX=%s" \
-                " STATUSMSG=%s" \
-                " CHANMODES=%s" \
-                " CASEMAPPING=%s" \
-                " NETWORK=%s"
-
-#define FEATURESVALUES1 feature_int(FEAT_MAXSILES), MAXMODEPARAMS, \
-                       feature_int(FEAT_MAXCHANNELSPERUSER), \
-                        feature_int(FEAT_MAXBANS), feature_int(FEAT_NICKLEN), \
-                        NICKLEN, TOPICLEN, AWAYLEN, TOPICLEN, \
-                        feature_int(FEAT_CHANNELLEN), CHANNELLEN
-
-#define FEATURESVALUES2 (feature_bool(FEAT_LOCAL_CHANNELS) ? "#&" : "#"), 
"(ov)@+", "@+", \
-                        (feature_bool(FEAT_OPLEVELS) ? "b,AkU,l,imnpstrDd" : 
"b,k,l,imnpstrDd"), \
-                        "rfc1459", feature_str(FEAT_NETWORK)
-
-#endif /* INCLUDED_supported_h */
-
Index: ircu2.10/ircd/ircd.c
diff -u ircu2.10/ircd/ircd.c:1.91 ircu2.10/ircd/ircd.c:1.92
--- ircu2.10/ircd/ircd.c:1.91   Mon Sep 12 15:52:01 2005
+++ ircu2.10/ircd/ircd.c        Mon Oct 17 20:20:53 2005
@@ -19,7 +19,7 @@
  */
 /** @file
  * @brief Entry point and other initialization functions for the daemon.
- * @version $Id: ircd.c,v 1.91 2005/09/12 22:52:01 decampos Exp $
+ * @version $Id: ircd.c,v 1.92 2005/10/18 03:20:53 entrope Exp $
  */
 #include "config.h"
 
@@ -84,6 +84,7 @@
  * External stuff
  *--------------------------------------------------------------------------*/
 extern void init_counters(void);
+extern void init_isupport(void);
 extern void mem_dbg_initialise(void);
 
 /*----------------------------------------------------------------------------
@@ -679,6 +680,7 @@
   event_init(MAXCONNECTIONS);
 
   setup_signals();
+  init_isupport();
   feature_init(); /* initialize features... */
   log_init(*argv);
   set_nomem_handler(outofmemory);
Index: ircu2.10/ircd/ircd_features.c
diff -u ircu2.10/ircd/ircd_features.c:1.51 ircu2.10/ircd/ircd_features.c:1.52
--- ircu2.10/ircd/ircd_features.c:1.51  Tue Oct  4 19:15:20 2005
+++ ircu2.10/ircd/ircd_features.c       Mon Oct 17 20:20:53 2005
@@ -18,7 +18,7 @@
  */
 /** @file
  * @brief Implementation of configurable feature support.
- * @version $Id: ircd_features.c,v 1.51 2005/10/05 02:15:20 entrope Exp $
+ * @version $Id: ircd_features.c,v 1.52 2005/10/18 03:20:53 entrope Exp $
  */
 #include "config.h"
 
@@ -41,6 +41,7 @@
 #include "s_bsd.h"
 #include "s_debug.h"
 #include "s_misc.h"
+#include "s_user.h"
 #include "send.h"
 #include "struct.h"
 #include "sys.h"    /* FALSE bleah */
@@ -207,6 +208,54 @@
   }
 }
 
+static void
+set_isupport_maxsiles(void)
+{
+    add_isupport_i("SILENCE", feature_int(FEAT_MAXSILES));
+}
+
+static void
+set_isupport_maxchannels(void)
+{
+    add_isupport_i("MAXCHANNELS", feature_int(FEAT_MAXCHANNELSPERUSER));
+}
+
+static void
+set_isupport_maxbans(void)
+{
+    add_isupport_i("MAXBANS", feature_int(FEAT_MAXBANS));
+}
+
+static void
+set_isupport_nicklen(void)
+{
+    add_isupport_i("NICKLEN", feature_int(FEAT_NICKLEN));
+}
+
+static void
+set_isupport_channellen(void)
+{
+    add_isupport_i("CHANNELLEN", feature_int(FEAT_CHANNELLEN));
+}
+
+static void
+set_isupport_chantypes(void)
+{
+    add_isupport_s("CHANTYPES", feature_bool(FEAT_LOCAL_CHANNELS) ? "#&" : 
"#");
+}
+
+static void
+set_isupport_chanmodes(void)
+{
+    add_isupport_s("CHANMODES", feature_bool(FEAT_OPLEVELS) ? 
"b,AkU,l,imnpstrDd" : "b,k,l,imnpstrDd");
+}
+
+static void
+set_isupport_network(void)
+{
+    add_isupport_s("NETWORK", feature_str(FEAT_NETWORK));
+}
+
 /** Sets a feature to the given value.
  * @param[in] from Client trying to set parameters.
  * @param[in] fields Array of parameters to set.
@@ -308,18 +357,18 @@
   F_S(HIDDEN_HOST, FEAT_CASE, "users.undernet.org", 0),
   F_S(HIDDEN_IP, 0, "127.0.0.1", 0),
   F_B(CONNEXIT_NOTICES, 0, 0, 0),
-  F_B(OPLEVELS, 0, 1, 0),
-  F_B(LOCAL_CHANNELS, 0, 1, 0),
+  F_B(OPLEVELS, 0, 1, set_isupport_chanmodes),
+  F_B(LOCAL_CHANNELS, 0, 1, set_isupport_chantypes),
   F_B(TOPIC_BURST, 0, 0, 0),
   F_B(USER_GLIST, 0, 1, 0),
 
   /* features that probably should not be touched */
   F_I(KILLCHASETIMELIMIT, 0, 30, 0),
-  F_I(MAXCHANNELSPERUSER, 0, 10, 0),
-  F_I(NICKLEN, 0, 12, 0),
+  F_I(MAXCHANNELSPERUSER, 0, 10, set_isupport_maxchannels),
+  F_I(NICKLEN, 0, 12, set_isupport_nicklen),
   F_I(AVBANLEN, 0, 40, 0),
-  F_I(MAXBANS, 0, 45, 0),
-  F_I(MAXSILES, 0, 15, 0),
+  F_I(MAXBANS, 0, 45, set_isupport_maxbans),
+  F_I(MAXSILES, 0, 15, set_isupport_maxsiles),
   F_I(HANGONGOODLINK, 0, 300, 0),
   F_I(HANGONRETRYDELAY, 0, 10, 0),
   F_I(CONNECTTIMEOUT, 0, 90, 0),
@@ -333,7 +382,7 @@
   F_I(IPCHECK_CLONE_LIMIT, 0, 4, 0),
   F_I(IPCHECK_CLONE_PERIOD, 0, 40, 0),
   F_I(IPCHECK_CLONE_DELAY, 0, 600, 0),
-  F_I(CHANNELLEN, 0, 200, 0),
+  F_I(CHANNELLEN, 0, 200, set_isupport_channellen),
 
   /* Some misc. default paths */
   F_S(MPATH, FEAT_CASE | FEAT_MYOPER, "ircd.motd", motd_init),
@@ -403,7 +452,7 @@
   F_S(HIS_URLSERVERS, 0, "http://www.undernet.org/servers.php";, 0),
 
   /* Misc. random stuff */
-  F_S(NETWORK, 0, "UnderNet", 0),
+  F_S(NETWORK, 0, "UnderNet", set_isupport_network),
   F_S(URL_CLIENTS, 0, "ftp://ftp.undernet.org/pub/irc/clients";, 0),
 
 #undef F_S
Index: ircu2.10/ircd/m_defaults.c
diff -u ircu2.10/ircd/m_defaults.c:1.6 ircu2.10/ircd/m_defaults.c:1.7
--- ircu2.10/ircd/m_defaults.c:1.6      Fri Dec 10 21:13:46 2004
+++ ircu2.10/ircd/m_defaults.c  Mon Oct 17 20:20:53 2005
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: m_defaults.c,v 1.6 2004/12/11 05:13:46 klmitch Exp $
+ * $Id: m_defaults.c,v 1.7 2005/10/18 03:20:53 entrope Exp $
  */
 #include "config.h"
 
@@ -31,7 +31,6 @@
 #include "numeric.h"
 #include "numnicks.h"
 #include "send.h"
-#include "supported.h"
 #include "version.h"
 
 /* #include <assert.h> -- Now using assert in ircd_log.h */
Index: ircu2.10/ircd/m_proto.c
diff -u ircu2.10/ircd/m_proto.c:1.6 ircu2.10/ircd/m_proto.c:1.7
--- ircu2.10/ircd/m_proto.c:1.6 Fri Dec 10 21:13:48 2004
+++ ircu2.10/ircd/m_proto.c     Mon Oct 17 20:20:53 2005
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: m_proto.c,v 1.6 2004/12/11 05:13:48 klmitch Exp $
+ * $Id: m_proto.c,v 1.7 2005/10/18 03:20:53 entrope Exp $
  */
 #include "config.h"
 
@@ -37,7 +37,6 @@
 #include "s_debug.h"
 #include "s_misc.h"
 #include "send.h"
-#include "supported.h"
 #include "version.h"
 
 /* #include <assert.h> -- Now using assert in ircd_log.h */
Index: ircu2.10/ircd/m_version.c
diff -u ircu2.10/ircd/m_version.c:1.16 ircu2.10/ircd/m_version.c:1.17
--- ircu2.10/ircd/m_version.c:1.16      Fri Dec 10 21:14:03 2004
+++ ircu2.10/ircd/m_version.c   Mon Oct 17 20:20:53 2005
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: m_version.c,v 1.16 2004/12/11 05:14:03 klmitch Exp $
+ * $Id: m_version.c,v 1.17 2005/10/18 03:20:53 entrope Exp $
  */
 
 /*
@@ -95,7 +95,6 @@
 #include "s_debug.h"
 #include "s_user.h"
 #include "send.h"
-#include "supported.h"
 #include "version.h"
 
 /* #include <assert.h> -- Now using assert in ircd_log.h */
Index: ircu2.10/ircd/s_user.c
diff -u ircu2.10/ircd/s_user.c:1.99 ircu2.10/ircd/s_user.c:1.100
--- ircu2.10/ircd/s_user.c:1.99 Tue Aug 16 18:57:03 2005
+++ ircu2.10/ircd/s_user.c      Mon Oct 17 20:20:53 2005
@@ -22,7 +22,7 @@
  */
 /** @file
  * @brief Miscellaneous user-related helper functions.
- * @version $Id: s_user.c,v 1.99 2005/08/17 01:57:03 entrope Exp $
+ * @version $Id: s_user.c,v 1.100 2005/10/18 03:20:53 entrope Exp $
  */
 #include "config.h"
 
@@ -58,7 +58,6 @@
 #include "s_serv.h" /* max_client_count */
 #include "send.h"
 #include "struct.h"
-#include "supported.h"
 #include "sys.h"
 #include "userload.h"
 #include "version.h"
@@ -1729,6 +1728,203 @@
   return 1;
 }
 
+/** Describes one element of the ISUPPORT list. */
+struct ISupport {
+    const char *is_name; /**< Name of supported feature. */
+    enum {
+        OPT_NONE,
+        OPT_INT,
+        OPT_STRING
+    } is_type; /**< Type of the feature's value. */
+    union {
+        int iv;
+        char *sv;
+    } is_value; /**< Feature's value. */
+    struct ISupport *is_next; /**< Pointer to next feature. */
+};
+
+static struct ISupport *isupport; /**< List of supported ISUPPORT features. */
+static struct SLink *isupport_lines; /**< List of formatted ISUPPORT lines. */
+
+/** Mark #isupport_lines as dirty and needing a rebuild. */
+static void
+touch_isupport()
+{
+  while (isupport_lines) {
+    struct SLink *link = isupport_lines;
+    isupport_lines = link->next;
+    MyFree(link->value.cp);
+    free_link(link);
+  }
+}
+
+/** Get (or create) an ISupport element from #isupport with the
+ * specified name and OPT_NONE type.
+ * @param[in] name Name of ISUPPORT feature to describe.
+ * @return Pre-existing or newly allocated ISupport structure.
+ */
+static struct ISupport *
+get_clean_isupport(const char *name)
+{
+  struct ISupport *isv, *prev;
+
+  for (isv = isupport, prev = 0; isv; prev = isv, isv = isv->is_next) {
+    if (strcmp(isv->is_name, name))
+      continue;
+    if (isv->is_type == OPT_STRING)
+      MyFree(isv->is_value.sv);
+    break;
+  }
+
+  if (!isv) {
+    isv = MyMalloc(sizeof(*isv));
+    if (prev)
+        prev->is_next = isv;
+    else
+        isupport = isv;
+  }
+
+  isv->is_name = name;
+  isv->is_type = OPT_NONE;
+  isv->is_next = NULL;
+  touch_isupport();
+  return isv;
+}
+
+/** Declare support for a feature with no parameter.
+ * @param[in] name Name of ISUPPORT feature to announce.
+ */
+void add_isupport(const char *name)
+{
+  get_clean_isupport(name);
+}
+
+/** Declare support for a feature with an integer parameter.
+ * @param[in] name Name of ISUPPORT feature to announce.
+ * @param[in] value Value associated with the feature.
+ */
+void add_isupport_i(const char *name, int value)
+{
+  struct ISupport *isv = get_clean_isupport(name);
+  isv->is_type = OPT_INT;
+  isv->is_value.iv = value;
+}
+
+/** Declare support for a feature with a string parameter.
+ * @param[in] name Name of ISUPPORT feature to announce.
+ * @param[in] value Value associated with the feature.
+ */
+void add_isupport_s(const char *name, const char *value)
+{
+  struct ISupport *isv = get_clean_isupport(name);
+  isv->is_type = OPT_STRING;
+  DupString(isv->is_value.sv, value);
+}
+
+/** Stop announcing support for a feature.
+ * @param[in] name Name of ISUPPORT feature to revoke.
+ */
+void del_isupport(const char *name)
+{
+  struct ISupport *isv, *prev;
+
+  for (isv = isupport, prev = 0; isv; prev = isv, isv = isv->is_next) {
+    if (strcmp(isv->is_name, name))
+      continue;
+    if (isv->is_type == OPT_STRING)
+      MyFree(isv->is_value.sv);
+    if (prev)
+      prev->is_next = isv->is_next;
+    else
+      isupport = isv->is_next;
+    break;
+  }
+  touch_isupport();
+}
+
+/** Populate #isupport_lines from #isupport. */
+static void
+build_isupport_lines()
+{
+  struct ISupport *is;
+  struct SLink **plink;
+  char buf[BUFSIZE];
+  int used, len, usable;
+
+  /* Extra buffer space for :me.name 005 ClientNick <etc> */
+  assert(isupport_lines == 0);
+  usable = BUFSIZE - 10
+      - strlen(cli_name(&me))
+      - strlen(get_error_numeric(RPL_ISUPPORT)->format)
+      - feature_int(FEAT_NICKLEN);
+  plink = &isupport_lines;
+  used = 0;
+
+  /* For each ISUPPORT feature, */
+  for (is = isupport; is; ) {
+    /* Try to append it to the buffer. */
+    switch (is->is_type) {
+    case OPT_NONE:
+      len = ircd_snprintf(NULL, buf + used, usable - used,
+                          " %s", is->is_name);
+      break;
+    case OPT_INT:
+      len = ircd_snprintf(NULL, buf + used, usable - used,
+                          " %s=%d", is->is_name, is->is_value.iv);
+      break;
+    case OPT_STRING:
+      len = ircd_snprintf(NULL, buf + used, usable - used,
+                          " %s=%s", is->is_name, is->is_value.sv);
+      break;
+    default:
+      assert(0 && "Unhandled ISUPPORT option type");
+      len = 0;
+      break;
+    }
+
+    /* If it fits, move on; else flush buffer and try again. */
+    if (len + used < usable) {
+      used += len;
+      is = is->is_next;
+    } else {
+      assert(used > 0);
+      *plink = make_link();
+      DupString((*plink)->value.cp, buf + 1);
+      (*plink)->next = 0;
+      plink = &(*plink)->next;
+      used = 0;
+    }
+  }
+
+  /* Terminate buffer and flush last bit of it out. */
+  buf[used] = '\0';
+  *plink = make_link();
+  DupString((*plink)->value.cp, buf + 1);
+  (*plink)->next = 0;
+}
+
+/** Announce fixed-parameter and parameter-free ISUPPORT features
+ * provided by ircu's core code.
+ */
+void init_isupport(void)
+{
+  add_isupport("WHOX");
+  add_isupport("WALLCHOPS");
+  add_isupport("WALLVOICES");
+  add_isupport("USERIP");
+  add_isupport("CPRIVMSG");
+  add_isupport("CNOTICE");
+  add_isupport_i("MODES", MAXMODEPARAMS);
+  add_isupport_i("MAXNICKLEN", NICKLEN);
+  add_isupport_i("TOPICLEN", TOPICLEN);
+  add_isupport_i("AWAYLEN", AWAYLEN);
+  add_isupport_i("KICKLEN", TOPICLEN);
+  add_isupport_i("MAXCHANNELLEN", CHANNELLEN);
+  add_isupport_s("PREFIX", "(ov)@+");
+  add_isupport_s("STATUSMSG", "@+");
+  add_isupport_s("CASEMAPPING", "rfc1459");
+}
+
 /** Send RPL_ISUPPORT lines to \a cptr.
  * @param[in] cptr Client to send ISUPPORT to.
  * @return Zero.
@@ -1736,12 +1932,13 @@
 int
 send_supported(struct Client *cptr)
 {
-  char featurebuf[512];
+  struct SLink *line;
+
+  if (isupport && !isupport_lines)
+    build_isupport_lines();
 
-  ircd_snprintf(0, featurebuf, sizeof(featurebuf), FEATURES1, FEATURESVALUES1);
-  send_reply(cptr, RPL_ISUPPORT, featurebuf);
-  ircd_snprintf(0, featurebuf, sizeof(featurebuf), FEATURES2, FEATURESVALUES2);
-  send_reply(cptr, RPL_ISUPPORT, featurebuf);
+  for (line = isupport_lines; line; line = line->next)
+    send_reply(cptr, RPL_ISUPPORT, line->value.cp);
 
   return 0; /* convenience return, if it's ever needed */
 }
----------------------- End of diff -----------------------
_______________________________________________
Patches mailing list
[email protected]
http://undernet.sbg.org/mailman/listinfo/patches

Reply via email to