Browse Source

Merge branch 'random_stuff'

* random_stuff: (32 commits)
  Simplify class for C++11
  RfcString will never be assigned via rvalue
  Tweak connect burst to be even faster/deeper
  Joining from getin_request is fine during burst, it will just queue.
  Log how many auth entries will be removed
  CPRIVMSG/CNOTICE/TIME/TOPIC/OPER should end connection bursting on ratbox.
  These function ptrs can be static
  These are const but still needed.
  Appease Clang 8
  Remove dead code transfer_init()
  got353 is dead (RPL_NAMREPLY)
  Remove dead function init_debug()
  Add more pure functions
  Remove dead function lower_bot_linked
  GCC doesn't like the empty irc_log() macro after an else statement
  GCC says these attributes do nothing
  Enable -Wusggest-attribute
  Update bdlib
  HashTable.keys() removed
  This can be const
  ...
Bryan Drewery 7 years ago
parent
commit
9bfb1f0bfc

+ 1 - 0
build/autotools/configure.ac

@@ -53,6 +53,7 @@ if [[ "${ax_cv_prog_cc_fsanitize_address}" = "yes" ]]; then
   DEBCXXFLAGS="${DEBCXXFLAGS} -D__SANITIZE_ADDRESS__"
 fi
 CXX_FLAG_CHECK([DEBCXXFLAGS], [-fstack-protector-all], [stackprotectorall])
+CXX_FLAG_CHECK([DEBCXXFLAGS], [-Wsuggest-attribute=pure -Wsuggest-attribute=const], [wsuggest_attribute])
 CXX_FLAG_CHECK([DEBCXXFLAGS], [-Wconditional-uninitialized], [w_conditional_uninitialized])
 CXX_FLAG_CHECK([LDFLAGS], [-static-libstdc++], [static_libstdcxx])
 #CXX_FLAG_CHECK([LDFLAGS], [-static-libgcc], [static_libgcc])

+ 57 - 0
configure

@@ -4103,6 +4103,63 @@ EOF
   fi
 
 
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler understands -Wsuggest-attribute=pure -Wsuggest-attribute=const" >&5
+$as_echo_n "checking whether the compiler understands -Wsuggest-attribute=pure -Wsuggest-attribute=const... " >&6; }
+if ${ax_cv_prog_cc_wsuggest_attribute+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    ac_saved_flags="$CXXFLAGS"
+    CXXFLAGS="-Werror -Wsuggest-attribute=pure -Wsuggest-attribute=const"
+    cat build/confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end build/confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_prog_cc_wsuggest_attribute="yes"
+else
+  ax_cv_prog_cc_wsuggest_attribute="no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    CXXFLAGS="$ac_saved_flags"
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_prog_cc_wsuggest_attribute" >&5
+$as_echo "$ax_cv_prog_cc_wsuggest_attribute" >&6; }
+
+  if [ "$ax_cv_prog_cc_wsuggest_attribute" = "yes" ]; then
+    DEBCXXFLAGS="$DEBCXXFLAGS -Wsuggest-attribute=pure -Wsuggest-attribute=const"
+  elif [ -n "" ]; then
+      cat << 'EOF' >&2
+configure: error:
+
+  Your OS or C++ compiler does not support -Wsuggest-attribute=pure -Wsuggest-attribute=const.
+  This compile flag is required.
+
+EOF
+    exit 1
+  fi
+
+
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler understands -Wconditional-uninitialized" >&5
 $as_echo_n "checking whether the compiler understands -Wconditional-uninitialized... " >&6; }
 if ${ax_cv_prog_cc_w_conditional_uninitialized+:} false; then :

+ 3 - 0
doc/UPDATES.md

@@ -10,6 +10,9 @@
   * Add 'chanset homechan-user [nothing/voice/op]' to auto-voice or auto-op
     clients who are opped in 'set homechan'.
   * Some small performance improvements.
+  * CPRIVMSG/CNOTICE/TIME/TOPIC/OPER should end connection bursting on ratbox.
+  * Fix server connect bursting for joining channels with help from other bots.
+  * Tweak server connect burst to progress quicker.
 
 # maint
   * Clear FiSH keys when a client quits.

+ 1 - 1
lib/bdlib

@@ -1 +1 @@
-Subproject commit 3f1b81af3a4b70cea90230b7f923589f2b9f5973
+Subproject commit 1dd7d209178f3264110f3f8c25856c31c6e3fe13

+ 7 - 4
src/EncryptedStream.h

