]> jfr.im git - irc/quakenet/newserv.git/blobdiff - control/control.c
chanfix: Fix check for null pointer.
[irc/quakenet/newserv.git] / control / control.c
index 76caa3efb98dec09b1ee4908a11249de0fab6276..e55879653fb83de6a1a01a05330298fb4c5454bd 100644 (file)
@@ -36,7 +36,10 @@ nick *mynick;
 CommandTree *controlcmds;
 ControlMsg controlreply;
 ControlWall controlwall;
+ControlPermitted controlpermitted;
+DestroyExt controldestroyext;
 
+void controldestroycmdext(void *ext); 
 void handlemessages(nick *target, int messagetype, void **args);
 int controlstatus(void *sender, int cargc, char **cargv);
 void controlconnect(void *arg);
@@ -49,12 +52,17 @@ int controllsmod(void *sender, int cargc, char **cargv);
 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, ...) __attribute__ ((format (printf, 3, 4)));
 void controlnoticeopers(flag_t permissionlevel, flag_t noticelevel, char *format, ...);
+int controlcheckpermitted(flag_t level, nick *user);
+void handlesignal(int hooknum, void *arg);
 
 void _init() {
   controlcmds=newcommandtree();
   controlreply=&controlmessage;
   controlwall=&controlnoticeopers;
+  controlpermitted=&controlcheckpermitted;
+  controldestroyext=&controldestroycmdext;
 
   registercontrolhelpcmd("status",NO_DEVELOPER,1,&controlstatus,"Usage: status ?level?\nDisplays status information, increasing level gives more verbose information.");
   registercontrolhelpcmd("whois",NO_OPERED,1,&controlwhois,"Usage: whois <nickname|#numeric>\nDisplays lots of information about the specified nickname or numeric.");
@@ -68,7 +76,9 @@ void _init() {
   registercontrolhelpcmd("showcommands",NO_ACCOUNT,0,&controlshowcommands,"Usage: showcommands\nShows all registered commands.");
   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, &handlesignal);
+  registerhook(HOOK_CORE_SIGINT, &handlesignal);
   scheduleoneshot(time(NULL)+1,&controlconnect,NULL);
 }
 
@@ -92,12 +102,57 @@ void _fini() {
   deregistercontrolcmd("help",&controlhelpcmd);
   
   destroycommandtree(controlcmds);
+
+  deregisterhook(HOOK_CORE_REHASH, &handlesignal);
+  deregisterhook(HOOK_CORE_SIGINT, &handlesignal);
+}
+
+void registercontrolhelpcmd(const char *name, int level, int maxparams, CommandHandler handler, char *helpstr) {
+  cmdhelp *help;
+  Command *newcmd;
+
+  newcmd = addcommandtotree(controlcmds,name,level,maxparams,handler);
+  if (helpstr) {
+    /* Allocate a help record */
+    help=(cmdhelp *)malloc(sizeof(cmdhelp));
+    if(!help) {
+      Error("control",ERR_ERROR,"Malloc failed: registercontrolhelpcmd");
+      return; 
+    }
+    memset((void *)help,0,sizeof(cmdhelp));
+
+    /* this isn't an sstring atm, as sstring has a max length (512) */ 
+    int len=strlen(helpstr);
+    help->helpstr=(char *)malloc(len+1);
+    if(help->helpstr) {
+      strncpy(help->helpstr, helpstr, len);
+      help->helpstr[len] = '\0';
+    }
+    newcmd->ext=(void *)help;
+    newcmd->destroyext=controldestroyext;
+  }
 }
 
-void registercontrolhelpcmd(const char *name, int level, int maxparams, CommandHandler handler, char *help) {
-  addcommandhelptotree(controlcmds,name,level,maxparams,handler,help);
+void registercontrolhelpfunccmd(const char *name, int level, int maxparams, CommandHandler handler, CommandHelp helpcmd) {
+  cmdhelp *help;
+  Command *newcmd;
+
+  /* Allocate a help record */
+  help=(cmdhelp *)malloc(sizeof(cmdhelp));
+  if (!help) {
+    Error("control",ERR_ERROR,"Malloc failed: registercontrolhelpfunccmd");
+    return;
+  }
+  memset((void *)help,0,sizeof(cmdhelp));
+
+  help->helpcmd=helpcmd;
+
+  newcmd = addcommandexttotree(controlcmds,name,level,maxparams,handler, (void *)help);
+  newcmd->destroyext=controldestroyext;
 }
 
+
 int deregistercontrolcmd(const char *name, CommandHandler handler) {
   return deletecommandfromtree(controlcmds, name, handler);
 }
@@ -194,7 +249,21 @@ int controlwhois(void *sender, int cargc, char **cargv) {
     }
   }
   controlreply((nick *)sender,"Timestamp : %lu",target->timestamp);
