]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Merge.
authorChris Porter <redacted>
Wed, 20 Aug 2008 15:49:11 +0000 (16:49 +0100)
committerChris Porter <redacted>
Wed, 20 Aug 2008 15:49:11 +0000 (16:49 +0100)
26 files changed:
authext/authext.c
authext/authext.h
bans/bans.c
chanindex/chanindex.c
chanserv/database/chanservdb.c
control/control.c
core/hooks.h
core/main.c
core/modules.c
graphing/Makefile.in [deleted file]
graphing/dump.c [deleted file]
graphing/fsample.c [deleted file]
graphing/fsample.h [deleted file]
graphing/graphing.c [deleted file]
graphing/graphing.h [deleted file]
graphing/nterfacer_graphing.c [deleted file]
lib/irc_string.c
lib/sstring-new.c
lib/sstring-new.h
lib/sstring.c
localuser/localuserstats.c
noperserv/noperserv_hooks.c
serverlist/serverlist.c
usercount/usercount.c
xsb/xsb.c
xsb/xsb.h

index 2451a6227bfddc4675ae88a890ea5bf0ee29764c..e1939e38605ffc051903a09fa5b4f49cbb029600 100644 (file)
@@ -6,10 +6,13 @@
 #include "../nick/nick.h"
 #include "../core/hooks.h"
 #include "../lib/strlfunc.h"
+#include "../lib/version.h"
 
 #include <string.h>
 #include <stdio.h>
 
+MODULE_VERSION("")
+
 #define ALLOCUNIT 100
 
 #define authnamehash(x)   ((x)%AUTHNAMEHASHSIZE)
@@ -21,7 +24,10 @@ authname *authnametable[AUTHNAMEHASHSIZE];
 /* internal access only */
 static authname *authnametablebyname[AUTHNAMEHASHSIZE];
 
-sstring *authnameextnames[MAXAUTHNAMEEXTS];
+static struct {
+  sstring *name;
+  int persistant;
+} authnameexts[MAXAUTHNAMEEXTS];
 
 static void authextstats(int hooknum, void *arg);
 
@@ -60,7 +66,7 @@ void freeauthname (authname *anp) {
   freeauthnames=anp;
 }
 
