/* 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);
}
/* 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);
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;
}
-int localpartchannel(nick *np, channel *cp) {
+int localpartchannel(nick *np, channel *cp, char *reason) {
void *harg[3];
/* Check pointers are valid.. */
}
if (connected) {
- irc_send("%s L %s",longtonumeric(np->numeric,5),cp->index->name->content);
+ if (reason != NULL)
+ irc_send("%s L %s :%s",longtonumeric(np->numeric,5),cp->index->name->content, reason);
+ else
+ irc_send("%s L %s",longtonumeric(np->numeric,5),cp->index->name->content);
}
harg[0]=cp;
/* If we're told to clear a ban that isn't here, do nothing. */
if (dir==MCB_DEL && !clearban(changes->cp, bansstr->content, 1))
return;
+
+ /* Similarly if someone is trying to add a completely overlapped ban, do
+ * nothing */
+ if (dir==MCB_ADD && !setban(changes->cp, bansstr->content))
+ return;
if (changes->changecount >= MAXMODEARGS)
localsetmodeflush(changes, 0);
* 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;
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);
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
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 */
}
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:"");
}
}
+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, channel *cp, nick *target) {
/* Servers can't send invites */