-  controlreply((nick *)sender,"IP address: %s",IPtostr(target->p_ipaddr));
+
+  /* HACK */
+  {
+    int ext = findnickext("signontracker");
+
+    if(ext >= 0) {
+      time_t signedon = (time_t)(target->exts[ext]);
+      if(signedon) {
+        controlreply((nick *)sender,"Signed on : %lu",signedon);
+      } else {
+        controlreply((nick *)sender,"Signed on : ???");
+      }
+    }
+  }
+  controlreply((nick *)sender,"IP address: %s",IPtostr(target->ipaddress));
   controlreply((nick *)sender,"Realname  : %s (%d user(s) have this realname)",target->realname->name->content,target->realname->usercount);
   if (target->umodes) {
     controlreply((nick *)sender,"Umode(s)  : %s",printflags(target->umodes,umodeflags));
@@ -212,6 +281,10 @@ int controlwhois(void *sender, int cargc, char **cargv) {
     }
   }
 
+  if (target->away) {
+    controlreply((nick *)sender, "Away      : %s",target->away->content);
+  }
+
   hooknick=(nick *)sender;
   registerhook(HOOK_CONTROL_WHOISREPLY,&handlewhois);
   triggerhook(HOOK_CONTROL_WHOISREQUEST,target);
@@ -270,7 +343,7 @@ int controlrmmod(void *sender, int cargc, char **cargv) {
   if (cargc<1)
     return CMD_USAGE;
   
-  switch(rmmod(cargv[0])) {
+  switch(rmmod(cargv[0], 1)) {
     case 1:
       controlreply((nick *)sender,"Module %s is not loaded.",cargv[0]);
       return CMD_ERROR;
@@ -295,9 +368,9 @@ int controllsmod(void *sender, int cargc, char **cargv) {
     ptr = lsmod(i, &ver, &buildid, &t);
 
     /*                                                                    9999d 24h 59m 59s fbf2a4a69ee1-tip */
-    controlreply((nick *)sender,"Module                                   Loaded for        Version              Build id");
+    controlreply((nick *)sender,"Module                                   Loaded for        Version                        Build id");
     while (ptr != NULL) {
-      controlreply((nick *)sender," %-40s %-17s %-20s %s", ptr, longtoduration(t2-t, 2), ver?ver:"", buildid?buildid:"");
+      controlreply((nick *)sender," %-40s %-17s %-30s %s", ptr, longtoduration(t2-t, 2), ver?ver:"", buildid?buildid:"");
       ptr = lsmod(++i, &ver, &buildid, &t);
     }
   } else {
@@ -331,7 +404,7 @@ int relink(void *sender, int cargc, char **cargv) {
 }
 
 int die(void *sender, int cargc, char **cargv) {
-  if (cargc<1) {
+  if (cargc<1 || (strlen(cargv[0]) < 10)) {
     controlreply((nick *)sender,"You must give a reason.");
     return CMD_USAGE;
   }
@@ -479,6 +552,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:
@@ -537,7 +611,7 @@ void controlspecialrmmod(void *arg) {
   
   a->schedule = NULL;
 
-  rmmod(froo->content);
+  rmmod(froo->content, 1);
   freesstring(froo);
 }
 
@@ -552,29 +626,42 @@ void controlspecialreloadmod(void *arg) {
 }
 
 void controlhelp(nick *np, Command *cmd) {
-  sstring *scp = cmd->help;
-  if(!scp) {
+  char *cp, *sp;
+  char *scp;
+  cmdhelp *help=(cmdhelp *)cmd->ext;
+
+  if (!help) { 
     controlreply(np, "Sorry, no help for this command.");
+    return;
+  }
+  if ( help->helpcmd ) {
+    (help->helpcmd)(np, cmd); 
   } else {
-    char *cp = scp->content, *sp = cp;
-    int finished = 0;
-    for(;;cp++) {
-      if(*cp == '\0' || *cp == '\n') {
-        if(*cp == '\0') {
-          finished = 1;
-        } else {
-          *cp = '\0';
+    scp = help->helpstr;
+    if (!scp) {
+      controlreply(np, "Sorry, no help for this command.");
+    } else {
+      cp = scp;
+      sp = cp;
+      int finished = 0;
+      for(;;cp++) {
+        if(*cp == '\0' || *cp == '\n') {
+          if(*cp == '\0') {
+            finished = 1;
+          } else {
+            *cp = '\0';
+          }
+
+          if(sp != cp)
+            controlreply(np, "%s", sp);
+
+          if(finished)
+            break;
+
+          *cp = '\n';
+
+          sp = cp + 1;
         }
-
-        if(sp != cp)
-          controlreply(np, "%s", sp);
-
-        if(finished)
-          break;
-
-        *cp = '\n';
-
-        sp = cp + 1;
       }
     }
   }
@@ -624,3 +711,39 @@ void controlnswall(int noticelevel, char *format, ...) {
   controlwall(NO_OPER, noticelevel, "%s", broadcast);
 }
 
+int controlcheckpermitted(flag_t level, nick *user) {
+  return 1;
+}
+
+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);
+}
+
+void controldestroycmdext(void *ext) {
+  if ( ((cmdhelp *)ext)->helpstr)
+    free( ((cmdhelp *)ext)->helpstr);
+  free(ext);
+}
+
+char *controlid(nick *np) {
+  static char buf[512];
+
+  snprintf(buf, sizeof(buf), "%s!%s@%s/%s", np->nick, np->ident, np->host->name->content, np->authname);
+
+  return buf;
+}
+