HOOK_ENGINE=old
endif
-# if USE_VALGRIND == 1
-ifeq (${USE_VALGRIND},1)
- CFLAGS+=-DUSE_VALGRIND
- SSTRING_ENGINE=valgrind
-
-## if SSTRING_NEW == 1
-ifeq (${SSTRING_NEW},1)
- IMPOSSIBLE="USE_VALGRIND and SSTRING_NEW"
-endif # SSTRING_NEW == 1
-
-## if SSTRING_MMAP == 1
-ifeq (${SSTRING_MMAP},1)
- IMPOSSIBLE="USE_VALGRIND and SSTRING_MMAP"
-endif ## SSTRING_MMAP == 1
-else # USE_VALGRIND == 1
-
-## if SSTRING_NEW == 1
-ifeq (${SSTRING_NEW},1)
- SSTRING_ENGINE=new
-else ## SSTRING_NEW == 1
- SSTRING_ENGINE=old
-
-### if SSTRING_MMAP == 1
-ifeq (${SSTRING_MMAP},1)
- IMPOSSIBLE="SSTRING_MMAP without SSTRING_NEW"
-endif ### SSTRING_MMAP == 1
-endif ## SSTRING_NEW == 1
-endif # USE_VALGRIND == 1
-
-ifdef IMPOSSIBLE
-$(error impossible combination of settings: ${IMPOSSIBLE})
-endif
-
ifndef BUILDID
BUILDID = $(shell (hg id || echo "unknown") | sed -e "s/[()]//g;s/+ /+/g;s/ /-/g" )
endif
init_logfile();
- initsstring();
-
if (argc>1) {
if (strcmp(argv[1], "--help")==0) {
printf("Syntax: %s [config]\n", argv[0]);
}
freeconfig();
- finisstring();
fini_logfile();
finischedule();
default: all
-all: sstring-${SSTRING_ENGINE}.o array.o splitline.o base64.o flags.o irc_string.o strlfunc.o sha1.o irc_ipv6.o rijndael.o sha2.o hmac.o prng.o md5.o stringbuf.o sstring-lib.o cbc.o
+all: sstring.o array.o splitline.o base64.o flags.o irc_string.o strlfunc.o sha1.o irc_ipv6.o rijndael.o sha2.o hmac.o prng.o md5.o stringbuf.o cbc.o
+++ /dev/null
-#include <string.h>
-#include "sstring.h"
-
-int sstringcompare(sstring *ss1, sstring *ss2) {
- if (ss1->length != ss2->length)
- return -1;
-
- return strncmp(ss1->content, ss2->content, ss1->length);
-}
-
+++ /dev/null
-/* sstring.h - Declaration of "static strings" functions */
-
-#define COMPILING_SSTRING
-#define SSTRING_NEW
-#include "sstring.h"
-
-#include "../core/hooks.h"
-#include "../core/nsmalloc.h"
-#include "../core/error.h"
-#include "../lib/irc_string.h"
-
-#include <stdio.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#define _GNU_SOURCE
-#include <string.h>
-
-/* List of free stuff */
-static sstring *freelist[SSTRING_MAXLEN+1];
-static sstring *sshash[SSTRING_HASHSIZE];
-
-/* Global variables to track allocated memory */
-static char *ssmem;
-static int ssmemfree;
-
-/* Statistics counters */
-static int getcalls;
-static int freecalls;
-static int allocs;
-
-/* Internal functions */
-static void sstringstats(int hooknum, void *arg);
-static void salloc(void);
-
-#ifndef SSTRING_MMAP
-
-#define sunprotect(x)
-#define sunprotectb(x)
-#define sprotect(x)
-
-#else
-
-#define __USE_MISC
-
-#include <sys/mman.h>
-static void *mblock;
-struct mblock_list {
- void *block;
- struct mblock_list *next;
-};
-
-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);
-
-#ifndef MAP_ANON
-#define MAP_ANON MAP_ANONYMOUS
-#endif
-
-#endif /* SSTRING_MMAP */
-
-void initsstring() {
- int i;
- for(i=0;i<=SSTRING_MAXLEN;i++)
- freelist[i]=NULL;
-
- for(i=0;i<SSTRING_HASHSIZE;i++)
- sshash[i]=NULL;
-
- ssmemfree=0;
- ssmem=NULL;
-
- /* Initialise statistics counters */
- getcalls=0;
- freecalls=0;
- allocs=0;
-
- registerhook(HOOK_CORE_STATSREQUEST,&sstringstats);
-}
-
-void finisstring() {
- deregisterhook(HOOK_CORE_STATSREQUEST,&sstringstats);
-
- #ifndef SSTRING_MMAP
- nsfreeall(POOL_SSTRING);
- #endif /* SSTRING_MMAP */
-}
-
-#ifndef SSTRING_MMAP
-static void salloc(void) {
- ssmem=(char *)nsmalloc(POOL_SSTRING, SSTRING_ALLOC);
- ssmemfree=SSTRING_ALLOC;
-}
-#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, sstring_content(ss)))
- return ss;
-
- return NULL;
-}
-
-void sstring_enhash(sstring *ss) {
- 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(sstring_content(ss))%SSTRING_HASHSIZE;
- sstring *ssh, *ssp;
-
- 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=%lu, length=%d) in hash: %s",ss->refcount,ss->length,sstring_content(ss));
-}
-
-sstring *getsstring(const char *inputstr, int maxlen) {
- int i;
- sstring *retval=NULL;
- int length, foreignblock;
- char strbuf[SSTRING_MAXLEN];
-
- /* getsstring() on a NULL pointer returns a NULL sstring.. */
- if (inputstr==NULL) {
- return NULL;
- }
-
- if (inputstr[0]=='\0') {
- return NULL;
- }
-
- if (maxlen>SSTRING_MAX) {
- Error("sstring", ERR_ERROR, "Attempt to allocate overlength string (maxlen=%d)",maxlen);
- return NULL;
- }
-
- /* Only count calls that actually did something */
- getcalls++;
-
- /* Make a copy of the desired string to make things easier later */
- for (length=0;length<maxlen;length++) {
- strbuf[length]=inputstr[length];
- if (!strbuf[length])
- break;
- }
- strbuf[length]='\0';
-
- length++;
-
- /* If it's hashed this is easy */
- if ((retval=findsstring(strbuf))) {
- sunprotect(retval) {
- retval->refcount++;
- } sprotect(retval);
-
- return retval;
- }
-
- foreignblock=0;
- /* Check to see if an approximately correct
- * sized string is available */
- for(i=0;i<SSTRING_SLACK;i++) {
- if (length+i>SSTRING_MAXLEN)
- break;
-
- if (freelist[length+i]!=NULL) {
- retval=freelist[length+i];
- freelist[length+i]=retval->next;
- sunprotect(retval);
- foreignblock=1;
-
- retval->alloc=(length+i);
- break;
- }
- }
-
- /* None found, allocate a new one */
- if (retval==NULL) {
- /* Check for free memory */
- if (ssmemfree < (sizeof(sstring)+length)) {
- /* Not enough for us - turn the remaining memory into a free string for later */
- if (ssmemfree>sizeof(sstring)) {
- retval=(sstring *)ssmem;
- sunprotectb(mblock);
-#ifdef SSTRING_MMAP
- retval->block=mblock;
-#endif
- retval->alloc=(ssmemfree-sizeof(sstring));
- retval->refcount=0;
- freesstring(retval);
- }
-
- allocs++;
- salloc();
- } else {
- sunprotectb(mblock);
- }
-
- retval=(sstring *)ssmem;
- ssmem+=(sizeof(sstring)+length);
- ssmemfree-=(sizeof(sstring)+length);
-
- retval->alloc=length;
-
- /* If there's a fragment left over, lump it into this allocation */
- if (ssmemfree < (sizeof(sstring)+1)) {
- retval->alloc += ssmemfree;
- ssmemfree=0;
- ssmem=NULL;
- }
- }
-
- /*
- * At this point, retval points to a valid structure which is at
- * least the right size and has the "alloc" value set correctly
- */
-
- retval->length=(length-1);
- strcpy(sstring_content(retval),strbuf);
- retval->refcount=1;
-
-#ifdef SSTRING_MMAP
- if(!foreignblock)
- retval->block = mblock;
-#endif
-
- sstring_enhash(retval);
-
-#ifdef SSTRING_COMPAT
- retval->content = retval->__content;
-#endif
-
- sprotect(retval);
-
- return retval;
-}
-
-void freesstring(sstring *inval) {
- int alloc;
-
- /* Allow people to call this with a NULL value */
- if (inval==NULL)
- return;
-
- /* Only count calls that actually did something */
- freecalls++;
-
- if (inval->refcount)
- sunprotect(inval);
-
- if (inval->refcount > 1) {
- inval->refcount--;
- sprotect(inval);
- return;
- }
-
- /* If refcount==0 it wasn't hashed, or protected */
- 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) {
- char buf[512];
- int i,j;
- sstring *ssp;
- long statslev=(long)arg;
-
- if (statslev>10) {
- for(i=0,j=0;i<=SSTRING_MAXLEN;i++) {
- for(ssp=freelist[i];ssp;ssp=ssp->next)
- j++;
- }
-
- snprintf(buf,512,"SString : %7d get calls, %7d free calls, %7d allocs, %7d strings free",getcalls,freecalls,allocs,j);
- triggerhook(HOOK_CORE_STATSREPLY,(void *)buf);
- }
-}
-
-#ifdef SSTRING_MMAP
-void finisstring() {
- struct mblock_list *c, *n;
- for (c=mblock_head;c;c=n) {
- n=c->next;
- munmap(c->block, SSTRING_ALLOC);
- }
-}
-
-static void salloc(void) {
- struct mblock_list *n;
- mblock=mmap((void *)0, SSTRING_ALLOC, PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANON, -1, 0);
-
- n=(struct mblock_list *)mblock;
- n->block = mblock;
- n->next = mblock_head;
- mblock_head = n;
-
- ssmem=(char *)mblock + sizeof(struct mblock_list);
- ssmemfree=SSTRING_ALLOC-sizeof(struct mblock_list);
-}
-#endif /* SSTRING_MMAP */
+++ /dev/null
-/* sstring.h - Declaration of "static strings" functions */
-
-#define COMPILING_SSTRING
-#include "sstring.h"
-
-#include "../core/hooks.h"
-#include "../core/nsmalloc.h"
-#include "../core/error.h"
-
-#include <stdio.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#define _GNU_SOURCE
-#include <string.h>
-
-/* List of free stuff */
-sstring *freelist[SSTRING_MAXLEN+1];
-
-/* Global variables to track allocated memory */
-sstring *structmem;
-char *stringmem;
-int structfree;
-int stringfree;
-
-/* Statistics counters */
-int getcalls;
-int freecalls;
-int allocstruct;
-int allocstring;
-
-/* Internal function */
-void sstringstats(int hooknum, void *arg);
-
-void initsstring() {
- int i;
- for(i=0;i<=SSTRING_MAXLEN;i++)
- freelist[i]=NULL;
-
- structfree=0;
- stringfree=0;
- structmem=NULL;
- stringmem=NULL;
-
- /* Initialise statistics counters */
- getcalls=0;
- freecalls=0;
- allocstruct=0;
- allocstring=0;
-
- registerhook(HOOK_CORE_STATSREQUEST,&sstringstats);
-}
-
-void finisstring() {
- nsfreeall(POOL_SSTRING);
-}
-
-sstring *getsstring(const char *inputstr, int maxlen) {
- int i;
- sstring *retval=NULL;
- int length;
-
-
- /* getsstring() on a NULL pointer returns a NULL sstring.. */
- if (inputstr==NULL) {
- return NULL;
- }
-
- if (inputstr[0]=='\0') {
- return NULL;
- }
-
- /* Only count calls that actually did something */
- getcalls++;
-
- length=strlen(inputstr)+1;
- if (length>maxlen) {
- length=maxlen+1;
- }
- assert(length<=SSTRING_MAXLEN);
-
- /* Check to see if an approximately correct
- * sized string is available */
- for(i=0;i<SSTRING_SLACK;i++) {
- if (length+i>SSTRING_MAXLEN)
- break;
-
- if (freelist[length+i]!=NULL) {
- retval=freelist[length+i];
- freelist[length+i]=retval->u.next;
- retval->u.l.alloc=(length+i);
- break;
- }
- }
-
- /* None found, allocate a new one */
- if (retval==NULL) {
-getstruct:
- if (structfree < sizeof(sstring)) {
- /* We always allocate an exact multiple of these.
- * Therefore, if there is enough for a partial structure we broke something */
- assert(structfree==0);
-
- /* Allocate more RAM */
- allocstruct++;
- structmem=(sstring *)nsmalloc(POOL_SSTRING,SSTRING_STRUCTALLOC);
- assert(structmem!=NULL);
- structfree=SSTRING_STRUCTALLOC;
- }
-
- retval=structmem;
- structmem++;
- structfree-=sizeof(sstring);
-
- if (stringfree < length) {
- /* Not enough left for what we want.
- * Allocate the remainder of our chunk (if any)
- * to something and immediately free it.
- * Decrement the freecalls counter to fix the stats */
- if (stringfree > 0) {
- retval->content=stringmem;
- retval->u.l.alloc=stringfree;
- stringfree=0;
- freecalls--;
- freesstring(retval);
-
- /* GOTO GOTO GOTO: We need to allocate
- * another new struct here. Goto is the cleanest
- * way to do this */
- goto getstruct;
- } else {
- /* Grab some more string space */
- allocstring++;
- stringmem=(char *)nsmalloc(POOL_SSTRING,SSTRING_DATAALLOC);
- assert(stringmem!=NULL);
- stringfree=SSTRING_DATAALLOC;
- }
- }
-
- retval->content=stringmem;
- retval->u.l.alloc=length;
- stringfree-=length;
- stringmem+=length;
- }
-
- /*
- * At this point, retval points to a valid structure which is at
- * least the right size and has the "alloc" value set correctly
- */
-
- retval->u.l.length=(length-1);
- strncpy(retval->content,inputstr,(length-1));
- retval->content[length-1]='\0';
-
- return retval;
-}
-
-void freesstring(sstring *inval) {
- int alloc;
-
- /* Allow people to call this with a NULL value */
- if (inval==NULL)
- return;
-
- /* Only count calls that actually did something */
- freecalls++;
-
- alloc=inval->u.l.alloc;
- assert(alloc<=SSTRING_MAXLEN);
- inval->u.next=freelist[alloc];
- freelist[alloc]=inval;
-}
-
-void sstringstats(int hooknum, void *arg) {
- char buf[512];
- int i,j;
- sstring *ssp;
- long statslev=(long)arg;
-
- if (statslev>10) {
- for(i=0,j=0;i<=SSTRING_MAXLEN;i++) {
- for(ssp=freelist[i];ssp;ssp=ssp->u.next)
- j++;
- }
-
- snprintf(buf,512,"SString : %7d get calls, %7d free calls, %7d struct allocs, %7d string allocs, %7d strings free",getcalls,freecalls,allocstruct,allocstring,j);
- triggerhook(HOOK_CORE_STATSREPLY,(void *)buf);
- }
-}
+++ /dev/null
-#define COMPILING_SSTRING
-#include "sstring.h"
-
-#include "../core/hooks.h"
-#include "../core/nsmalloc.h"
-#include "../core/error.h"
-
-#include <stdio.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#define __USE_GNU
-#include <string.h>
-
-typedef struct sstringlist {
- struct sstringlist *prev;
- struct sstringlist *next;
- sstring s[];
-} sstringlist;
-
-static sstringlist *head;
-
-void initsstring() {
-}
-
-void finisstring() {
- sstringlist *s, *sn;
-
- /* here we deliberately don't free the pointers so valgrind can tell us where they were allocated, in theory */
-
- for(s=head;s;s=sn) {
- sn = s->next;
- s->next = NULL;
- s->prev = NULL;
-
- Error("sstring", ERR_WARNING, "sstring of length %d still allocated: %s", s->s->u.l.length, s->s->content);
- }
-
- head = NULL;
-}
-
-sstring *getsstring(const char *inputstr, int maxlen) {
- sstringlist *s;
- size_t len;
- char *p;
-
- if(!inputstr)
- return NULL;
-
- for(p=(char *)inputstr;*p&&maxlen;maxlen--,p++)
- ; /* empty */
-
- len = p - inputstr;
- s=(sstringlist *)malloc(sizeof(sstringlist) + sizeof(sstring));
-
- s->s->u.l.length = len;
- s->s->content=(char *)malloc(len + 1);
-
- memcpy(s->s->content, inputstr, len);
- s->s->content[len] = '\0';
-
- s->next = head;
- s->prev = NULL;
- if(head)
- head->prev = s;
- head = s;
-
- return s->s;
-}
-
-void freesstring(sstring *inval) {
- sstringlist *s;
- if(!inval)
- return;
-
- s = (sstringlist *)inval - 1;
-
- if(s->prev) {
- s->prev->next = s->next;
- if(s->next)
- s->next->prev = s->prev;
- } else {
- head = s->next;
- if(head)
- head->prev = NULL;
- }
-
- free(inval->content);
- free(s);
-}
--- /dev/null
+/* sstring.h - Declaration of "static strings" functions */
+
+#include "sstring.h"
+#include "../core/nsmalloc.h"
+
+#include <assert.h>
+#include <string.h>
+
+sstring *getsstring(const char *inputstr, int maxlen) {
+ sstring *retval = NULL;
+ int length;
+
+ /* getsstring() on a NULL pointer returns a NULL sstring.. */
+ if (inputstr == NULL)
+ return NULL;
+
+ if (inputstr[0] == '\0')
+ return NULL;
+
+ length = strlen(inputstr) + 1;
+
+ if (length > maxlen)
+ length = maxlen + 1;
+
+ assert(length <= SSTRING_MAX + 1);
+
+ retval = nsmalloc(POOL_SSTRING, sizeof(sstring) + length);
+
+ retval->length = length - 1;
+ strncpy(retval->content, inputstr, length - 1);
+ retval->content[length - 1] = '\0';
+
+ return retval;
+}
+
+void freesstring(sstring *inval) {
+ nsfree(POOL_SSTRING, inval);
+}
+
+int sstringcompare(sstring *ss1, sstring *ss2) {
+ if (ss1->length != ss2->length)
+ return -1;
+
+ return strncmp(ss1->content, ss2->content, ss1->length);
+}
/* sstring.h - Declaration of "static strings" functions */
-#ifndef __SSTRING_H
+#ifndef __SSTRING_H
#define __SSTRING_H
-#define SSTRING_COMPAT
-
-#ifdef COMPILING_SSTRING
-
-#ifdef SSTRING_NEW
-
-/* this is here for compatibility reasons with old sstring */
-/* this should be used when old sstring is removed entirely */
-#ifdef SSTRING_COMPAT
-
-typedef struct sstring {
- char *content;
- short length;
- short alloc;
- struct sstring *next;
-#ifdef USE_VALGRIND
- void *block;
-#endif
- unsigned long refcount;
- char __content[];
-} sstring;
-
-#define sstring_content(x) (x)->__content
-
-#else /* SSTRING_COMPAT */
-
typedef struct sstring {
short length;
- short alloc;
- struct sstring *next;
-#ifdef USE_VALGRIND
- void *block;
-#endif
- unsigned long refcount;
char content[];
} sstring;
-#define sstring_content(x) (x)->content
-
-#endif /* SSTRING_COMPAT */
-
-#else /* SSTRING_NEW */
-
-/* this is the old format */
-
-/* Internal version of structure */
-typedef struct {
- char *content;
- union {
- struct {
- short length;
- short alloc;
- } l;
- void *next;
- } u;
-} sstring;
-
-#endif /* SSTRING_NEW */
-
-/* Internal defines */
-
-/* SSTRING_MAXLEN is the internal version of SSTRING_MAX which includes
- * space for the trailing NUL */
-#define SSTRING_MAXLEN (SSTRING_MAX + 1)
-#define SSTRING_SLACK 8
-
-/* new sstring defines */
-#define SSTRING_ALLOC 16384
-
-#define SSTRING_HASHSIZE 85243
-
-/* old sstring defines */
-#define SSTRING_STRUCTALLOC 4096
-#define SSTRING_DATAALLOC 4096
-
-#else
-
-typedef struct sstring {
- char *content;
- short length;
-} sstring;
-
-#endif /* COMPILING_SSTRING */
-
/* Externally visibly max string length */
-#define SSTRING_MAX 512
+#define SSTRING_MAX 512
sstring *getsstring(const char *, int);
void freesstring(sstring *);
int sstringcompare(sstring *ss1, sstring *ss2);
-void initsstring();
-void finisstring();
#endif /* __SSTRING_H */