]> jfr.im git - irc/quakenet/newserv.git/blobdiff - localuser/localuserchannel.c
TRUSTS: require sqlite
[irc/quakenet/newserv.git] / localuser / localuserchannel.c
index 1e52e6d9057556fe4d247566af4149c725afca89..d770f877a22a22075eb4df957ab6d723f77e9cea 100644 (file)
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <string.h>
+#include <stdint.h>
 
 MODULE_VERSION("");
 
@@ -94,7 +95,7 @@ int handleinvitecmd(void *source, int cargc, char **cargv) {
   }
   
   if (!(sender=getnickbynumericstr(source))) {
-    Error("localuserchannel",ERR_WARNING,"Got invite from unknown numeric %s.",source);
+    Error("localuserchannel",ERR_WARNING,"Got invite from unknown numeric %s.",(char *)source);
     return CMD_OK;
   }
   
@@ -236,7 +237,11 @@ int localburstontochannel(channel *cp, nick *np, time_t timestamp, flag_t modes,
     /* deal with key - if we need one use the provided one if set, otherwise
      * the existing one, but if there is no existing one clear +k */
     if (IsKey(cp)) {
-      if (key) {
+      /* Sanitise the provided key - this might invalidate it.. */
+      if (key)
+        clean_key(key);
+        
+      if (key && *key) {
         /* Free old key, if any */
         if (cp->key)
           freesstring(cp->key);
@@ -298,7 +303,7 @@ int localburstontochannel(channel *cp, nick *np, time_t timestamp, flag_t modes,
     }
     
     /* XX B #channel <timestamp> +modes <limit> <key> <user> */
-    irc_send("%s B %s %lu %s %s%s%s%s",
+    irc_send("%s B %s %lu %s%s%s%s%s",
               mynumeric->content,cp->index->name->content,cp->timestamp,
               printflags(cp->flags,cmodeflags),extramodebuf,
               IsKey(cp)?" ":"",IsKey(cp)?cp->key->content:"", nickbuf);
@@ -334,11 +339,12 @@ int localjoinchannel(nick *np, channel *cp) {
   harg[0]=cp;
   harg[1]=np;
     
-  triggerhook(HOOK_CHANNEL_JOIN, harg);
-    
   if (connected) {
     irc_send("%s J %s %lu",longtonumeric(np->numeric,5),cp->index->name->content,cp->timestamp);
   }
+
+  triggerhook(HOOK_CHANNEL_JOIN, harg);
+    
   return 0;
 }
 
@@ -347,7 +353,7 @@ int localpartchannel(nick *np, channel *cp, char *reason) {
   
   /* Check pointers are valid.. */
   if (cp==NULL || np==NULL) {
-    Error("localuserchannel",ERR_WARNING,"Trying to part NULL channel or NULL nick (cp=%x,np=%x)",cp,np);
+    Error("localuserchannel",ERR_WARNING,"Trying to part NULL channel or NULL nick (cp=%p,np=%p)",cp,np);
     return 1;
   }    
   
@@ -509,7 +515,7 @@ void localdosetmode_ban (modechanges *changes, const char *ban, short dir) {
  *  Set or clear a key on the channel
  */
 
-void localdosetmode_key (modechanges *changes, const char *key, short dir) {
+void localdosetmode_key (modechanges *changes, char *key, short dir) {
   int i,j;
   sstring *keysstr;
 
@@ -518,6 +524,11 @@ void localdosetmode_key (modechanges *changes, const char *key, short dir) {
     localsetmodeflush(changes,0);
 
   if (dir==MCB_ADD) {
+    /* Sanitise the key.  If this nullifies it then we give up */
+    clean_key(key);
+    if (!*key)
+      return;
+
     /* Get a copy of the key for use later */
     keysstr=getsstring(key, KEYLEN);
     
@@ -534,6 +545,7 @@ void localdosetmode_key (modechanges *changes, const char *key, short dir) {
          freesstring(changes->cp->key);
          changes->cp->key=getsstring(key, KEYLEN);
          /* That's it, we're done */
+         freesstring(keysstr);
          return;
        } else {
          /* There was a command to delete key.. we need to flush 
@@ -697,6 +709,11 @@ void localdosetmode_nick (modechanges *changes, nick *target, short modes) {
     return;
   }
 
+  if (IsCloaked(target)) {
+    /* Target is cloaked, never set channel modes for cloaked users */
+    return;
+  }
+
   if ((modes & MC_DEOP) && (*lp & CUMODE_OP)) {
     (*lp) &= ~CUMODE_OP;
     if (changes->changecount >= MAXMODEARGS)
@@ -876,6 +893,7 @@ void localusermodechange(nick *np, channel *cp, char *modes) {
 void localsettopic(nick *np, channel *cp, char *topic) {
   unsigned long *lp;
   char source[10];
+  time_t now=getnettime();
 
   if (np==NULL || (lp=getnumerichandlefromchanhash(cp->users,np->numeric))==NULL) {
     /* User isn't on channel, hack mode */
@@ -896,10 +914,16 @@ void localsettopic(nick *np, channel *cp, char *topic) {
   }
 
   cp->topic=getsstring(topic,TOPICLEN);
-  cp->topictime=getnettime();
+
+  /* Update the topic time iff the old time was in the past.  This 
+   * means if we are bouncing a topic with a TS 1sec newer than ours 
+   * we won't use an old timestamp */
+  if (cp->topictime < now) {
+    cp->topictime=now;
+  }
   
   if (connected) {
-    irc_send("%s T %s %u %u :%s",source,cp->index->name->content,cp->timestamp,cp->topictime,(cp->topic)?cp->topic->content:"");
+    irc_send("%s T %s %jd %jd :%s",source,cp->index->name->content,(intmax_t)cp->timestamp,(intmax_t)cp->topictime,(cp->topic)?cp->topic->content:"");
   }
 }
 
@@ -1024,7 +1048,30 @@ void sendmessagetochannel(nick *source, channel *cp, char *format, ... ) {
   }
 }
 
-void localinvite(nick *source, channel *cp, nick *target) {
+void sendopnoticetochannel(nick *source, channel *cp, char *format, ... ) {
+  char buf[BUFSIZE];
+  char senderstr[6];
+  va_list va;
+  
+  if (!source)
+    return;
+  longtonumeric2(source->numeric,5,senderstr);
+     
+  va_start(va,format);
+  /* 10 bytes of numeric, 5 bytes of fixed format + terminator = 17 bytes */
+  /* So max sendable message is 495 bytes.  Of course, a client won't be able
+   * to receive this.. */
+
+  vsnprintf(buf,BUFSIZE-17,format,va);
+  va_end(va);
+
+  if (connected) {
+    irc_send("%s WC %s :%s",senderstr,cp->index->name->content,buf);
+  }
+}
+
+void localinvite(nick *source, chanindex *cip, nick *target) {
 
   /* Servers can't send invites */
   if (!source) 
@@ -1036,7 +1083,7 @@ void localinvite(nick *source, channel *cp, nick *target) {
    * argument */
   if (connected) {
     irc_send("%s I %s :%s",longtonumeric(source->numeric,5),
-            target->nick, cp->index->name->content);
+            target->nick, cip->name->content);
   }
 }