]> jfr.im git - irc/quakenet/newserv.git/blobdiff - lib/sstring-new.c
add is_normalized_ipmask
[irc/quakenet/newserv.git] / lib / sstring-new.c
index 86d4d0ee798a7b3d0fac95adbc4e8444625247b4..afaa9e7c3c1d78dfc016dec26923e2d21cb4bbf3 100644 (file)
@@ -1,6 +1,7 @@
 /* sstring.h - Declaration of "static strings" functions */
 
 #define COMPILING_SSTRING
+#define SSTRING_NEW
 #include "sstring.h"
 
 #include "../core/hooks.h"
@@ -32,7 +33,7 @@ static int allocs;
 static void sstringstats(int hooknum, void *arg);
 static void salloc(void);
 
-#ifndef USE_VALGRIND
+#ifndef SSTRING_MMAP
 
 #define sunprotect(x)
 #define sunprotectb(x)
@@ -40,6 +41,8 @@ static void salloc(void);
 
 #else
 
+#define __USE_MISC
+
 #include <sys/mman.h>
 static void *mblock;
 struct mblock_list {
@@ -50,10 +53,14 @@ struct mblock_list {
 static void *mblock_head;
 
 #define sunprotectb(x) mprotect(x, SSTRING_ALLOC, PROT_READ|PROT_WRITE);
-#define sunprotect(x) sunprotectb(x->block);
-#define sprotect(x) mprotect(x->block, SSTRING_ALLOC, PROT_READ);
+#define sunprotect(x) sunprotectb((x)->block);
+#define sprotect(x) mprotect((x)->block, SSTRING_ALLOC, PROT_READ);
+
+#ifndef MAP_ANON
+#define MAP_ANON MAP_ANONYMOUS
+#endif
 
-#endif /* USE_VALGRIND */
+#endif /* SSTRING_MMAP */
 
 void initsstring() {
   int i;
@@ -74,7 +81,7 @@ void initsstring() {
   registerhook(HOOK_CORE_STATSREQUEST,&sstringstats);
 }
 
-#ifndef USE_VALGRIND
+#ifndef SSTRING_MMAP
 void finisstring() {
   nsfreeall(POOL_SSTRING);
 }
@@ -83,38 +90,52 @@ static void salloc(void) {
   ssmem=(char *)nsmalloc(POOL_SSTRING, SSTRING_ALLOC);
   ssmemfree=SSTRING_ALLOC;
 }
-#endif /* USE_VALGRIND */
+#endif /* SSTRING_MMAP */
 
 sstring *findsstring(const char *str) {
   unsigned int hash=crc32(str)%SSTRING_HASHSIZE;
   sstring *ss;
   
   for (ss=sshash[hash];ss;ss=ss->next)
-    if (!strcmp(str, ss->content))
+    if (!strcmp(str, sstring_content(ss)))
       return ss;
   
   return NULL;
 }
 
 void sstring_enhash(sstring *ss) {
-  unsigned int hash=crc32(ss->content)%SSTRING_HASHSIZE;
+  unsigned int hash=crc32(sstring_content(ss))%SSTRING_HASHSIZE;
   
   ss->next=sshash[hash];
   sshash[hash]=ss;
 }
 
 void sstring_dehash(sstring *ss) {
-  unsigned int hash=crc32(ss->content)%SSTRING_HASHSIZE;
-  sstring **ssh;
+  unsigned int hash=crc32(sstring_content(ss))%SSTRING_HASHSIZE;
+  sstring *ssh, *ssp;
   
-  for (ssh=&(sshash[hash]); *ssh; ssh=&((*ssh)->next)) {
-    if (*ssh==ss) {
-      *ssh=ss->next;
+  for (ssh=sshash[hash],ssp=NULL; ssh; ssp=ssh,ssh=ssh->next) {
+    if (ssh==ss) {
+      if (!ssp) {
+        sshash[hash]=ss->next;
+      } else {
+#ifndef SSTRING_MMAP
+        ssp->next=ss->next;
+#else
+        if (ssp->block!=ss->block) {
+          sunprotect(ssp) {
+            ssp->next=ss->next;
+          } sprotect(ssp);
+        } else {
+          ssp->next=ss->next;
+        }
+#endif
+      }
       return;
     }
   }
   
-  Error("sstring",ERR_WARNING,"sstring_dehash(): Unable to find string (ref=%d, length=%d) in hash: %s",ss->refcount,ss->length,ss->content);
+  Error("sstring",ERR_WARNING,"sstring_dehash(): Unable to find string (ref=%lu, length=%d) in hash: %s",ss->refcount,ss->length,sstring_content(ss));
 }
 
 sstring *getsstring(const char *inputstr, int maxlen) {
@@ -184,7 +205,10 @@ sstring *getsstring(const char *inputstr, int maxlen) {
       /* Not enough for us - turn the remaining memory into a free string for later */
       if (ssmemfree>sizeof(sstring)) {
         retval=(sstring *)ssmem;
-        sunprotect(retval);
+        sunprotectb(mblock);
+#ifdef SSTRING_MMAP
+        retval->block=mblock;
+#endif
         retval->alloc=(ssmemfree-sizeof(sstring));
         retval->refcount=0;
         freesstring(retval);
@@ -216,15 +240,20 @@ sstring *getsstring(const char *inputstr, int maxlen) {
    */
   
   retval->length=(length-1);
-  strcpy(retval->content,strbuf);
+  strcpy(sstring_content(retval),strbuf);
   retval->refcount=1;
-  
-#ifdef USE_VALGRIND 
+
+#ifdef SSTRING_MMAP 
   if(!foreignblock)
     retval->block = mblock;
 #endif
 
   sstring_enhash(retval);
+
+#ifdef SSTRING_COMPAT
+  retval->content = retval->__content;
+#endif
+
   sprotect(retval);
 
   return retval;    
@@ -240,23 +269,24 @@ void freesstring(sstring *inval) {
   /* Only count calls that actually did something */
   freecalls++;
   
+  if (inval->refcount)
+    sunprotect(inval);
+
   if (inval->refcount > 1) {
-    sunprotect(inval) {
-      inval->refcount--;
-    } sprotect(inval);
+    inval->refcount--;
+    sprotect(inval);
     return;
   }
 
   /* If refcount==0 it wasn't hashed, or protected */
-  if (inval->refcount) {
-    sunprotect(inval);
+  if (inval->refcount)
     sstring_dehash(inval);
-  }
 
   alloc=inval->alloc;
   assert(alloc<=SSTRING_MAXLEN);
   inval->next=freelist[alloc];
   freelist[alloc]=inval;
+  sprotect(inval);
 }
 
 void sstringstats(int hooknum, void *arg) {
@@ -276,14 +306,7 @@ void sstringstats(int hooknum, void *arg) {
   }
 }
 
-int sstringcompare(sstring *ss1, sstring *ss2) {
-  if (ss1->length != ss2->length)
-    return -1;
-  
-  return strncmp(ss1->content, ss2->content, ss1->length);
-}
-
-#ifdef USE_VALGRIND
+#ifdef SSTRING_MMAP
 void finisstring() {
   struct mblock_list *c, *n;
   for (c=mblock_head;c;c=n) {
@@ -304,4 +327,4 @@ static void salloc(void) {
   ssmem=(char *)mblock + sizeof(struct mblock_list);
   ssmemfree=SSTRING_ALLOC-sizeof(struct mblock_list);
 }
-#endif /* USE_VALGRIND */
+#endif /* SSTRING_MMAP */