@@ -23,16 +23,19 @@ namespace bd {
 class EncryptedStream : public bd::Stream {
   private:
         bd::String key;
-        mutable char enc_flags;
+        mutable char enc_flags{ENC_DEFAULT};
         void apply_filters(bd::String& buf, const bd::String& IV) const;
         void unapply_filters(bd::String& buf, const bd::String& IV) const;
 
   protected:
 
   public:
-        EncryptedStream(const char* keyStr) : Stream(), key(bd::String(keyStr)), enc_flags(ENC_DEFAULT) {};
-        EncryptedStream(bd::String& keyStr) : Stream(), key(keyStr), enc_flags(ENC_DEFAULT) {};
-        EncryptedStream(EncryptedStream& stream) : Stream(stream), key(stream.key), enc_flags(ENC_DEFAULT) {};
+        EncryptedStream(const char* keyStr) : key(bd::String(keyStr)) {};
+        EncryptedStream(const bd::String& keyStr) : key(keyStr) {};
+        EncryptedStream(bd::String&& keyStr) noexcept :
+          key(std::move(keyStr)) {};
+        EncryptedStream(const EncryptedStream& stream) = default;
+        EncryptedStream(EncryptedStream&& stream) noexcept = default;
 
         inline void setFlags(const char _enc_flags) const noexcept {
           enc_flags = _enc_flags;

+ 19 - 7
src/RfcString.h

@@ -8,14 +8,26 @@ namespace bd {
 #include <bdlib/src/String.h>
 
 class RfcString : public bd::String {
-  private:
-
-  protected:
-
   public:
     using String::String;
-    RfcString(const String &str) : String(str) {};
-    RfcString(String &&str) : String(std::move(str)) {};
+    RfcString() = default;
+    RfcString(const RfcString& str) = default;
+    RfcString(RfcString&& str) noexcept = default;
+    RfcString(const String &str) : String(str) {}
+    RfcString(String &&str) noexcept :
+      String(std::move(str)) {}
+    using String::operator=;
+    RfcString& operator=(const RfcString& rhs) & = default;
+    RfcString& operator=(RfcString&& rhs) & noexcept = default;
+    RfcString& operator=(const String& rhs) & {
+      String::operator=(rhs);
+      return *this;
+    }
+
+    RfcString& operator=(String&& rhs) & noexcept {
+      String::operator=(std::move(rhs));
+      return *this;
+    }
 
     int compare(const RfcString& str, size_t n = npos) const noexcept
       __attribute__((pure));
@@ -26,7 +38,7 @@ class RfcString : public bd::String {
     friend bool operator>(const RfcString&, const RfcString&);
     friend bool operator>=(const RfcString&, const RfcString&);
 
-    virtual size_t hash() const noexcept;
+    size_t hash() const noexcept;
 };
 
 inline bool __attribute__((pure))

+ 10 - 5
src/adns.cc

@@ -169,7 +169,7 @@ static int read_resolv(char *fname);
 static void read_hosts(char *fname);
 static int get_dns_idx();
 //static void dns_resend_queries();
-static int cache_find(const char *);
+static int cache_find(const char *) __attribute__((pure));
 //static int dns_on_read(void *client_data, int idx, char *buf, int len);
 //static int dns_on_eof(void *client_data, int idx, int err, const char *errmsg);
 static void dns_read(int idx, char*, int&, bool blocking = 0);
@@ -418,7 +418,9 @@ static void egg_dns_send(char *query, int len, bool blocking)
 //	sockbuf_write(dns_idx, query, len);
 }
 
-dns_query_t *find_query(const char *host)
+static dns_query_t *
+__attribute__((pure))
+find_query(const char *host)
 {
 	dns_query_t *q = NULL;
 
@@ -892,7 +894,8 @@ static void cache_add(const char *query, bd::Array<bd::String> answer, int ttl)
 	ncache++;
 }
 
-static int cache_find(const char *query)
+static int
+cache_find(const char *query)
 {
 	int i;
 
@@ -1053,10 +1056,12 @@ int egg_dns_cancel(int id, int issue_callback)
 	return(0);
 }
 
-static int skip_name(unsigned char *ptr)
+static int
+__attribute__((pure))
+skip_name(const unsigned char *ptr)
 {
 	int len;
-	unsigned char *start = ptr;
+	const unsigned char *start = ptr;
 
 	while ((len = *ptr++) > 0) {
 		if (len > 63) {

+ 37 - 39
src/auth.cc

@@ -39,19 +39,19 @@
 #include "stat.h"
 
 bd::HashTable<bd::String, Auth*> Auth::ht_host(10);
-bd::HashTable<bd::String, Auth*> Auth::ht_nick(10);
+bd::HashTable<RfcString, Auth*> Auth::ht_nick(10);
 
-Auth::Auth(const char *_nick, const char *_host, struct userrec *u)
+Auth::Auth(const RfcString& _nick, const char *_host, struct userrec *u)
 {
   Status(AUTHING);
-  strlcpy(nick, _nick, NICKLEN);
+  nick = _nick;
   strlcpy(host, _host, UHOSTLEN);
   user = u;
 
   ht_host[host] = this;
   ht_nick[_nick] = this;
 
-  sdprintf(STR("New auth created! (%s!%s) [%s]"), nick, host,
+  sdprintf(STR("New auth created! (%s!%s) [%s]"), nick.c_str(), host,
       u ? u->handle : "*");
   authtime = atime = now;
   idx = -1;
@@ -59,7 +59,7 @@ Auth::Auth(const char *_nick, const char *_host, struct userrec *u)
 
 Auth::~Auth()
 {
-  sdprintf(STR("Removing auth: (%s!%s) [%s]"), nick, host,
+  sdprintf(STR("Removing auth: (%s!%s) [%s]"), nick.c_str(), host,
       user ? user->handle : "*");
   ht_host.remove(host);
   ht_nick.remove(nick);
@@ -78,12 +78,12 @@ void Auth::Done() noexcept
   Status(AUTHED);
 }
 
-void Auth::NewNick(const char *newnick) noexcept
+void Auth::NewNick(const RfcString& newnick) noexcept
 {
   if (ht_nick.contains(nick)) {
     ht_nick.remove(nick);
   }
-  strlcpy(nick, newnick, NICKLEN);
+  nick = newnick;
   ht_nick[newnick] = this;
 }
 
@@ -92,7 +92,7 @@ Auth *Auth::Find(const char *_host) noexcept
 
   if (ht_host.contains(_host)) {
     Auth *auth = ht_host[_host];
-    sdprintf(STR("Found auth: (%s!%s) [%s]"), auth->nick, auth->host,
+    sdprintf(STR("Found auth: (%s!%s) [%s]"), auth->nick.c_str(), auth->host,
         auth->user ? auth->user->handle : "*");
     return auth;
   }
@@ -102,21 +102,24 @@ Auth *Auth::Find(const char *_host) noexcept
 static void auth_clear_users_block(const bd::String& key, Auth* auth)
 {
   if (auth->user) {
-    sdprintf(STR("Clearing USER for auth: (%s!%s) [%s]"), auth->nick,
+    sdprintf(STR("Clearing USER for auth: (%s!%s) [%s]"), auth->nick.c_str(),
         auth->host, auth->user ? auth->user->handle : "*");
     auth->user = NULL;
   }
 }
 
-void Auth::NullUsers(const char *nick) noexcept
+void Auth::NullUsers(const RfcString& nick) noexcept
 {
-  if (nick == NULL) {
-    for (auto& kv : ht_host) {
-      auth_clear_users_block(kv.first, kv.second);
-    }
-  } else if (ht_nick.contains(nick)) {
-    Auth* auth = ht_nick[nick];
-    auth_clear_users_block(nick, auth);
+  if (!ht_nick.contains(nick))
+    return;
+  auto auth = ht_nick[nick];
+  auth_clear_users_block(nick, auth);
+}
+
+void Auth::NullUsers(void) noexcept
+{
+  for (auto& kv : ht_host) {
+    auth_clear_users_block(kv.first, kv.second);
   }
 }
 
@@ -124,21 +127,16 @@ static void auth_fill_users_block(const bd::String& key, Auth* auth)
 {
   char from[NICKLEN + UHOSTLEN];
 
-  sdprintf(STR("Filling USER for auth: (%s!%s) [%s]"), auth->nick, auth->host,
+  sdprintf(STR("Filling USER for auth: (%s!%s) [%s]"), auth->nick.c_str(), auth->host,
       auth->user ? auth->user->handle : "*");
-  simple_snprintf(from, sizeof(from), "%s!%s", auth->nick, auth->host);
+  simple_snprintf(from, sizeof(from), "%s!%s", auth->nick.c_str(), auth->host);
   auth->user = get_user_by_host(from);
 }
 
-void Auth::FillUsers(const char *nick) noexcept
+void Auth::FillUsers(void) noexcept
 {
-  if (nick == NULL) {
-    for (auto& kv : ht_host) {
-      auth_fill_users_block(kv.first, kv.second);
-    }
-  } else if (ht_nick.contains(nick)) {
-    Auth *auth = ht_nick[nick];
-    auth_fill_users_block(nick, auth);
+  for (auto& kv : ht_host) {
+    auth_fill_users_block(kv.first, kv.second);
   }
 }
 
@@ -155,9 +153,9 @@ void Auth::ExpireAuths() noexcept
   for (const auto& kv : ht_host) {
     const bd::String& host = kv.first;
     const auto& auth = kv.second;
-    if (auth->Authed() && ((now - auth->atime) >= (60 * 60))) {
+    if (auth->Authed() && ((now - auth->atime) >= (1 * 60))) {
       putlog(LOG_DEBUG, "*", STR("Auth (%s!%s) [%s] expired."),
-          auth->nick, auth->host, auth->user ? auth->user->handle : "*");
+          auth->nick.c_str(), auth->host, auth->user ? auth->user->handle : "*");
       expired_hosts.push_back(host);
       ht_nick.remove(auth->nick);
       delete_auths.push_back(auth);
@@ -175,13 +173,13 @@ void Auth::DeleteAll() noexcept
 {
   if (!ischanhub())
     return;
-  putlog(LOG_DEBUG, "*", STR("Removing auth entries."));
+  putlog(LOG_DEBUG, "*", STR("Removing %zd auth entries."), ht_host.size());
   std::vector<const Auth*> delete_auths;
   delete_auths.reserve(ht_host.size());
   for (const auto& kv : ht_host) {
     const auto& auth = kv.second;
     putlog(LOG_DEBUG, "*", STR("Removing (%s!%s) [%s], from auth list."),
-        auth->nick, auth->host, auth->user ? auth->user->handle : "*");
+        auth->nick.c_str(), auth->host, auth->user ? auth->user->handle : "*");
     delete_auths.push_back(auth);
   }
   ht_host.clear();
@@ -198,7 +196,7 @@ void Auth::InitTimer() noexcept
 
 bool Auth::GetIdx(const char *chname) noexcept
 {
-sdprintf(STR("GETIDX: auth: %s, idx: %d"), nick, idx);
+sdprintf(STR("GETIDX: auth: %s, idx: %d"), nick.c_str(), idx);
   if (idx != -1) {
     if (!valid_idx(idx))
       idx = -1;
@@ -208,7 +206,7 @@ sdprintf(STR("GETIDX: auth: %s, idx: %d"), nick, idx);
       idx = -1;
     else {
       sdprintf(STR("FIRST FOUND: %d"), idx);
-      strlcpy(dcc[idx].simulbot, nick, sizeof(dcc[idx].simulbot));
+      strlcpy(dcc[idx].simulbot, nick.c_str(), sizeof(dcc[idx].simulbot));
       strlcpy(dcc[idx].u.chat->con_chan, chname ? chname : "*", sizeof(dcc[idx].u.chat->con_chan));
       return 1;
     }
@@ -220,11 +218,11 @@ sdprintf(STR("GETIDX: auth: %s, idx: %d"), nick, idx);
     if (dcc[i].type && dcc[i].irc &&
        (((chname && chname[0]) && !strcmp(dcc[i].simulbot, chname) &&
          user && !strcmp(dcc[i].nick, user->handle)) ||
-       (!(chname && chname[0]) && !strcmp(dcc[i].simulbot, nick)))) {
-      putlog(LOG_DEBUG, "*", STR("Simul found old idx for %s/%s: (%s!%s)"), nick, chname, nick, host);
+       (!(chname && chname[0]) && !strcmp(dcc[i].simulbot, nick.c_str())))) {
+      putlog(LOG_DEBUG, "*", STR("Simul found old idx for %s/%s: (%s!%s)"), nick.c_str(), chname, nick.c_str(), host);
       dcc[i].simultime = now;
       idx = i;
-      strlcpy(dcc[idx].simulbot, nick, sizeof(dcc[idx].simulbot));
+      strlcpy(dcc[idx].simulbot, nick.c_str(), sizeof(dcc[idx].simulbot));
       strlcpy(dcc[idx].u.chat->con_chan, chname ? chname : "*", sizeof(dcc[idx].u.chat->con_chan));
 
       return 1;
@@ -243,13 +241,13 @@ sdprintf(STR("GETIDX: auth: %s, idx: %d"), nick, idx);
     dcc[idx].simul = 0;		/* not -1, so it's cleaned up later */
     dcc[idx].status = STAT_COLOR;
     dcc[idx].u.chat->con_flags = 0;
-    strlcpy(dcc[idx].simulbot, nick, sizeof(dcc[idx].simulbot));
+    strlcpy(dcc[idx].simulbot, nick.c_str(), sizeof(dcc[idx].simulbot));
     strlcpy(dcc[idx].u.chat->con_chan, chname ? chname : "*", sizeof(dcc[idx].u.chat->con_chan));
     dcc[idx].u.chat->strip_flags = STRIP_ALL;
     strlcpy(dcc[idx].nick, user ? user->handle : "*", sizeof(dcc[idx].nick));
     strlcpy(dcc[idx].host, host, sizeof(dcc[idx].host));
     dcc[idx].addr = 0L;
-    simple_snprintf(from, sizeof(from), "%s!%s", nick, host);
+    simple_snprintf(from, sizeof(from), "%s!%s", nick.c_str(), host);
     dcc[idx].user = user ? user : get_user_by_host(from);
     return 1;
   }
@@ -262,7 +260,7 @@ void Auth::TellAuthed(int idx) noexcept
   for (const auto& kv : ht_host) {
     const Auth* auth = kv.second;
     dprintf(idx, "(%s!%s) [%s] authtime: %li, atime: %li, Status: %d\n",
-        auth->nick,
+        auth->nick.c_str(),
         auth->host, auth->user ? auth->user->handle : "*",
         (long)auth->authtime, (long)auth->atime, auth->Status());
   }

+ 9 - 6
src/auth.h

@@ -5,6 +5,8 @@
 #include <bdlib/src/String.h>
 #include <bdlib/src/HashTable.h>
 
+class RfcString;
+
 #define AUTHED	    1
 #define AUTHING     2
 /* These are what we are expecting back from the user */
@@ -14,7 +16,7 @@
 
 class Auth {
   public:
-  Auth(const char *, const char *, struct userrec * = NULL);
+  Auth(const RfcString&, const char *, struct userrec * = NULL);
   ~Auth();
 
   inline int Status(void) const noexcept __attribute__((pure)) {
@@ -30,11 +32,12 @@ class Auth {
   }
   bool GetIdx(const char *) noexcept;
   void Done() noexcept;
-  void NewNick(const char *nick) noexcept;
+  void NewNick(const RfcString&) noexcept;
 
   static Auth *Find(const char * host) noexcept __attribute__((pure));
-  static void NullUsers(const char *nick = NULL) noexcept;
-  static void FillUsers(const char *nick = NULL) noexcept;
+  static void NullUsers(const RfcString&) noexcept;
+  static void NullUsers(void) noexcept;
+  static void FillUsers(void) noexcept;
   static void ExpireAuths() noexcept;
   static void InitTimer() noexcept;
   static void DeleteAll() noexcept;
@@ -46,11 +49,11 @@ class Auth {
   int idx;			/* do they have an associated idx? */
   char hash[MD5_HASH_LENGTH + 1];       /* used for dcc authing */
   char rand[51];
-  char nick[NICKLEN];
+  RfcString nick;
   char host[UHOSTLEN];
 
   static bd::HashTable<bd::String, Auth*> ht_host;
-  static bd::HashTable<bd::String, Auth*> ht_nick;
+  static bd::HashTable<RfcString, Auth*> ht_nick;
 
   private:
   int status;

+ 6 - 2
src/binds.cc

@@ -156,7 +156,8 @@ static void bind_table_really_del(bind_table_t *table)
 	free(table);
 }
 
-bind_table_t *bind_table_lookup(const char *name)
+bind_table_t *
+bind_table_lookup(const char *name)
 {
 	bind_table_t *table = NULL;
 
@@ -177,7 +178,10 @@ bind_table_t *bind_table_lookup_or_fake(const char *name)
 
 
 /* Look up a bind entry based on either function name or id. */
-static bind_entry_t *bind_entry_lookup(bind_table_t *table, int id, const char *mask, const char *function_name, Function callback)
+static bind_entry_t *
+__attribute__((pure))
+bind_entry_lookup(bind_table_t *table, int id, const char *mask,
+		const char *function_name, Function callback)
 {
 	bind_entry_t *entry = NULL;
 	int hit;

+ 1 - 1
src/binds.h

@@ -71,7 +71,7 @@ int check_bind_hits(bind_table_t *table, const char *match, struct flag_record *
 
 bind_table_t *bind_table_add(const char *name, int nargs, const char *syntax, int match_type, int flags);
 void bind_table_del(bind_table_t *table);
-bind_table_t *bind_table_lookup(const char *name);
+bind_table_t *bind_table_lookup(const char *name) __attribute__((pure));
 bind_table_t *bind_table_lookup_or_fake(const char *name);
 //int bind_entry_add(bind_table_t *table, const char *flags, const char *mask, const char *function_name, int bind_flags, Function callback, void *client_data);
 //int bind_entry_del(bind_table_t *table, int id, const char *mask, const char *function_name, Function callback);

+ 0 - 4
src/botnet.cc

@@ -1813,8 +1813,4 @@ void zapfbot(int idx)
   lostdcc(idx);
 }
 
-void lower_bot_linked(int idx)
-{
-}
-
 /* vim: set sts=2 sw=2 ts=8 et: */

+ 1 - 1
src/botnet.h

@@ -11,7 +11,7 @@ extern tand_t		*tandbot;
 extern party_t		*party;
 extern int		tands;
 
-void lower_bot_linked(int idx);
+#define lower_bot_linked(idx) do {} while (0)
 void answer_local_whom(int, int);
 char *lastbot(const char *) __attribute__((pure));
 int nextbot(const char *) __attribute__((pure));

+ 41 - 19
src/chanprog.cc

@@ -32,6 +32,7 @@
 #include "common.h"
 #include "chanprog.h"
 #include "settings.h"
+#include "auth.h"
 #include "src/mod/irc.mod/irc.h"
 #include "src/mod/channels.mod/channels.h"
 #include "src/mod/server.mod/server.h"
@@ -123,10 +124,13 @@ struct userrec *check_chanlist(const char *host)
   strlcpy(buf, host, sizeof buf);
   uhost = buf;
   nick = splitnick(&uhost);
-  for (chan = chanset; chan; chan = chan->next)
-    for (m = chan->channel.member; m && m->nick[0]; m = m->next) 
-      if (!rfc_casecmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
-	return m->user;
+  const RfcString rfc_nick(nick);
+  for (chan = chanset; chan; chan = chan->next) {
+    if ((m = ismember(chan, rfc_nick)) != NULL &&
+        !strcasecmp(uhost, m->userhost)) {
+      return m->user;
+    }
+  }
   return NULL;
 }
 
@@ -144,25 +148,40 @@ struct userrec *check_chanlist_hand(const char *hand)
   return NULL;
 }
 
+/* Clear the user pointers in the chanlists.
+ *
+ * Necessary when a hostmask is added/removed, a user is added or a new
+ * userfile is loaded.
+ */
+void clear_chanlist(void)
+{
+  memberlist		*m = NULL;
+  struct chanset_t	*chan = NULL;
+
+  for (chan = chanset; chan; chan = chan->next) {
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
+      m->user = NULL;
+      m->tried_getuser = 0;
+    }
+  }
+
+  Auth::NullUsers();
+}
+
 /* Clear the user pointer of a specific nick in the chanlists.
  *
  * Necessary when a hostmask is added/removed, a nick changes, etc.
  * Does not completely invalidate the channel cache like clear_chanlist().
  */
-void clear_chanlist_member(const char *nick)
+void clear_chanlist_member(const RfcString& nick)
 {
   memberlist		*m = NULL;
   struct chanset_t	*chan = NULL;
 
   for (chan = chanset; chan; chan = chan->next) {
-    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
-      if (nick == NULL || !rfc_casecmp(m->nick, nick)) {
-	m->user = NULL;
-        m->tried_getuser = 0;
-        if (nick != NULL) {
-          break;
-        }
-      }
+    if ((m = ismember(chan, nick)) != NULL) {
+      m->user = NULL;
+      m->tried_getuser = 0;
     }
   }
 
@@ -180,10 +199,13 @@ void set_chanlist(const char *host, struct userrec *rec)
   strlcpy(buf, host, sizeof buf);
   uhost = buf;
   nick = splitnick(&uhost);
-  for (chan = chanset; chan; chan = chan->next)
-    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
-      if (!rfc_casecmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
-	m->user = rec;
+  const RfcString rfc_nick(nick);
+  for (chan = chanset; chan; chan = chan->next) {
+    if ((m = ismember(chan, rfc_nick)) != NULL &&
+        !strcasecmp(uhost, m->userhost)) {
+      m->user = rec;
+    }
+  }
 }
 
 /* 0 marks all channels
@@ -832,10 +854,10 @@ samechans(const char *nick, const char *delim)
 
 static struct chanset_t*
 __attribute__((pure))
-find_common_opped_chan(const bd::String& nick) {
+find_common_opped_chan(const RfcString& nick) {
   for (struct chanset_t* chan = chanset; chan; chan = chan->next) {
     if (channel_active(chan) && (me_op(chan) || me_voice(chan))) {
-      if (ismember(chan, nick.c_str()))
+      if (ismember(chan, nick))
         return chan;
     }
   }

+ 2 - 2
src/chanprog.h

@@ -24,8 +24,8 @@ void check_timers();
 void check_utimers();
 void rmspace(char *s);
 void set_chanlist(const char *host, struct userrec *rec);
-void clear_chanlist_member(const char *nick);
-#define clear_chanlist() clear_chanlist_member(NULL)
+void clear_chanlist(void);
+void clear_chanlist_member(const RfcString& nick);
 bool bot_shouldjoin(struct userrec*, const struct flag_record *, const struct chanset_t *, bool = 0);
 bool shouldjoin(const struct chanset_t *);
 const char *samechans(const char *, const char *);

+ 1 - 1
src/core_binds.h

@@ -1,7 +1,7 @@
 #ifndef _CORE_BINDS_H_
 #define _CORE_BINDS_H_
 
-#include "auth.h"
+class Auth;
 
 void core_binds_init();
 void check_bind_time(struct tm *tm);

+ 1 - 1
src/crypto/bf_util.cc

@@ -99,7 +99,7 @@ bd::String egg_bf_decrypt(bd::String in, const bd::String& key)
   if (in.size() < 12) return out;
 
   // Not valid base64
-  if (eggdrop_blowfish_base64_index[in[0]] == -1) return out;
+  if (eggdrop_blowfish_base64_index[int(in[0])] == -1) return out;
 
   int cut_off = in.length() % 12;
   if (cut_off > 0)

+ 2 - 1
src/dcc.cc

@@ -1993,7 +1993,8 @@ struct dcc_table DCC_SOCKET = {
   NULL
 };
 
-void
+static void
+__attribute__((const))
 dcc_identwait(int idx, char *buf, int len)
 {
   /* Ignore anything now */

+ 0 - 1
src/dccutil.h

@@ -3,7 +3,6 @@
 
 #include "common.h"
 #include "dcc.h"
-#include "auth.h"
 
 /* Public structure for the listening port map */
 struct portmap {

+ 0 - 4
src/debug.cc

@@ -80,10 +80,6 @@ void setlimits()
   setrlimit(RLIMIT_NOFILE, &fdlim);
 }
 
-void init_debug()
-{
-}
-
 void sdprintf (const char *format, ...)
 {
   char s[2001] = "";

+ 0 - 1
src/debug.h

@@ -36,7 +36,6 @@ extern char		get_buf[GET_BUFS][SGRAB + 5];
 void setlimits();
 void sdprintf (const char *, ...) __attribute__((format(printf, 1, 2)));
 void init_signals();
-void init_debug();
 
 #ifdef DEBUG
 #undef _assert

+ 1 - 1
src/enclink.h

@@ -40,7 +40,7 @@ struct enc_link_dcc {
 extern struct enc_link enclink[];
 
 
-extern int link_find_by_type(int);
+extern int link_find_by_type(int) __attribute__((pure));
 
 extern void link_link(int, int, int, direction_t);
 extern const char *link_write(int, const char *, size_t *);

+ 1 - 1
src/flags.cc

@@ -487,7 +487,7 @@ chk_homechan_user_op(const memberlist *m, const struct chanset_t *chan)
     return 0;
   if (homechan_chan == chan)
     return 0;
-  if (!(homechan_m = ismember(homechan_chan, m->nick)))
+  if (!(homechan_m = ismember(homechan_chan, *m->rfc_nick)))
     return 0;
   if (chan_hasop(homechan_m))
     return 1;

+ 1 - 1
src/log.h

@@ -36,7 +36,7 @@ char *maskname(int);
 #if 0
 void irc_log(struct chanset_t *, const char *, ...) __attribute__((format(printf, 2, 3)));
 #else
-#define irc_log(...)
+#define irc_log(...) do {} while (0)
 #endif
 void logfile(int type, const char *msg);
 

+ 0 - 3
src/main.cc

@@ -699,7 +699,6 @@ void irc_init();
 void channels_init();
 void compress_init();
 void share_init();
-void transfer_init();
 
 int main(int argc, char **argv)
 {
@@ -722,7 +721,6 @@ int main(int argc, char **argv)
   srandom(now % (mypid + getppid()) * randint(1000));
 
   setlimits();
-  init_debug();
   init_signals();
 
   if (strcmp(fake_md5, STR("596a96cc7bf9108cd896f33c44aedc8a"))) {
@@ -836,7 +834,6 @@ int main(int argc, char **argv)
     server_init();
     ctcp_init();
   }
-  transfer_init();
   share_init();
   update_init();
   console_init();

+ 2 - 3
src/mod/channels.mod/chanmisc.cc

@@ -1047,9 +1047,8 @@ void clear_channel(struct chanset_t *chan, bool reset)
 
   if (chan->channel.cached_members) {
     if (chan->channel.cached_members->size()) {
-      for (const auto& uhost : chan->channel.cached_members->keys()) {
-        // Delete the cached member
-        m = (*chan->channel.cached_members)[uhost];
+      for (const auto& kv : *(chan->channel.cached_members)) {
+        m = kv.second;
         delete_member(m);
       }
     }

+ 4 - 2
src/mod/channels.mod/channels.cc

@@ -577,7 +577,8 @@ static void get_mode_protect(struct chanset_t *chan, char *s, size_t ssiz)
 
 /* Returns true if this is one of the channel masks
  */
-bool ismodeline(masklist *m, const char *username)
+bool
+ismodeline(const masklist *m, const char *username)
 {
   for (; m && m->mask[0]; m = m->next)  
     if (!rfc_casecmp(m->mask, username))
@@ -587,7 +588,8 @@ bool ismodeline(masklist *m, const char *username)
 
 /* Returns true if user matches one of the masklist -- drummer
  */
-bool ismasked(masklist *m, const char *username)
+bool
+ismasked(const masklist *m, const char *username)
 {
   for (; m && m->mask[0]; m = m->next)
     if (wild_match(m->mask, (char *) username))

+ 5 - 5
src/mod/channels.mod/channels.h

@@ -46,16 +46,16 @@ bool expired_mask(struct chanset_t *, char *);
 void set_handle_laston(char *, struct userrec *, time_t);
 int u_delmask(char type, struct chanset_t *c, char *who, int doit);
 bool u_addmask(char type, struct chanset_t *, char *, const char *, const char *, time_t, int);
-int u_sticky_mask(maskrec *, char *);
+int u_sticky_mask(const maskrec *, const char *) __attribute__((pure));
 int u_setsticky_mask(struct chanset_t *, maskrec *, char *, int, const char);
 int SplitList(char *, const char *, int *, const char ***);
 int channel_modify(char *, struct chanset_t *, int, char **, bool);
 int channel_add(char *, const char *, char *, bool = 0);
 void clear_channel(struct chanset_t *, bool);
-int u_equals_mask(maskrec *, char *);
-bool u_match_mask(struct maskrec *, const char *);
-bool ismasked(masklist *, const char *);
-bool ismodeline(masklist *, const char *);
+int u_equals_mask(const maskrec *, const char *) __attribute__((pure));
+bool u_match_mask(const maskrec *, const char *) __attribute__((pure));
+bool ismasked(const masklist *, const char *) __attribute__((pure));
+bool ismodeline(const masklist *, const char *) __attribute__((pure));
 void channels_report(int, int);
 void channels_writeuserfile(bd::Stream&, int = 0);
 void rcmd_chans(char *, char *, char *);

+ 12 - 4
src/mod/channels.mod/userchan.cc

@@ -152,7 +152,9 @@ void set_handle_laston(char *chan, struct userrec *u, time_t n)
 
 /* Is this mask sticky?
  */
-int u_sticky_mask(maskrec *u, char *uhost)
+int
+__attribute__((pure))
+u_sticky_mask(const maskrec *u, const char *uhost)
 {
   for (; u; u = u->next)
     if (!rfc_casecmp(u->mask, uhost))
@@ -205,7 +207,9 @@ int u_setsticky_mask(struct chanset_t *chan, maskrec *u, char *uhost, int sticky
  *   1       temporary ban
  *   2       perm ban
  */
-int u_equals_mask(maskrec *u, char *mask)
+int
+__attribute__((pure))
+u_equals_mask(const maskrec *u, const char *mask)
 {
   for (; u; u = u->next)
     if (!rfc_casecmp(u->mask, mask)) {
@@ -217,7 +221,9 @@ int u_equals_mask(maskrec *u, char *mask)
   return 0;
 }
 
-bool u_match_mask(maskrec *rec, const char *mask)
+bool
+__attribute__((pure))
+u_match_mask(const maskrec *rec, const char *mask)
 {
   for (; rec; rec = rec->next)
     if (wild_match(rec->mask, mask) || match_cidr(rec->mask, mask))
@@ -225,7 +231,9 @@ bool u_match_mask(maskrec *rec, const char *mask)
   return 0;
 }
 
-static int count_mask(maskrec *rec)
+static int
+__attribute__((pure))
+count_mask(maskrec *rec)
 {
   int ret = 0;
 

+ 17 - 6
src/mod/irc.mod/chan.cc

@@ -296,7 +296,7 @@ void delete_member(memberlist* m) {
 
 static bool member_getuser(memberlist* m, bool act_on_lookup) {
   if (!m) return 0;
-  if (!m->user && !m->tried_getuser) {
+  if (!m->user && !m->tried_getuser && !m->is_me) {
     m->user = get_user_by_host(m->from);
     if (!m->user && m->userip[0]) {
       m->user = get_user_by_host(m->fromip);
@@ -307,6 +307,9 @@ static bool member_getuser(memberlist* m, bool act_on_lookup) {
     if (act_on_lookup && m->user)
       check_this_user(m->user->handle, 0, NULL);
 
+  } else if (!m->user && m->is_me) {
+    m->user = conf.bot->u;
+    m->tried_getuser = 1;
   }
   return !(m->user == NULL);
 }
@@ -2141,6 +2144,8 @@ static int got315(char *from, char *msg)
     force_join_chan(chan);
   } else {
     me->is_me = 1;
+    me->user = conf.bot->u;
+    me->tried_getuser = 1;
     if (!me->joined)
       me->joined = now;				/* set this to keep the whining masses happy */
     rebalance_roles_chan(chan);
@@ -2266,6 +2271,7 @@ static int got349(char *from, char *msg)
   return 0;
 }
 
+#if 0
 static void got353(char *from, char *msg)
 {
   char *chname = NULL;
@@ -2278,6 +2284,7 @@ static void got353(char *from, char *msg)
   fixcolon(msg);
   irc_log(chan, "%s", msg);
 }
+#endif
 
 /* got 346: invite exemption info
  * <server> 346 <to> <chan> <exemption>
@@ -2779,6 +2786,8 @@ static int gotjoin(char *from, char *chname)
 
 	if (match_my_nick(nick)) {
           m->is_me = 1;
+          m->user = conf.bot->u;
+          m->tried_getuser = 1;
 	  /* It was me joining! Need to update the channel record with the
 	   * unique name for the channel (as the server see's it). <cybah>
 	   */
@@ -3072,14 +3081,14 @@ static int gotnick(char *from, char *msg)
   nick = splitnick(&uhost);
   fixcolon(msg);
   irc_log(NULL, "[%s] Nick change: %s -> %s", samechans(nick, ","), nick, msg);
-  clear_chanlist_member(nick);	/* Cache for nick 'nick' is meaningless now. */
+  const RfcString rfc_nick(nick);
+  clear_chanlist_member(rfc_nick);	/* Cache for nick 'nick' is meaningless now. */
+
+  auto new_rfc_nick = std::make_shared<RfcString>(msg);
 
   Auth *auth = Auth::Find(uhost);
   if (auth)
-    auth->NewNick(msg);
-
-  const RfcString rfc_nick(nick);
-  auto new_rfc_nick = std::make_shared<RfcString>(msg);
+    auth->NewNick(*new_rfc_nick);
 
   /* Compose a nick!user@host for the new nick */
   simple_snprintf(s1, sizeof(s1), "%s!%s", msg, uhost);
@@ -3546,7 +3555,9 @@ static cmd_t irc_raw[] =
   {"347",	"",	(Function) got347,	"irc:347", LEAF},
   {"348",	"",	(Function) got348,	"irc:348", LEAF},
   {"349",	"",	(Function) got349,	"irc:349", LEAF},
+#if 0
   {"353",	"",	(Function) got353,	"irc:353", LEAF},
+#endif
   {"710",	"",	(Function) got710,	"irc:710", LEAF},
   {NULL,	NULL,	NULL,			NULL, 0}
 };

+ 11 - 12
src/mod/irc.mod/irc.cc

@@ -60,6 +60,7 @@ using std::swap;
 #include <bdlib/src/HashTable.h>
 #include <bdlib/src/base64.h>
 #include <deque>
+#include <vector>
 
 #include <stdarg.h>
 
@@ -677,11 +678,6 @@ getin_request(char *botnick, char *code, char *par)
     return;
   }
 
-  if (connect_bursting) {
-    putlog(LOG_GETIN, "*", "%sreq from %s/%s %s %s - I'm in connect burst mode.", type, botnick, nick, desc, chan->dname);
-    return;
-  }
-
   if (server_lag > lag_threshold) {
     putlog(LOG_GETIN, "*", "%sreq from %s/%s %s %s - I'm too lagged", type, botnick, nick, desc, chan->dname);
     return;
@@ -1235,7 +1231,7 @@ static void member_update_from_cache(struct chanset_t* chan, memberlist *m) {
 bool
 me_voice(const struct chanset_t *chan)
 {
-  memberlist *mx = ismember(chan, botname);
+  const memberlist *mx = ismember(chan, botname);
 
   if (!mx)
     return 0;
@@ -1249,6 +1245,7 @@ me_voice(const struct chanset_t *chan)
 /* Check if there are any ops on the channel. Returns boolean 1 or 0.
  */
 static bool
+__attribute__((pure))
 any_ops(struct chanset_t *chan)
 {
   memberlist *x = NULL;
@@ -1636,18 +1633,20 @@ check_expired_chanstuff(struct chanset_t *chan)
   }
   // Clear out expired cached members
   if (chan->channel.cached_members && chan->channel.cached_members->size()) {
-    bd::Array<bd::String> member_uhosts(chan->channel.cached_members->keys());
-    for (size_t i = 0; i < member_uhosts.length(); ++i) {
-      const bd::String uhost(member_uhosts[i]);
-
-      m = (*chan->channel.cached_members)[uhost];
+    std::vector<bd::String> expired_hosts;
+    for (const auto& kv : *(chan->channel.cached_members)) {
+      auto& uhost = kv.first;
+      m = kv.second;
 
       // Delete the expired member
       if (now - m->last > wait_split) {
         delete_member(m);
-        chan->channel.cached_members->remove(uhost);
+        expired_hosts.push_back(uhost);
       }
     }
+    for (const auto& uhost : expired_hosts) {
+      chan->channel.cached_members->remove(uhost);
+    }
   }
 }
 

+ 2 - 2
src/mod/irc.mod/irc.h

@@ -6,7 +6,6 @@
 #ifndef _EGG_MOD_IRC_IRC_H
 #define _EGG_MOD_IRC_IRC_H
 
-#include "src/auth.h"
 #include "src/chanprog.h"
 
 enum { BC_NOCOOKIE = 1, BC_SLACK, BC_HASH, BC_COUNTER };
@@ -18,6 +17,8 @@ enum { BC_NOCOOKIE = 1, BC_SLACK, BC_HASH, BC_COUNTER };
 #define NORMAL          0
 #define QUICK           1
 
+class Auth;
+
 #ifdef MAKING_IRC
 
 namespace bd {
@@ -70,7 +71,6 @@ static void cache_invite(struct chanset_t *, char *, char *, char *, bool, bool)
 void makecookie(char*, size_t, const char *, const memberlist*, const memberlist*, const memberlist* = NULL, const memberlist* = NULL);
 static int checkcookie(const char*, const memberlist*, const memberlist*, const char*, int);
 extern void counter_clear(const char*);
-static bool any_ops(struct chanset_t *);
 static char *getchanmode(struct chanset_t *);
 static void flush_mode(struct chanset_t *, int);
 static bool member_getuser(memberlist* m, bool act_on_lookup = 0);

+ 4 - 2
src/mod/irc.mod/mode.cc

@@ -158,8 +158,10 @@ flush_cookies(struct chanset_t *chan, int pri)
   if (post[0]) {
     memberlist* me = ismember(chan, botname);
 
-    if (me)
-      member_getuser(me);
+    if (me) {
+      me->user = conf.bot->u;
+      me->tried_getuser = 1;
+    }
 
     /* Am I even on the channel? */
     if (!me || !me->user)

+ 8 - 8
src/mod/irc.mod/msgcmds.cc

@@ -291,14 +291,14 @@ static int msg_invite(char *nick, char *host, struct userrec *u, char *par)
   return BIND_RET_BREAK;
 }
 
-static void logc(const char *cmd, Auth *a, char *chname, char *par)
+static void logc(const char *cmd, Auth *auth, char *chname, char *par)
 {
   if (chname && chname[0])
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %c%s %s", a->nick, a->host,
-        a->user ? a->user->handle : "*", chname, auth_prefix[0], cmd, par ? par : "");
+    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %c%s %s", auth->nick.c_str(), auth->host,
+        auth->user ? auth->user->handle : "*", chname, auth_prefix[0], cmd, par ? par : "");
   else
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %c%s %s", a->nick, a->host,
-        a->user ? a->user->handle : "*", auth_prefix[0], cmd, par ? par : "");
+    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %c%s %s", auth->nick.c_str(), auth->host,
+        auth->user ? auth->user->handle : "*", auth_prefix[0], cmd, par ? par : "");
 }
 #define LOGC(cmd) logc(cmd, a, chname, par)
   
@@ -326,7 +326,7 @@ static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
       return 0;
     }
   } else
-    auth = new Auth(nick, host, u);
+    auth = new Auth(RfcString(nick), host, u);
 
   /* Send "auth." if they are recognized, otherwise "auth!" */
   auth->Status(AUTH_PASS);
@@ -340,11 +340,11 @@ static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
 static void
 AuthFinish(Auth *auth)
 {
-  putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! +AUTH"), auth->nick, auth->host, auth->user ? auth->user->handle : "*");
+  putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! +AUTH"), auth->nick.c_str(), auth->host, auth->user ? auth->user->handle : "*");
   auth->Done();
   bd::String msg;
   msg = bd::String::printf(STR("You are now authorized for cmds, see %chelp"), auth_prefix[0]);
-  notice(auth->nick, msg, DP_HELP);
+  notice(auth->nick.c_str(), msg, DP_HELP);
 }
 
 static int msg_auth(char *nick, char *host, struct userrec *u, char *par)

+ 30 - 17
src/mod/server.mod/server.cc

@@ -51,6 +51,7 @@
 #include <bdlib/src/Array.h>
 #include "server.h"
 #include <stdarg.h>
+#include <vector>
 
 int default_alines = 5;		/* How many mode lines are assumed will work before throttling */
 bool floodless = 0;		/* floodless iline? */
@@ -130,7 +131,7 @@ static bind_table_t *BT_raw = NULL, *BT_msg = NULL;
 bind_table_t *BT_ctcr = NULL, *BT_ctcp = NULL;
 // Ratbox is (5*8):30, ircd-seven is (5*8):20, try to not push th elimits.
 #define SERVER_CONNECT_BURST_TIME 18
-#define SERVER_CONNECT_BURST_RATE 5 * 7
+#define SERVER_CONNECT_BURST_RATE 5 * 8
 
 #include "servmsg.cc"
 
@@ -170,9 +171,11 @@ static const struct {
 /*
  *     Bot server queues
  */
-static bool burst_mode_ok(const char *msg, size_t len) {
-  bd::String mode(msg, len);
-  bd::Array<bd::String> list(mode.split(' '));
+static bool
+__attribute__((pure))
+burst_mode_ok(const char *msg, size_t len) {
+  const bd::String mode(msg, len);
+  const auto list(mode.split(' '));
   if (list.length() == 2) return 1;
   if (list.length() == 3) {
     if (!strchr(CHANMETA, bd::String(list[1]).at(0))) return 1;
@@ -181,11 +184,10 @@ static bool burst_mode_ok(const char *msg, size_t len) {
   return 0;
 }
 
-// Hybrid/ratbox allows bursting 5*8 lines on connect until certain commands are sent, for up to 30 seconds
+// Hybrid/ratbox allows bursting MAX_FLOOD_BURST=5(MAX_FLOOD)*8 lines on connect until certain commands are sent, for up to 30 seconds
 /*
-   BAD:
+   BAD (src/packet.c flood_endgrace()):
      JOIN 0
-     MODE #chan b
      NICK
      PART
      KICK
@@ -203,18 +205,26 @@ static bool burst_mode_ok(const char *msg, size_t len) {
      WHO !
      WHO #Chan
      WHO NICK
+     MODE #chan
+     MODE #chan b
 */
-static bool burst_ok(const char* msg, size_t len) {
+static inline bool
+__attribute__((pure))
+burst_ok(const char* msg, size_t len) {
   if (strstr(msg, "JOIN 0") ||
       (strstr(msg, "MODE") && !burst_mode_ok(msg, len)) ||
       strstr(msg, "NICK") ||
+      strstr(msg, "CPRIVMSG") ||
       strstr(msg, "PRIVMSG") ||
+      strstr(msg, "CNOTICE") ||
       strstr(msg, "NOTICE") ||
       strstr(msg, "PART") ||
       strstr(msg, "KICK") ||
+      strstr(msg, "TIME") ||
+      strstr(msg, "OPER") ||
+      strstr(msg, "TOPIC") ||
       strstr(msg, "INVITE") ||
       strstr(msg, "AWAY")) {
-    sdprintf("BURST MODE VIOLATION!!!: %s\n", msg);
     return 0;
   }
   return 1;
@@ -644,8 +654,10 @@ void queue_server(int which, char *buf, int len)
 
   // If connect bursting, hold off any commands which would end the gracetime (flood_endgrace)
   if (connect_bursting && (which == DP_MODE || which == DP_MODE_NEXT || which == DP_SERVER || which == DP_SERVER_NEXT)) {
-    if (!burst_ok(buf, len))
+    if (!burst_ok(buf, len)) {
+      sdprintf("BURST MODE VIOLATION!!!: %s\n", buf);
       which = DP_HELP;
+    }
   }
 
   int qnext = 0;
@@ -1051,10 +1063,10 @@ static void server_secondly()
       }
 
       // Clear expired key exchanges that aren't finished (7 seconds)
-      const bd::Array<bd::String> fish_targets(FishKeys.keys());
-      for (size_t i = 0; i < fish_targets.length(); ++i) {
-        const bd::String target(fish_targets[i]);
-        fish_data_t* fishData = FishKeys[target];
+      std::vector<bd::String> expired_keys;
+      for (const auto& kv : FishKeys) {
+        auto& target = kv.first;
+        const auto fishData = kv.second;
         bool should_delete = false;
         if (fishData->key_created_at && !fishData->sharedKey && ((now - 7) >= fishData->key_created_at)) {
           putlog(LOG_DEBUG, "*", "Deleting expired DH1080 FiSH exchange with %s", target.c_str());
@@ -1063,13 +1075,14 @@ static void server_secondly()
           putlog(LOG_DEBUG, "*", "Deleting expired (60 min) FiSH key with %s", target.c_str());
           should_delete = true;
         }
-
         if (should_delete) {
-          FishKeys.remove(target);
           delete fishData;
+          expired_keys.push_back(target);
         }
       }
-
+      for (const auto& target : expired_keys) {
+        FishKeys.remove(target);
+      }
 
       cnt_10 = 0;
     } else {

+ 1 - 1
src/mod/server.mod/server.h

@@ -74,7 +74,7 @@ void release_nick(const char* = NULL);
 #define check_bind_ctcp(a, b, c, d, e, f) check_bind_ctcpr(a, b, c, d, e, f, BT_ctcp)
 #define check_bind_ctcr(a, b, c, d, e, f) check_bind_ctcpr(a, b, c, d, e, f, BT_ctcr)
 
-bool detect_avalanche(char *);
+bool detect_avalanche(const char *) __attribute__((pure));
 void server_report(int, int);
 void server_init();
 void queue_server(int, char *, int);

+ 4 - 3
src/mod/server.mod/servmsg.cc

@@ -339,7 +339,7 @@ got004(char *from, char *msg)
   if (!replaying_cache && connect_burst) {
     connect_bursting = now;
     msgburst = SERVER_CONNECT_BURST_RATE;
-    msgrate = 200;
+    msgrate = 0;
     reset_flood();
     putlog(LOG_DEBUG, "*", "Server allows connect bursting, bursting for %d seconds", SERVER_CONNECT_BURST_TIME);
   }
@@ -618,11 +618,12 @@ static bool detect_flood(char *floodnick, char *floodhost, char *from, int which
 /* Check for more than 8 control characters in a line.
  * This could indicate: beep flood CTCP avalanche.
  */
-bool detect_avalanche(char *msg)
+bool
+detect_avalanche(const char *msg)
 {
   int count = 0;
 
-  for (unsigned char *p = (unsigned char *) msg; (*p) && (count < 8); p++)
+  for (const unsigned char *p = (const unsigned char *) msg; (*p) && (count < 8); p++)
     if ((*p == 7) || (*p == 1))
       count++;
   if (count >= 8)

+ 15 - 17
src/mod/transfer.mod/transfer.cc

@@ -108,7 +108,7 @@ static unsigned long pump_file_to_sock(FILE *file, long sock,
   return pending_data;
 }
 
-void eof_dcc_fork_send(int idx)
+static void eof_dcc_fork_send(int idx)
 {
   fclose(dcc[idx].u.xfer->f);
   if (!strcmp(dcc[idx].nick, "*users")) {
@@ -266,7 +266,7 @@ inline static void handle_resend_packet(int idx, transfer_reget *reget_data)
  * Note: The first received packet during reget is a special 8 bit packet
  *       containing special information.
  */
-void dcc_get(int idx, char *buf, int len)
+static void dcc_get(int idx, char *buf, int len)
 {
   unsigned char bbuf[4] = "";
   unsigned long cmp, l;
@@ -396,7 +396,7 @@ void dcc_get(int idx, char *buf, int len)
   dcc[idx].status += l;
 }
 
-void eof_dcc_get(int idx)
+static void eof_dcc_get(int idx)
 {
   char s[1024] = "";
 
@@ -457,7 +457,7 @@ void eof_dcc_get(int idx)
   lostdcc(idx);
 }
 
-void dcc_send(int idx, char *buf, int len)
+static void dcc_send(int idx, char *buf, int len)
 {
   char s[SGRAB + 2] = "", *b = NULL;
   size_t siz = 0;
@@ -576,7 +576,7 @@ static void transfer_get_timeout(int i)
   }
 }
 
-void tout_dcc_send(int idx)
+static void tout_dcc_send(int idx)
 {
   fclose(dcc[idx].u.xfer->f);
   if (!strcmp(dcc[idx].nick, "*users")) {
@@ -610,7 +610,7 @@ void tout_dcc_send(int idx)
   lostdcc(idx);
 }
 
-void display_dcc_get(int idx, char *buf, size_t bufsiz)
+static void display_dcc_get(int idx, char *buf, size_t bufsiz)
 {
   if (dcc[idx].status == dcc[idx].u.xfer->length)
     simple_snprintf(buf, bufsiz, "send  (%lu)/%lu\n    Filename: %s\n", dcc[idx].u.xfer->acked,
@@ -620,22 +620,22 @@ void display_dcc_get(int idx, char *buf, size_t bufsiz)
 	    dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
 }
 
-void display_dcc_get_p(int idx, char *buf, size_t bufsiz)
+static void display_dcc_get_p(int idx, char *buf, size_t bufsiz)
 {
   simple_snprintf(buf, bufsiz, "send  waited %ds\n    Filename: %s\n", (int) (now - dcc[idx].timeval), dcc[idx].u.xfer->origname);
 }
 
-void display_dcc_send(int idx, char *buf, size_t bufsiz)
+static void display_dcc_send(int idx, char *buf, size_t bufsiz)
 {
   simple_snprintf(buf, bufsiz, "send  (%lu)/%lu\n    Filename: %s\n", dcc[idx].status, dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
 }
 
-void display_dcc_fork_send(int idx, char *buf, size_t bufsiz)
+static void display_dcc_fork_send(int idx, char *buf, size_t bufsiz)
 {
   simple_snprintf(buf, bufsiz, "conn  send");
 }
 
-void kill_dcc_xfer(int idx, void *x)
+static void kill_dcc_xfer(int idx, void *x)
 {
   struct xfer_info *p = (struct xfer_info *) x;
 
@@ -649,7 +649,9 @@ void kill_dcc_xfer(int idx, void *x)
   free(x);
 }
 
-void out_dcc_xfer(int idx, char *buf, void *x)
+static void
+__attribute__((const))
+out_dcc_xfer(int idx, char *buf, void *x)
 {
 }
 
@@ -675,7 +677,7 @@ struct dcc_table DCC_SEND =
   NULL
 };
 
-void dcc_fork_send(int idx, char *x, int y);
+static void dcc_fork_send(int idx, char *x, int y);
 
 struct dcc_table DCC_FORK_SEND =
 {
@@ -691,7 +693,7 @@ struct dcc_table DCC_FORK_SEND =
   NULL
 };
 
-void dcc_fork_send(int idx, char *x, int y)
+static void dcc_fork_send(int idx, char *x, int y)
 {
   if (dcc[idx].type != &DCC_FORK_SEND)
     return;
@@ -904,8 +906,4 @@ void transfer_report(int idx, int details)
 	    dcc_block, (dcc_block == 0) ? " (turbo dcc)" : "", dcc_limit);
   }
 }
-
-void transfer_init()
-{
-}
 /* vim: set sts=2 sw=2 ts=8 et: */

+ 3 - 3
src/rfc1459.cc

@@ -27,9 +27,9 @@
 #include "common.h"
 #include "rfc1459.h"
 
-int (*rfc_casecmp) (const char *, const char *) __attribute__((pure)) = _rfc_casecmp;
-int (*rfc_ncasecmp) (const char *, const char *, size_t) __attribute__((pure)) = _rfc_ncasecmp;
-bool (*rfc_char_equal) (const char, const char) __attribute__((const)) = _rfc_char_equal;
+int (*rfc_casecmp) (const char *, const char *) = _rfc_casecmp;
+int (*rfc_ncasecmp) (const char *, const char *, size_t) = _rfc_ncasecmp;
+bool (*rfc_char_equal) (const char, const char)  = _rfc_char_equal;
 
 int
 _rfc_casecmp(const char *s1, const char *s2)

+ 3 - 3
src/rfc1459.h

@@ -57,8 +57,8 @@ _rfc_char_equal(const char c1, const char c2)
   return _rfc_toupper(c1) == _rfc_toupper(c2);
 }
 
-extern bool (*rfc_char_equal) (const char, const char) __attribute__((const));
-extern int (*rfc_casecmp) (const char *, const char *) __attribute__((pure));
-extern int (*rfc_ncasecmp) (const char *, const char *, size_t) __attribute__((pure));
+extern bool (*rfc_char_equal) (const char, const char);
+extern int (*rfc_casecmp) (const char *, const char *);
+extern int (*rfc_ncasecmp) (const char *, const char *, size_t);
 
 #endif /* !_RFC1459_H */

+ 7 - 4
src/set.cc

@@ -143,7 +143,7 @@ static variable_t vars[] = {
 };
 
 
-static inline variable_t *var_get_var_by_name(const char *name);
+static inline variable_t *var_get_var_by_name(const char *name) __attribute__((pure));
 
 static const char* get_server_type()
 {
@@ -525,7 +525,7 @@ static int comp_variable_t(const void *m1, const void *m2) {
   return strcasecmp(mi1->name, mi2->name);
 }
 
-static inline variable_t * __attribute__((pure))
+static inline variable_t *
 var_get_var_by_name(const char *name)
 {
   variable_t key;
@@ -533,7 +533,7 @@ var_get_var_by_name(const char *name)
   return (variable_t*) bsearch(&key, &vars, lengthof(vars) - 1, sizeof(variable_t), comp_variable_t);
 }
 
-const char * __attribute__((pure))
+const char *
 var_get_gdata(const char *name) {
   variable_t* var = var_get_var_by_name(name);
   return var && var->gdata ? var->gdata : NULL;
@@ -673,7 +673,9 @@ const char *var_get_str_by_name(const char *name)
   return NULL;
 }
 
-void *var_get_by_name(const char *name)
+#if 0
+void *
+var_get_by_name(const char *name)
 {
   variable_t *var = NULL;
 
@@ -682,6 +684,7 @@ void *var_get_by_name(const char *name)
 
   return NULL;
 }
+#endif
 
 void init_vars()
 {

+ 3 - 1
src/userent.cc

@@ -107,7 +107,9 @@ void def_write_userfile(bd::Stream& stream, const struct userrec *u, const struc
   stream << bd::String::printf("--%s %s\n", e->type->name, e->u.string);
 }
 
-void *def_get(struct userrec *u, struct user_entry *e)
+void *
+__attribute__((pure))
+def_get(struct userrec *u, struct user_entry *e)
 {
   return e->u.string;
 }

+ 8 - 4
src/userrec.cc

@@ -29,6 +29,7 @@
 
 #include <sys/stat.h>
 #include "common.h"
+#include "auth.h"
 #include "userrec.h"
 #include "misc.h"
 #include "misc_file.h"
@@ -69,16 +70,19 @@ int		userfile_perm = 0600;	/* Userfile permissions,
 
 static bool		 sort_users = 1;	/* sort the userlist when saving    */
 
-int count_users(struct userrec *bu)
+int
+count_users(const struct userrec *bu)
 {
   int tot = 0;
 
-  for (struct userrec *u = bu; u; u = u->next)
+  for (const struct userrec *u = bu; u; u = u->next)
     tot++;
   return tot;
 }
 
-static struct userrec *check_dcclist_hand(const char *handle)
+static struct userrec *
+__attribute__((pure))
+check_dcclist_hand(const char *handle)
 {
   for (int i = 0; i < dcc_total; i++)
     if (dcc[i].type && !strcasecmp(dcc[i].nick, handle))
@@ -86,7 +90,7 @@ static struct userrec *check_dcclist_hand(const char *handle)
   return NULL;
 }
 
-struct userrec *host_conflicts(char *host)
+struct userrec *host_conflicts(const char *host)
 {
   struct userrec *u = NULL;
   struct list_type *q = NULL;

+ 2 - 2
src/userrec.h

@@ -13,7 +13,7 @@ void cache_users();
 void clear_userlist(struct userrec *);
 int u_pass_match(struct userrec *, const char *);
 int delhost_by_handle(char *, char *);
-int count_users(struct userrec *);
+int count_users(const struct userrec *) __attribute__((pure));
 int deluser(char *);
 int change_handle(struct userrec *, char *);
 void correct_handle(char *);
@@ -22,7 +22,7 @@ int real_write_userfile(int);
 int write_userfile(int);
 void touch_laston(struct userrec *, char *, time_t);
 void user_del_chan(char *);
-struct userrec *host_conflicts(char *);
+struct userrec *host_conflicts(const char *);
 struct userrec *get_user_by_handle(struct userrec *, const char *);
 struct userrec *get_user_by_host(char *);
 

+ 2 - 1
src/users.cc

@@ -62,7 +62,8 @@ interval_t ignore_time = 10;		/* how many minutes will ignores last? */
 bool	dont_restructure = 0;		/* set when we botlink() to a hub with +U, only stops bot from restructuring */
 
 /* is this nick!user@host being ignored? */
-bool match_ignore(char *uhost)
+bool
+match_ignore(const char *uhost)
 {
   for (struct igrec *ir = global_ign; ir; ir = ir->next)
     if (wild_match(ir->igmask, uhost))

+ 2 - 2
src/users.h

@@ -182,7 +182,7 @@ extern struct igrec *global_ign;
 bool def_unpack(struct userrec *u, struct user_entry *e);
 bool def_kill(struct user_entry *e);
 bool def_write_userfile(FILE *f, struct userrec *u, struct user_entry *e);
-void *def_get(struct userrec *u, struct user_entry *e);
+void *def_get(struct userrec *u, struct user_entry *e) __attribute__((pure));
 bool def_set(struct userrec *u, struct user_entry *e, void *buf);
 bool def_gotshare(struct userrec *u, struct user_entry *e, char *data, int idx);
 void def_display(int idx, struct user_entry *e, struct userrec *u);
@@ -192,7 +192,7 @@ void backup_userfile();
 void addignore(char *, char *, const char *, time_t);
 char *delignore(char *);
 void tell_ignores(int, char *);
-bool match_ignore(char *);
+bool match_ignore(const char *) __attribute__((pure));
 void check_expired_ignores();
 void autolink_cycle();
 void tell_file_stats(int, char *);