-int registerauthnameext(const char *name) {
+int registerauthnameext(const char *name, int persistant) {
   int i;
 
   if (findauthnameext(name)!=-1) {
@@ -69,8 +75,9 @@ int registerauthnameext(const char *name) {
   }
 
   for (i=0;i<MAXAUTHNAMEEXTS;i++) {
-    if (authnameextnames[i]==NULL) {
-      authnameextnames[i]=getsstring(name,100);
+    if (authnameexts[i].name==NULL) {
+      authnameexts[i].name=getsstring(name,100);
+      authnameexts[i].persistant=persistant;
       return i;
     }
   }
@@ -83,7 +90,7 @@ int findauthnameext(const char *name) {
   int i;
 
   for (i=0;i<MAXAUTHNAMEEXTS;i++) {
-    if (authnameextnames[i]!=NULL && !ircd_strcmp(name,authnameextnames[i]->content)) {
+    if (authnameexts[i].name!=NULL && !ircd_strcmp(name,authnameexts[i].name->content)) {
       return i;
     }
   }
@@ -95,8 +102,8 @@ void releaseauthnameext(int index) {
   int i;
   authname *anp;
 
-  freesstring(authnameextnames[index]);
-  authnameextnames[index]=NULL;
+  freesstring(authnameexts[index].name);
+  authnameexts[index].name=NULL;
 
   for (i=0;i<AUTHNAMEHASHSIZE;i++) {
     for (anp=authnametable[i];anp;anp=anp->next) {
@@ -169,9 +176,10 @@ void releaseauthname(authname *anp) {
     anp->nicks = NULL;
 
     for(i=0;i<MAXAUTHNAMEEXTS;i++)
-      if(anp->exts[i]!=NULL)
+      if(authnameexts[i].persistant && anp->exts[i]!=NULL)
         return;
 
+    triggerhook(HOOK_AUTH_LOSTAUTHNAME, (void *)anp);
     found = 0;
     for(manp=&(authnametable[authnamehash(anp->userid)]);*manp;manp=(authname **)&((*manp)->next)) {
       if ((*manp)==anp) {
index 5a0ed6a784eb682d0fe666c0783151973720c0fc..4a78c2f0f4d5bc10aee4f80c561208e215cbaadb 100644 (file)
@@ -36,7 +36,7 @@ authname *newauthname(void);
 void freeauthname (authname *hp);
 
 /* EXT management */
-int registerauthnameext(const char *name);
+int registerauthnameext(const char *name, int persistant);
 int findauthnameext(const char *name);
 void releaseauthnameext(int index);
 
index b7fc500e300c90f998e3ab41d198cc7517a6cb24..137308638a701ed4aeeb649948854cf22c4ba5ac 100644 (file)
@@ -10,6 +10,9 @@
 #include "../irc/irc_config.h"
 #include "../core/nsmalloc.h"
 #include "../lib/flags.h"
+#include "../lib/version.h"
+
+MODULE_VERSION("")
 
 #define ALLOCUNIT 100
 
index a859250cb2b86eda681180725762db20427f6ce9..e610fd8e2e960ce8e6b0d7557f65d1314f0d0ed6 100644 (file)
@@ -5,10 +5,13 @@
 #include "../lib/irc_string.h"
 #include "../core/error.h"
 #include "../core/nsmalloc.h"
+#include "../lib/version.h"
 
 #include <stdio.h>
 #include <string.h>
 
+MODULE_VERSION("")
+
 #define ALLOCUNIT      1000
 
 #define channelhash(x)  (crc32i(x)%CHANNELHASHSIZE)
index df83df675e09018f8553c18b419e5eb87aa44167..cb28b286c1b4e2132aff974a142ca32c03f7d1e2 100644 (file)
@@ -230,7 +230,7 @@ static void setuptables() {
 
 void _init() {
   chanservext=registerchanext("chanserv");
-  chanservaext=registerauthnameext("chanserv");
+  chanservaext=registerauthnameext("chanserv",1);
 
   /* Set up the allocators and hashes */
   chanservallocinit();
index d97df3bbbf39cf589ae5836fef73cbdd188d2f35..efeddfef51a0a697010aedb7840369414f34a94c 100644 (file)
@@ -50,7 +50,7 @@ int controlrehash(void *sender, int cargc, char **cargv);
 int controlreload(void *sender, int cargc, char **cargv);
 int controlhelpcmd(void *sender, int cargc, char **cargv);
 void controlnoticeopers(flag_t permissionlevel, flag_t noticelevel, char *format, ...);
-void handlerehash(int hooknum, void *arg);
+void handlesignal(int hooknum, void *arg);
 
 void _init() {
   controlcmds=newcommandtree();
@@ -70,7 +70,8 @@ void _init() {
   registercontrolhelpcmd("reload",NO_DEVELOPER,1,&controlreload,"Usage: reload <module>\nReloads specified module.");
   registercontrolhelpcmd("help",NO_ANYONE,1,&controlhelpcmd,"Usage: help <command>\nShows help for specified command.");
  
-  registerhook(HOOK_CORE_REHASH, &handlerehash); 
+  registerhook(HOOK_CORE_REHASH, &handlesignal);
+  registerhook(HOOK_CORE_SIGINT, &handlesignal);
   scheduleoneshot(time(NULL)+1,&controlconnect,NULL);
 }
 
@@ -95,7 +96,8 @@ void _fini() {
   
   destroycommandtree(controlcmds);
 
-  deregisterhook(HOOK_CORE_REHASH, &handlerehash); 
+  deregisterhook(HOOK_CORE_REHASH, &handlesignal);
+  deregisterhook(HOOK_CORE_SIGINT, &handlesignal);
 }
 
 void registercontrolhelpcmd(const char *name, int level, int maxparams, CommandHandler handler, char *help) {
@@ -483,6 +485,7 @@ void handlemessages(nick *target, int messagetype, void **args) {
       /* someone killed me?  Bastards */
       scheduleoneshot(time(NULL)+1,&controlconnect,NULL);
       mynick=NULL;
+      triggerhook(HOOK_CONTROL_REGISTERED, NULL);
       break;
       
     default:
@@ -628,9 +631,20 @@ void controlnswall(int noticelevel, char *format, ...) {
   controlwall(NO_OPER, noticelevel, "%s", broadcast);
 }
 
-void handlerehash(int hooknum, void *arg) {
-  long hupped = (long)arg;
-  if(hupped)
-    controlwall(NO_OPER, NL_OPERATIONS, "SIGHUP received, rehashing...");
-}
+void handlesignal(int hooknum, void *arg) {
+  char *signal, *action;
+
+  if(hooknum == HOOK_CORE_SIGINT) {
+    signal = "INT";
+    action = "terminating";
+  } else {
+    long hupped = (long)arg;
+    if(!hupped)
+      return;
 
+    signal = "HUP";
+    action = "rehashing";
+  }
+
+  controlwall(NO_OPER, NL_OPERATIONS, "SIG%s received, %s...", signal, action);
+}
index 34171fc95a8f0c57b34b94de94e73ae58c05b81b..b740418df22e11f8a880109f371114aba6fe106c 100644 (file)
@@ -14,6 +14,7 @@
 #define HOOK_CORE_STOPERROR          4
 #define HOOK_CORE_ERROR                     5  /* Argument is a struct error_event * */
 #define HOOK_CORE_SIGUSR1            6 
+#define HOOK_CORE_SIGINT             7
 
 #define HOOK_IRC_CONNECTED         100  /* Located in server.c now to fix burst bug */
 #define HOOK_IRC_DISCON            101
@@ -70,6 +71,7 @@
 #define HOOK_SHADOW_SERVER         701 /* Argument is char* */
 
 #define HOOK_AUTH_FLAGSUPDATED     801 /* Argument is void*[2] (authname*, u_int64_t*) */
+#define HOOK_AUTH_LOSTAUTHNAME     802 /* Argument is authname* */
 
 typedef void (*HookCallback)(int, void *);
 
index 3a5896f65c6f8f568162c1c962d5cfaea882e7a2..18f2a30a0c7c8b7b1a63b952bae5e739d1389c71 100644 (file)
@@ -23,7 +23,7 @@ void handlecore(void);
 void handlesignals(void);
 
 int newserv_shutdown_pending;
-static int newserv_sigusr1_pending, newserv_sighup_pending;
+static int newserv_sigint_pending, newserv_sigusr1_pending, newserv_sighup_pending;
 static void (*oldsegv)(int);
 
 int main(int argc, char **argv) {
@@ -82,6 +82,13 @@ void handlesignals(void) {
     triggerhook(HOOK_CORE_REHASH, (void *)1);
     newserv_sighup_pending=0;
   }
+
+  if (newserv_sigint_pending) {
+    Error("core", ERR_INFO, "SIGINT received, terminating.");
+    triggerhook(HOOK_CORE_SIGINT, NULL);
+    newserv_sigint_pending=0;
+    newserv_shutdown_pending=1;
+  }
 }
 
 /*
@@ -95,7 +102,7 @@ void initseed() {
 }
 
 void siginthandler(int sig) {
-  newserv_shutdown_pending = 1;
+  newserv_sigint_pending = 1;
 }
 
 void sigusr1handler(int sig) {
index 8f1b73575a794166f4ea111a6804b6781dcc1f87..4b9de8b6ac3dba4144b875b1c33ad6c314d77730 100644 (file)
@@ -222,50 +222,51 @@ void initmodules() {
 int insmod(char *modulename) {
   int i;
   module *mods;
-  char buf[1024];
+  char buf[1024], modulebuf[1024];
   const char *(*verinfo)(const char **);
   struct module_dep *mdp;
 
-  delchars(modulename,"./\\;");
+  strlcpy(modulebuf, modulename, sizeof(modulebuf));
+  delchars(modulebuf,"./\\;");
   
-  if (isloaded(modulename)) {
-    Error("core",ERR_DEBUG,"Tried to load already loaded module: %s",modulename);
+  if (isloaded(modulebuf)) {
+    Error("core",ERR_DEBUG,"Tried to load already loaded module: %s",modulebuf);
     return 1;
   }
   
-  if (strlen(modulename)>100) {
-    Error("core",ERR_WARNING,"Module name too long: %s",modulename);  
+  if (strlen(modulebuf)>100) {
+    Error("core",ERR_WARNING,"Module name too long: %s",modulebuf);  
     return 1;
   }
 
-  if ((mdp=getmoduledep(modulename))) {
+  if ((mdp=getmoduledep(modulebuf))) {
     for (i=0;i<mdp->numparents;i++) {
       if (!isloaded(mdp->parents[i]->name->content)) {
         if (insmod(mdp->parents[i]->name->content)) {
           Error("core",ERR_WARNING,"Error loading dependant module %s (needed by %s)",
-                   mdp->parents[i]->name->content,modulename);
+                   mdp->parents[i]->name->content,modulebuf);
           return 1;
         }
       }
     }
   } else {
-    Error("core",ERR_WARNING,"Loading module %s without dependency information.",modulename);
+    Error("core",ERR_WARNING,"Loading module %s without dependency information.",modulebuf);
   }
 
   i=array_getfreeslot(&modules);
   mods=(module *)(modules.content);
 
-  sprintf(buf,"%s/%s%s",moddir->content,modulename,modsuffix->content);
+  sprintf(buf,"%s/%s%s",moddir->content,modulebuf,modsuffix->content);
   
   mods[i].handle=dlopen(buf,RTLD_NOW|RTLD_GLOBAL);
   
   if(mods[i].handle==NULL) {
-    Error("core",ERR_ERROR,"Loading module %s failed: %s",modulename,dlerror());
+    Error("core",ERR_ERROR,"Loading module %s failed: %s",modulebuf,dlerror());
     array_delslot(&modules,i);
     return -1;
   }
 
-  mods[i].name=getsstring(modulename,MODULENAMELEN);
+  mods[i].name=getsstring(modulebuf,MODULENAMELEN);
 
   verinfo=dlsym(mods[i].handle,"_version");
   if(verinfo) {
@@ -276,7 +277,7 @@ int insmod(char *modulename) {
   }
 
   mods[i].loadedsince = time(NULL);
-  Error("core",ERR_INFO,"Loaded module %s OK.",modulename);
+  Error("core",ERR_INFO,"Loaded module %s OK.",modulebuf);
   
   return 0;
 }
@@ -322,30 +323,32 @@ int rmmod(char *modulename) {
   int i,j;
   module *mods;
   struct module_dep *mdp;
+  char modulebuf[1024];
+
+  strlcpy(modulebuf, modulename, sizeof(modulebuf));
+  delchars(modulebuf,"./\\;");
   
-  delchars(modulename,"./\\;");
-  
-  i=getindex(modulename);
+  i=getindex(modulebuf);
   if (i<0)
     return 1;
 
-  if ((mdp=getmoduledep(modulename))) {
+  if ((mdp=getmoduledep(modulebuf))) {
     for (j=0;j<mdp->numchildren;j++) {
       if (isloaded(mdp->children[j]->name->content)) {
         if (rmmod(mdp->children[j]->name->content)) {
           Error("core",ERR_WARNING,"Unable to remove child module %s (depends on %s)",
-                 mdp->children[j]->name->content, modulename);
+                 mdp->children[j]->name->content, modulebuf);
           return 1;
         }
       }
     }
 
     /* We may have removed other modules - reaquire the index number in case it has changed. */
-    i=getindex(modulename);
+    i=getindex(modulebuf);
     if (i<0)
       return 1;
   } else {
-    Error("core",ERR_WARNING,"Removing module %s without dependency information",modulename);
+    Error("core",ERR_WARNING,"Removing module %s without dependency information",modulebuf);
   }
   
   mods=(module *)(modules.content);
@@ -363,7 +366,7 @@ int rmmod(char *modulename) {
   freesstring(mods[i].name);
   array_delslot(&modules,i);
 
-  Error("core",ERR_INFO,"Removed module %s.",modulename);
+  Error("core",ERR_INFO,"Removed module %s.",modulebuf);
   
   return 0;
 }    
diff --git a/graphing/Makefile.in b/graphing/Makefile.in
deleted file mode 100644 (file)
index 3add014..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-@include@ @includel@../build.mk@includel@
-
-.PHONY: all
-all: graphing.so nterfacer_graphing.so dump
-
-graphing.so: graphing.o fsample.o
-
-nterfacer_graphing.so: nterfacer_graphing.o
-
-dump: dump.o fsample.o
-       $(CC) $(CFLAGS) -o $@ @srcs@
diff --git a/graphing/dump.c b/graphing/dump.c
deleted file mode 100644 (file)
index 2527de9..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "graphing.h"
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-int dump(fsample_m *f, fsample_t start, fsample_t stop) {
-  int i, j;
-
-  for(i=start;i<stop;i++) {
-    printf("%2d ", i);
-    for(j=0;j<f->pos;j++) {
-      fsample_t t;
-      int moo = fsget_m(f, j, i, &t);
-
-      if(!moo) {
-        int moo2 = fsget_mr(f, j, i, &t);
-        printf("X%2d(%2d) ", t, moo2);
-      } else {
-        printf(" %2d(%2d) ", t, moo);
-      }
-    }
-    printf("\n");
-  }
-
-  return 0;
-}
-
-
-int main(int cargc, char **cargv) {
-  fsample_m *f;
-  int stop = time(NULL) / GRAPHING_RESOLUTION;
-  struct stat sb;
-
-  if(cargc < 2) {
-    puts("insufficient args");
-    return 1;
-  }
-
-  if(stat(cargv[1], &sb) == -1) {
-    puts("file doesn't exist");
-    return 2;
-  }
-
-  f = fsopen_m(0, cargv[1], SAMPLES, NULL, NULL);
-  if(!f)
-    return 3;
-
-  dump(f, stop - 100, stop);
-
-  fsclose_m(f);
-
-  return 0;
-}
-
diff --git a/graphing/fsample.c b/graphing/fsample.c
deleted file mode 100644 (file)
index 7c78d27..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "fsample.h"
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-
-static fsample_t version = 1;
-
-static void fscorefree(void *arg) {
-  fsample *f = (fsample *)arg;
-  munmap(f->header, f->len);
-}
-
-fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
-  int flags = 0;
-  int new = 0;
-  fsample *f = (fsample *)malloc(sizeof(fsample));
-  if(!f)
-    return NULL;
-
-  f->len = samples * sizeof(struct fsample_p) + sizeof(struct fsample_header);
-  f->fd = open(filename, O_RDWR|O_CREAT, 0600);
-
-  if(!lseek(f->fd, 0, SEEK_END))
-    new = 1;
-
-  if((f->fd == -1) || (lseek(f->fd, f->len - 1, SEEK_SET) == -1)) {
-    free(f);
-    return NULL;
-  }
-  write(f->fd, "", 1);
-
-  flags = MAP_SHARED;
-#ifdef MAP_NOCORE
-  flags|=MAP_NOCORE;
-#endif
-
-  f->header = mmap(NULL, f->len, PROT_READ|PROT_WRITE, flags, f->fd, 0);
-  if(f->header == MAP_FAILED) {
-    close(f->fd);
-    free(f);
-    return NULL;
-  }
-
-  if(!new && (memcmp(f->header->magic, "FSAMP", sizeof(f->header->magic)) || (version != f->header->version))) {
-    munmap(f->header, f->len);
-    close(f->fd);
-    free(f);
-    return NULL;
-  }
-
-  if(chafn && chdfn) {
-    f->corehandler = chafn(fscorefree, f);
-    f->corehandlerdel = chdfn;
-  } else {
-    f->corehandler = NULL;
-    f->corehandlerdel = NULL;
-  }
-
-  memcpy(f->header->magic, "FSAMP", sizeof(f->header->magic));
-  f->header->version = version;
-
-  f->m = (struct fsample_p *)(f->header + 1);
-  f->samples = samples;
-
-  if(f->header->iteration == 0)
-    f->header->iteration = 1;
-
-  return f;
-}
-
-void fsclose(fsample *f) {
-  munmap(f->header, f->len);
-  close(f->fd);
-
-  if(f->corehandlerdel && f->corehandler)
-    (f->corehandlerdel)(f->corehandler);
-
-  free(f);
-}
-
-int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag) {
-  fsample_m_entry *p = &f->entry[f->pos];
-
-  p->f = fsopen(filename, f->samples / freq, f->chafn, f->chdfn);
-  if(!p->f)
-    return 0;
-
-  p->freq = freq;
-  p->derive = derive;
-  p->tag = tag;
-  f->pos++;
-  return 1;
-}
-
-fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
-  fsample_m *n = (fsample_m *)malloc(sizeof(fsample_m) + (count + 1) * sizeof(fsample_m_entry));
-  if(!n)
-    return NULL;
-
-  n->samples = samples;
-  n->pos = 0;
-  n->chafn = chafn;
-  n->chdfn = chdfn;
-
-  if(!fsadd_m(n, filename, 1, NULL, 0)) {
-    free(n);
-    return NULL;
-  }
-
-  return n;
-}
-
-void fsset_m(fsample_m *f, fsample_t pos, fsample_t value) {
-  int i;
-
-  for(i=0;i<f->pos;i++) {
-    fsample_t v;
-
-    if((pos + 1) % f->entry[i].freq != 0)
-      continue;
-
-    if(f->entry[i].derive) {
-      v = (f->entry[i].derive)(f, i, pos, f->entry[i].tag);
-    } else {
-      v = value;
-    }
-
-    fsset(f->entry[i].f, pos / f->entry[i].freq, v);
-  }
-}
-
-void fsclose_m(fsample_m *f) {
-  int i;
-
-  for(i=0;i<f->pos;i++)
-    fsclose(f->entry[i].f);
-  free(f);
-}
-
-fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag) {
-  fsample_t c = 0;
-  long samples = (long)tag;
-  int count = 0;
-  int rpos = pos / f->entry[0].freq;
-  int i;
-  fsample_t t;
-
-  for(i=0;i<samples;i++) {
-    if(__fsget_m(f, 0, rpos - i, &t)) {
-      c+=t;
-      count++;
-    } else {
-/*      printf("bad :(\n");*/
-    }
-  }
-
-  if(count == 0)
-    return 0;
-
-  return c / count;
-}
-
-fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag) {
-  fsample_t c = 0;
-  long samples = (long)tag;
-  int count = 0;
-  int rpos = pos / f->entry[entry - 1].freq;
-  int i;
-  fsample_t t;
-
-  for(i=0;i<=samples;i++) {
-    if(__fsget(f->entry[entry - 1].f, rpos - i, &t)) {
-      c+=t;
-      count++;
-    } else {
-      /*printf("bad :(\n");*/
-    }
-  }
-
-  if(count == 0)
-    return 0;
-
-  return c / count;
-}
diff --git a/graphing/fsample.h b/graphing/fsample.h
deleted file mode 100644 (file)
index 1c4f63c..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-#ifndef __FSAMPLE_H
-#define __FSAMPLE_H
-
-#include <sys/types.h>
-
-typedef u_int32_t fsample_t;
-
-typedef struct fsample fsample;
-
-/* nice loss of type safety here... */
-typedef void *(*CoreHandlerAddFn)(void *handler, void *arg);
-typedef void (*CoreHandlerDelFn)(void *);
-
-/* single sample functions */
-fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
-void fsclose(fsample *f);
-
-struct fsample_m;
-typedef fsample_t (*DeriveValueFn)(struct fsample_m *v, int entry, fsample_t pos, void *tag);
-
-typedef struct fsample_m_entry {
-  size_t freq;
-  fsample *f;
-  void *tag;
-  DeriveValueFn derive;
-} fsample_m_entry;
-
-typedef struct fsample_m {
-  size_t pos, samples;
-  CoreHandlerAddFn chafn;
-  CoreHandlerDelFn chdfn;
-  struct fsample_m_entry entry[];
-} fsample_m;
-
-/* multiple sample functions */
-fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
-void fsclose_m(fsample_m *f);
-int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag);
-void fsset_m(fsample_m *f, fsample_t pos, fsample_t value);
-
-/* aggregates */
-fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag);
-fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag);
-
-struct fsample_p {
-  fsample_t v;
-  unsigned char iteration;
-};
-
-struct fsample_header {
-  char magic[4];
-  fsample_t version;
-  unsigned char iteration;
-  fsample_t lastpos;
-};
-
-struct fsample {
-  struct fsample_p *m;
-  int fd;
-  size_t samples, len;
-  struct fsample_header *header;
-  void *corehandler;
-  CoreHandlerDelFn corehandlerdel;
-};
-
-static inline unsigned char previteration(fsample *f) {
-  unsigned char p = f->header->iteration - 1;
-  if(p == 0)
-    p = 255;
-  return p;
-}
-
-/* doesn't support writing to negative numbers... */
-static inline void fsset(fsample *f, fsample_t pos, fsample_t value) {
-  fsample_t actualpos = pos % f->samples;
-  struct fsample_p *p = &f->m[actualpos];
-
-  if(f->header->lastpos > actualpos) {
-    f->header->iteration++;
-    if(f->header->iteration == 0)
-      f->header->iteration = 1;
-  }
-
-  f->header->lastpos = actualpos;
-
-  p->iteration = f->header->iteration;
-  p->v = value;
-}
-
-static inline fsample_t mmod(int x, int y) {
-#if -5 % 3 == -2
-  int v = x % y;
-  if(v < 0)
-    v = v + y;
-  return v;
-#else
-#error Unknown modulo operator function.
-#endif
-}
-
-/* API functions only have access to positive indicies */
-static inline fsample_t __fsget(fsample *f, int pos, fsample_t *t) {
-  struct fsample_p *p = &f->m[mmod(pos, f->samples)];
-
-  if(p->iteration != f->header->iteration) {
-    unsigned char prev = previteration(f);
-
-    if(prev != p->iteration || (pos <= f->header->lastpos)) {
-      /*printf("bad: prev: %d p->iteration: %d, pos: %d lastpos: %d\n", prev, p->iteration, pos, f->header->lastpos);*/
-      return 0;
-    }
-  }
-
-  *t = p->v;
-  return p->iteration;
-}
-
-static inline fsample_t fsget_r(fsample *f, fsample_t pos, fsample_t *t) {
-  struct fsample_p *p = &f->m[mmod(pos, f->samples)];
-
-  *t = p->v;
-  return p->iteration;
-}
-
-static inline fsample_t fsget(fsample *f, fsample_t pos, fsample_t *t) {
-  return __fsget(f, pos, t);
-}
-
-static inline fsample_t __fsget_m(fsample_m *f, int entry, int pos, fsample_t *t) {
-  return __fsget(f->entry[entry].f, pos / f->entry[entry].freq, t);
-}
-
-static inline fsample_t fsget_m(fsample_m *f, int entry, fsample_t pos, fsample_t *t) {
-  return fsget(f->entry[entry].f, pos / f->entry[entry].freq, t);
-}
-
-static inline fsample_t fsget_mr(fsample_m *f, int entry, fsample_t pos, fsample_t *t) {
-  return fsget_r(f->entry[entry].f, pos / f->entry[entry].freq, t);
-}
-
-#endif
diff --git a/graphing/graphing.c b/graphing/graphing.c
deleted file mode 100644 (file)
index 5a8cfed..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-#include <string.h>
-#include <stdio.h>
-
-#include "../core/hooks.h"
-#include "../core/config.h"
-#include "../usercount/usercount.h"
-#include "../lib/sstring.h"
-#include "../core/schedule.h"
-#include "../core/error.h"
-#include "../lib/sha1.h"
-#include "../lib/hmac.h"
-
-#include "graphing.h"
-
-static void gr_newserver(int hook, void *arg);
-static void gr_lostserver(int hook, void *arg);
-static void tick(void *arg);
-static void openserver(int servernum);
-static void closeserver(int servernum);
-
-fsample_m *servergraphs[MAXSERVERS];
-static void *sched;
-
-static sstring *path;
-
-void _init(void) {
-  int i;
-
-  memset(servergraphs, 0, sizeof(servergraphs));
-
-  path = getcopyconfigitem("graphing", "path", "", 100);
-  if(!path || !path->content || !path->content[0]) {
-    Error("graphing", ERR_WARNING, "Path not set, not loaded.");
-    return;
-  }
-
-  for(i=0;i<MAXSERVERS;i++)
-    openserver(i);
-
-  registerhook(HOOK_SERVER_NEWSERVER, gr_newserver);
-  registerhook(HOOK_SERVER_LOSTSERVER, gr_lostserver);
-
-  sched = schedulerecurring(time(NULL), 0, 1, tick, NULL);
-}
-
-void _fini(void) {
-  int i;
-  if(sched)
-    deleteschedule(sched, tick, NULL);
-
-  for(i=0;i<MAXSERVERS;i++)
-    if(servermonitored(i))
-      closeserver(i);
-
-  freesstring(path);
-
-  deregisterhook(HOOK_SERVER_NEWSERVER, gr_newserver);
-  deregisterhook(HOOK_SERVER_LOSTSERVER, gr_lostserver);
-}
-
-int servermonitored(int servernum) {
-  return servergraphs[servernum] != NULL;
-}
-
-static char *appendsuffix(char *prefix, char *suffix) {
-  static char buf[1024];
-
-  snprintf(buf, sizeof(buf), "%s%s", prefix, suffix);
-
-  return buf;
-}
-
-static void openserver(int servernum) {
-  unsigned char digest[SHA1_DIGESTSIZE];
-  char filename[512], hexdigest[sizeof(digest)*2 + 1];
-  FILE *f;
-  SHA1_CTX sha;
-  fsample_m *m;
-
-  if(servermonitored(servernum))
-    return;
-
-  if(serverlist[servernum].linkstate == LS_INVALID)
-    return;
-
-  SHA1Init(&sha);
-  SHA1Update(&sha, (unsigned char *)serverlist[servernum].name->content, serverlist[servernum].name->length);
-  SHA1Final(digest, &sha);
-
-  snprintf(filename, sizeof(filename), "%s/%s", path->content, hmac_printhex(digest, hexdigest, sizeof(digest)));
-
-  f = fopen(appendsuffix(filename, ".name"), "w");
-  if(!f) {
-    Error("graphing", ERR_WARNING, "Unable to create name file for %s (%s.name)", serverlist[servernum].name->content, filename);
-    return;
-  }
-
-  fprintf(f, "%s\n", serverlist[servernum].name->content);
-  fclose(f);
-
-  /* 0: seconds
-     1: minutes
-     2: hours
-     3: days
-     4: weeks
-     5: months
-   */
-
-  m = fsopen_m(GRAPHING_DATASETS, appendsuffix(filename, ".0"), SAMPLES, (CoreHandlerAddFn)registercorehandler, (CoreHandlerDelFn)deregistercorehandler);
-  if(!m) {
-    Error("graphing", ERR_WARNING, "Unable to create main backing store for %s (%s.0)", serverlist[servernum].name->content, filename);
-    return;
-  }
-/*
-  if(!fsadd_m(m, appendsuffix(filename, ".1"), PERMINUTE, fsapmean, (void *)PERMINUTE) ||
-     !fsadd_m(m, appendsuffix(filename, ".2"), PERMINUTE * 24, fsapmean, (void *)(PERMINUTE * 24)) ||
-     !fsadd_m(m, appendsuffix(filename, ".3"), PERMINUTE * 24 * 7, fsapmean, (void *)(PERMINUTE * 24 * 7)) ||
-     !fsadd_m(m, appendsuffix(filename, ".4"), PERMINUTE * 24 * 7 * 4, fsapmean, (void *)(PERMINUTE * 24 * 7 * 4)) ||
-     !fsadd_m(m, appendsuffix(filename, ".5"), PERMINUTE * 24 * 7 * 4 * 12, fsapmean, (void *)(PERMINUTE * 24 * 7 * 4 * 12)))
-  {
-    Error("graphing", ERR_WARNING, "Unable to create main side store for %s (%s.X)", serverlist[servernum].name->content, filename);
-    fsclose_m(m);
-    return;
-  }
-*/
-  servergraphs[servernum] = m;
-}
-
-static void closeserver(int servernum) {
-  if(!servermonitored(servernum))
-    return;
-
-  fsclose_m(servergraphs[servernum]);
-  servergraphs[servernum] = NULL;
-}
-
-static void gr_newserver(int hook, void *arg) {
-  long num = (long)arg;
-
-  openserver(num);
-}
-
-static void gr_lostserver(int hook, void *arg) {
-  long num = (long)arg;
-
-  closeserver(num);
-}
-
-static void tick(void *arg) {
-  time_t t = time(NULL);
-  int i;
-
-  if(t % GRAPHING_RESOLUTION != 0)
-    return;
-
-  for(i=0;i<MAXSERVERS;i++)
-    if(servermonitored(i))
-      fsset_m(servergraphs[i], t / GRAPHING_RESOLUTION, servercount[i]);
-}
-
-
diff --git a/graphing/graphing.h b/graphing/graphing.h
deleted file mode 100644 (file)
index 7c507af..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __GRAPHING_H
-#define __GRAPHING_H
-
-#include "../server/server.h"
-#include "../graphing/fsample.h"
-
-extern fsample_m *servergraphs[MAXSERVERS];
-int servermonitored(int servernum);
-
-#define GRAPHING_DATASETS 5
-#define GRAPHING_RESOLUTION 5
-
-#define PERMINUTE (60 / GRAPHING_RESOLUTION)
-#define SAMPLES PERMINUTE * 60 * 24 * 7 * 4 * 12
-
-#endif
diff --git a/graphing/nterfacer_graphing.c b/graphing/nterfacer_graphing.c
deleted file mode 100644 (file)
index 910202d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "../nterfacer/library.h"
-#include "../nterfacer/nterfacer.h"
-
-#include "graphing.h"
-
-#include <time.h>
-
-#define ERR_SERVER_NOT_MONITORED        0x01
-#define ERR_BAD_PARAMETERS              0x02
-#define ERR_BAD_ENTRY                   0x03
-
-int handle_servernames(struct rline *li, int argc, char **argv);
-int handle_serverdata(struct rline *li, int argc, char **argv);
-
-static struct service_node *g_node;
-
-void _init(void) {
-  g_node = register_service("graphing");
-  if(!g_node)
-    return;
-
-  register_handler(g_node, "servernames", 0, handle_servernames);
-  register_handler(g_node, "serverdata", 3, handle_serverdata);
-}
-
-void _fini(void) {
-  if(g_node)
-    deregister_service(g_node);
-}
-
-int handle_servernames(struct rline *li, int argc, char **argv) {
-  int i;
-
-  for(i=0;i<MAXSERVERS;i++) {
-    if((serverlist[i].linkstate != LS_INVALID) && servermonitored(i)) {
-      if(ri_append(li, "%d:%s", i, serverlist[i].name->content) == BF_OVER)
-        return ri_error(li, BF_OVER, "Buffer overflow");
-    }
-  }
-
-  return ri_final(li);
-}
-
-int handle_serverdata(struct rline *li, int argc, char **argv) {
-  int servernum = atoi(argv[0]);
-  unsigned int entry = atoi(argv[1]);
-  fsample_t count = atoi(argv[2]);
-  time_t t = time(NULL) / GRAPHING_RESOLUTION;
-  int i, ret;
-  fsample_m *m;
-
-  if(!servermonitored(servernum))
-    return ri_error(li, ERR_SERVER_NOT_MONITORED, "Server not monitored");
-
-  m = servergraphs[servernum];
-
-  if(entry > m->pos) /* not inclusive as 0 is used for for the base index */
-    return ri_error(li, ERR_BAD_PARAMETERS, "Bad parameters");
-
-  for(i=0;i<count;i++) {
-    fsample_t v;
-    if(fsget_m(m, entry, t - m->entry[entry].freq * i, &v)) {
-      ret = ri_append(li, "%d", v);
-    } else {
-      ret = ri_append(li, "-1", v);
-    }
-    if(ret == BF_OVER)
-      return ri_error(li, BF_OVER, "Buffer overflow");
-  }
-
-  return ri_final(li);
-}
-
index dd4b748e5204688f7828fbfacaf71a97c619d992..0359b51b43a34230e312fccaeb704d274db8aa6f 100644 (file)
@@ -232,7 +232,9 @@ const char *IPlongtostr(unsigned long IP) {
 /*
  * longtoduration: 
  *  Converts a specified number of seconds into a duration string.  
- *  format: 0 for the "/stats u" compatible output, 1 for more human-friendly output, 2 for a different human-friendly output.
+ *  format: 0 for the "/stats u" compatible output, 1 for more
+ *  human-friendly output (that is sometimes format 0), and
+ *  2 for a different human-friendly output.
  */
 
 const char *longtoduration(unsigned long interval, int format) {
@@ -245,11 +247,11 @@ const char *longtoduration(unsigned long interval, int format) {
   hours=(interval%(3600*24))/3600;
   days=interval/(3600*24);
 
-  if (format==0) {
-    sprintf(outstring,"%d day%s, %02d:%02d:%02d",
-            days,(days==1)?"":"s",hours,minutes,seconds);
-  } else if (format == 1) {
-    if (days>0) {
+  if(format<2) {
+    if (format==0 || (days>0 && (hours||minutes||seconds))) {
+      sprintf(outstring,"%d day%s, %02d:%02d:%02d",
+              days,(days==1)?"":"s",hours,minutes,seconds);
+    } else if (days>0) {
       sprintf(outstring, "%d day%s",days,(days==1)?"":"s");
     } else {
       if (hours>0) {
index ebb35c79053cf0cdd6c86f9f367a6be197ecf636..d8f70208beba3cbc2ab22471f12bd300cb537064 100644 (file)
@@ -28,8 +28,38 @@ static int getcalls;
 static int freecalls;
 static int allocs;
 
-/* Internal function */
+/* Internal functions */
 static void sstringstats(int hooknum, void *arg);
+static void salloc(void);
+
+#ifndef USE_VALGRIND
+
+#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 /* USE_VALGRIND */
 
 void initsstring() {
   int i;
@@ -50,10 +80,17 @@ void initsstring() {
   registerhook(HOOK_CORE_STATSREQUEST,&sstringstats);
 }
 
+#ifndef USE_VALGRIND
 void finisstring() {
   nsfreeall(POOL_SSTRING);
 }
 
+static void salloc(void) {
+  ssmem=(char *)nsmalloc(POOL_SSTRING, SSTRING_ALLOC);
+  ssmemfree=SSTRING_ALLOC;
+}
+#endif /* USE_VALGRIND */
+
 sstring *findsstring(const char *str) {
   unsigned int hash=crc32(str)%SSTRING_HASHSIZE;
   sstring *ss;
@@ -74,11 +111,25 @@ void sstring_enhash(sstring *ss) {
 
 void sstring_dehash(sstring *ss) {
   unsigned int hash=crc32(ss->content)%SSTRING_HASHSIZE;
-  sstring **ssh;
+  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 USE_VALGRIND
+        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;
     }
   }
@@ -89,7 +140,7 @@ void sstring_dehash(sstring *ss) {
 sstring *getsstring(const char *inputstr, int maxlen) {
   int i;
   sstring *retval=NULL;
-  int length;
+  int length, foreignblock;
   char strbuf[SSTRING_MAXLEN];
 
   /* getsstring() on a NULL pointer returns a NULL sstring.. */
@@ -121,10 +172,14 @@ sstring *getsstring(const char *inputstr, int maxlen) {
 
   /* If it's hashed this is easy */
   if ((retval=findsstring(strbuf))) {
-    retval->refcount++;
+    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++) {
@@ -134,6 +189,9 @@ sstring *getsstring(const char *inputstr, int maxlen) {
     if (freelist[length+i]!=NULL) {
       retval=freelist[length+i];
       freelist[length+i]=retval->next;
+      sunprotect(retval);
+      foreignblock=1;
+
       retval->alloc=(length+i);
       break;
     }  
@@ -146,14 +204,17 @@ 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;
+        sunprotectb(mblock);
+        retval->block=mblock;
         retval->alloc=(ssmemfree-sizeof(sstring));
         retval->refcount=0;
         freesstring(retval);
       }
   
-      allocs++;      
-      ssmem=(char *)nsmalloc(POOL_SSTRING, SSTRING_ALLOC);
-      ssmemfree=SSTRING_ALLOC;
+      allocs++;     
+      salloc();
+    } else {
+      sunprotectb(mblock);
     }
     
     retval=(sstring *)ssmem;
@@ -179,8 +240,14 @@ sstring *getsstring(const char *inputstr, int maxlen) {
   strcpy(retval->content,strbuf);
   retval->refcount=1;
   
+#ifdef USE_VALGRIND 
+  if(!foreignblock)
+    retval->block = mblock;
+#endif
+
   sstring_enhash(retval);
-  
+  sprotect(retval);
+
   return retval;    
 }
 
@@ -194,19 +261,24 @@ void freesstring(sstring *inval) {
   /* 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 */
+  /* 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) {
@@ -233,3 +305,25 @@ int sstringcompare(sstring *ss1, sstring *ss2) {
   return strncmp(ss1->content, ss2->content, ss1->length);
 }
 
+#ifdef USE_VALGRIND
+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 /* USE_VALGRIND */
index 5f5266926805c4f26c0df246a6b7242cb90159ba..a0bc0d47c0f8f3d1deafaac05e2b5bf2cd9b7559 100644 (file)
@@ -6,10 +6,15 @@
 /* Externally visibly max string length */
 #define SSTRING_MAX    512
 
+/* you can actually change USE_VALGRIND here without recompiling! */
 typedef struct sstring {
   short length;
   short alloc;
   struct sstring *next;
+#ifdef USE_VALGRIND
+  void *block;
+#endif
+  unsigned long refcount;
   char content[];
 } sstring;
 
index ade298ef23665b9bc62a9257d286d9da6f391f52..ccb347e1d1a4ad1c81789488fb72067750f18f73 100644 (file)
@@ -192,6 +192,16 @@ void sstringstats(int hooknum, void *arg) {
 
 #else /* USE_VALGRIND */
 
+#define __USE_MISC
+#include <sys/mman.h>
+
+#ifndef MAP_ANON
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
+#define MModify(x) mprotect(x, x->s->u.l.alloc, PROT_READ|PROT_WRITE)
+#define MUnmodify(x) mprotect(x, x->s->u.l.alloc, PROT_READ)
+
 typedef struct sstringlist {
   struct sstringlist *prev;
   struct sstringlist *next;
@@ -210,6 +220,8 @@ void finisstring() {
 
   for(s=head;s;s=sn) {
     sn = s->next;
+
+    MModify(s);
     s->next = NULL;
     s->prev = NULL;
 
@@ -223,6 +235,7 @@ sstring *getsstring(const char *inputstr, int maxlen) {
   sstringlist *s;
   size_t len;
   char *p;
+  void *m;
 
   if(!inputstr)
     return NULL;
@@ -231,20 +244,29 @@ sstring *getsstring(const char *inputstr, int maxlen) {
     ; /* empty */
 
   len = p - inputstr;
-  s=(sstringlist *)malloc(sizeof(sstringlist) + sizeof(sstring));
-  
+  m=mmap((void *)0, sizeof(sstringlist) + sizeof(sstring) + len + 1, PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANON, -1, 0);
+  s=(sstringlist *)m;
+
+  if(m == MAP_FAILED)
+    s->s->u.l.length = 0;
+
   s->s->u.l.length = len;
-  s->s->content=(char *)malloc(len + 1);
+  s->s->u.l.alloc = sizeof(sstringlist) + sizeof(sstring) + len + 1;
+  s->s->content=(char *)m + sizeof(sstringlist) + sizeof(sstring);
 
   memcpy(s->s->content, inputstr, len);
   s->s->content[len] = '\0';
 
   s->next = head;
   s->prev = NULL;
-  if(head)
+  if(head) {
+    MModify(head);
     head->prev = s;
+    MUnmodify(head);
+  }
   head = s;
 
+  MUnmodify(s);
   return s->s;
 }
 
@@ -255,18 +277,26 @@ void freesstring(sstring *inval) {
 
   s = (sstringlist *)inval - 1;
 
+  MModify(s);
   if(s->prev) {
+    MModify(s->prev);
     s->prev->next = s->next;
-    if(s->next)
+    MUnmodify(s->prev);
+    if(s->next) {
+      MModify(s->next);
       s->next->prev = s->prev;
+      MUnmodify(s->prev);
+    }
   } else {
     head = s->next;
-    if(head)
+    if(head) {
+      MModify(head);
       head->prev = NULL;
+      MUnmodify(head);
+    }
   }
 
-  free(inval->content);
-  free(s);
+  munmap(s, s->s->u.l.alloc);
 }
 #endif
 
index 411434daff7feac71383bcd0ff8d2cbf8e7bcc0a..8d55e39c83ea5dfcab7af7f75b4a663acc24c8f9 100644 (file)
@@ -4,12 +4,15 @@
 #include "../nick/nick.h"
 #include "../irc/irc.h"
 #include "../core/error.h"
+#include "../lib/version.h"
 
 #include <stdarg.h>
 #include <stdio.h>
 #include <assert.h>
 #include <string.h>
 
+MODULE_VERSION("")
+
 int handleserverstats(void *source, int cargc, char **cargv);
 int handleserverstatsend(void *source, int cargc, char **cargv);
 
index efa1ae16802cc9ab295497508b3ee908e66eac24..23b5f4c77455201870ed518b49a604294194f7aa 100644 (file)
@@ -135,7 +135,7 @@ void noperserv_cleanup_hooks(void) {
     firsttime = 0;
   }
 
-  if(oldhandler)
+  if(oldhandler && mynick)
     hooklocaluserhandler(mynick, oldhandler);
 
   controlwall = oldwall;
@@ -143,6 +143,10 @@ void noperserv_cleanup_hooks(void) {
 }
 
 void noperserv_trap_registration(int hooknum, void *arg) {
+  nick *np = (nick *)arg;
+  if(!np)
+    return;
+
   oldhandler = hooklocaluserhandler((nick *)arg, &noperserv_handle_messages);
   if(!oldhandler)
     return;
index 9b47ee501e5b287ac6e22c24cc5a155096f9bdc9..47e9ba7c52f51b0eba673524d7af8f9de1422463 100644 (file)
@@ -5,6 +5,9 @@
 #include "../localuser/localuserchannel.h"
 #include "../control/control.h"
 #include "../usercount/usercount.h"
+#include "../lib/version.h"
+
+MODULE_VERSION("")
 
 #include <stdlib.h>
 #include <string.h>
index d0fc405a008ee2cb032612582513f3d71cb37b6a..02cecb6af585f13481069baf74b7bb03a78d3b40 100644 (file)
@@ -2,8 +2,11 @@
 
 #include "../nick/nick.h"
 #include "../core/hooks.h"
+#include "../lib/version.h"
 #include "usercount.h"
 
+MODULE_VERSION("")
+
 int servercount[MAXSERVERS];
 
 static void uc_newserver(int hook, void *arg);
index 11fb73e14f7474353b72992563842338e3510c3a..2450c415ca0ade1ad95b75be80afe388a9c692f5 100644 (file)
--- a/xsb/xsb.c
+++ b/xsb/xsb.c
@@ -1,3 +1,5 @@
+/* TODO: catch control messages */
+
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -7,28 +9,45 @@
 #include "../irc/irc.h"
 #include "../lib/array.h"
 #include "../lib/base64.h"
+#include "../lib/irc_string.h"
 #include "../core/error.h"
-#include "../server/server.h"
-#include "../control/control.h"
+#include "../localuser/localuser.h"
+#include "../lib/strlfunc.h"
 #include "xsb.h"
 
+#undef XSB_DEBUG
+
 static const char *DEFAULT_SERVICE_MASKS[] = { "services*.*.quakenet.org", (char *)0 };
+
 static array defaultservicemasks_a;
 static sstring **defaultservicemasks;
 
 static void handlemaskprivmsg(int, void *);
+static void handlecontrolregistered(int, void *);
 static CommandTree *cmds;
 
-#define DEBUG
+static char controlnum[6];
+
+struct messagequeue {
+  struct messagequeue *next;
+  char buf[];
+};
+
+struct messagequeue *head, *tail;
 
 void _init(void) {
   const char **p;
   array *servicemasks;
 
+  controlnum[0] = '\0';
+  
   cmds = newcommandtree();
-  if(cmds)
-    registerhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
-
+  if(!cmds)
+    return;
+  
+  registerhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
+  registerhook(HOOK_CONTROL_REGISTERED, &handlecontrolregistered);
+  
   array_init(&defaultservicemasks_a, sizeof(sstring *));
 
   for(p=DEFAULT_SERVICE_MASKS;*p;p++) {
@@ -45,17 +64,35 @@ void _init(void) {
 
 void _fini(void) {
   int i;
+  struct messagequeue *q, *nq;
+  
+  if(!cmds)
+    return;
+
+  destroycommandtree(cmds);
+
+  deregisterhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
+  deregisterhook(HOOK_CONTROL_REGISTERED, &handlecontrolregistered);
 
   for(i=0;i<defaultservicemasks_a.cursi;i++)
     freesstring(defaultservicemasks[i]);
   array_free(&defaultservicemasks_a);
 
-  if(!cmds)
-    return;
+  for(q=head;q;q=nq) {
+    nq = q->next;
+    free(q);
+  }
+  
+  head = NULL;
+  tail = NULL;
+}
 
-  deregisterhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
+void xsb_addcommand(const char *name, const int maxparams, CommandHandler handler) {
+  addcommandtotree(cmds, name, 0, maxparams, handler);
+}
 
-  destroycommandtree(cmds);
+void xsb_delcommand(const char *name, CommandHandler handler) {
+  deletecommandfromtree(cmds, name, handler);
 }
 
 static void handlemaskprivmsg(int hooknum, void *args) {
@@ -86,7 +123,7 @@ static void handlemaskprivmsg(int hooknum, void *args) {
     return;
   }
 
-#ifndef DEBUG
+#ifndef XSB_DEBUG
   if(!(s->flags & SMODE_SERVICE)) {
     Error("xsb", ERR_WARNING, "Got XSB message from non-service server (%s): %s", s->name->content, source->nick);
     return;
@@ -105,34 +142,113 @@ static void handlemaskprivmsg(int hooknum, void *args) {
   (cmd->handler)(source, cargc - 2, &cargv[2]);
 }
 
-void xsb_addcommand(const char *name, const int maxparams, CommandHandler handler) {
-  addcommandtotree(cmds, name, 0, maxparams, handler);
+static void directsend(char *buf) {
+  irc_send("%s P %s", controlnum, buf);
 }
 
-void xsb_delcommand(const char *name, CommandHandler handler) {
-  deletecommandfromtree(cmds, name, handler);
+static void handlecontrolregistered(int hooknum, void *args) {
+  nick *np = (nick *)args;
+
+  if(np) {
+    struct messagequeue *q, *nq;
+    
+    longtonumeric2(np->numeric, 5, controlnum);
+    
+    for(q=head;q;q=nq) {
+      nq = q->next;
+      
+      directsend(q->buf);
+      free(q);
+    }
+    head = NULL;
+    tail = NULL;
+  } else {
+    controlnum[0] = '\0';
+  }
 }
 
-void xsb_command(const char *command, const char *format, ...) {
+static int getservicemasks(sstring ***masks) {
+  array *aservicemasks = getconfigitems("xsb", "servicemask");
+  if(!aservicemasks || !aservicemasks->cursi)
+    aservicemasks = &defaultservicemasks_a;
+
+  *masks = (sstring **)aservicemasks->content;
+
+  return aservicemasks->cursi;
+}
+
+static void xsb_send(const char *format, ...) {
+  char buf[512];
+  va_list va;
+  size_t len;
+  
+  va_start(va, format);
+  len = vsnprintf(buf, sizeof(buf), format, va);
+  va_end(va);
+  if(len >= sizeof(buf))
+    len = sizeof(buf);
+  
+  if(controlnum[0]) {
+    directsend(buf);
+  } else {
+    struct messagequeue *q = (struct messagequeue *)malloc(sizeof(struct messagequeue) + len);
+    
+    strlcpy(q->buf, buf, len + 1);
+    q->next = NULL;
+    if(tail) {
+      tail->next = q;
+    } else {
+      head = q;
+    }
+    tail = q;
+  }
+}
+
+void xsb_broadcast(const char *command, server *service, const char *format, ...) {
   char buf[512];
   va_list va;
   sstring **servicemasks;
-  array *aservicemasks;
   int i;
-  char *controlnum;
 
   va_start(va, format);
   vsnprintf(buf, sizeof(buf), format, va);
   va_end(va);
 
-  aservicemasks = getconfigitems("xsb", "servicemask");
-  if(!aservicemasks || !aservicemasks->cursi)
-    aservicemasks = &defaultservicemasks_a;
+  if(service) {
+    xsb_send("$%s :XSB1 %s %s", service->name->content, command, buf);
+    return;
+  }
 
-  servicemasks = (sstring **)aservicemasks->content;
+  for(i=getservicemasks(&servicemasks)-1;i>=0;i--)
+    xsb_send("$%s :XSB1 %s %s", servicemasks[i]->content, command, buf);
+}
 
-  controlnum = longtonumeric(mynick->numeric, 5);
+void xsb_unicast(const char *command, nick *np, const char *format, ...) {
+  char buf[512];
+  va_list va;
+  
+  va_start(va, format);
+  vsnprintf(buf, sizeof(buf), format, va);
+  va_end(va);
 
-  for(i=0;i<aservicemasks->cursi;i++)
-    irc_send("%s P $%s :XSB1 %s %s", controlnum, servicemasks[i]->content, command, buf);
+  /* TODO */
+  xsb_send("$%s :XSB1 %s %s", serverlist[homeserver(np->numeric)].name, command, buf);
+  /* xsb_send("%s :XSB1 %s %s", longtonumeric(np->numeric, 5), command, buf);*/
+  
 }
+
+int xsb_isservice(server *service) {
+  int i;
+  sstring **servicemasks;
+  char *name = service->name->content;
+
+  if(!(service->flags & SMODE_SERVICE))
+    return 0;
+
+  for(i=getservicemasks(&servicemasks)-1;i>=0;i--)
+    if(match2strings(servicemasks[i]->content, name))
+      return 1;
+
+  return 0;
+}
+
index ea33450f732a7d0bfdaa36a4f38c1d325f7002e5..78b73f2651f681abc68063f9dd3edc8a5408a7a2 100644 (file)
--- a/xsb/xsb.h
+++ b/xsb/xsb.h
@@ -2,9 +2,13 @@
 #define __XSB_H
 
 #include "../parser/parser.h"
+#include "../nick/nick.h"
+#include "../server/server.h"
 
 void xsb_addcommand(const char *name, const int maxparams, CommandHandler handler);
 void xsb_delcommand(const char *name, CommandHandler handler);
-void xsb_command(const char *command, const char *format, ...);
+void xsb_broadcast(const char *command, server *service, const char *format, ...);
+void xsb_unicast(const char *command, nick *np, const char *format, ...);
+int xsb_isservice(server *service);
 
 #endif