Add "dummy client" support.
authorMichael Poole <mdpoole@troilus.org>
Fri, 22 Sep 2006 02:15:55 +0000 (02:15 +0000)
committerMichael Poole <mdpoole@troilus.org>
Fri, 22 Sep 2006 02:15:55 +0000 (02:15 +0000)
src/hash.h (FLAGS_DUMMY): New flag for non-propagated clients.
  (IsDummy): Check it.

src/helpfile.c (send_message): Allow sending to dummy clients.
  (send_message_type): Likewise.

src/proto-bahamut.c (irc_user): Bail if user is NULL or has a dummy nickname.
  (deliver_to_dummy): New function.
  (irc_privmsg): Try to deliver via dummy method before sending to IRC.
  (irc_notice): Likewise.
  (irc_notice_user): Likewise.
  (AddUser): If the first user mode character is '*', mark as a dummy.
  (DelUser): Unregister callback functions when destroying local clients.

src/proto-p10.c (irc_user): Bail if user is NULL or has a dummy nickname.
  (deliver_to_dummy): New function.
  (irc_notice): Try to deliver via dummy method before sending to IRC.
  (irc_notice_user): Likewise.
  (irc_privmsg): Likewise.
  (AddUser): If the first user mode character is '*', mark as a dummy.
  (DelUser): Unregister callback functions when destroying local clients.
git-archimport-id: srvx@srvx.net--2006/srvx--devo--1.3--patch-37

ChangeLog
src/hash.h
src/helpfile.c
src/proto-bahamut.c
src/proto-p10.c

index bd3963b5908bbba902fd6218e3e4edaa1917f202..bbcef8f2a677934099130da6d5a6e37964aee8e3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,40 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2006/srvx--devo--1.3
 #
 
+2006-09-22 02:15:55 GMT        Michael Poole <mdpoole@troilus.org>     patch-37
+
+    Summary:
+      Add "dummy client" support.
+    Revision:
+      srvx--devo--1.3--patch-37
+
+    src/hash.h (FLAGS_DUMMY): New flag for non-propagated clients.
+      (IsDummy): Check it.
+    
+    src/helpfile.c (send_message): Allow sending to dummy clients.
+      (send_message_type): Likewise.
+    
+    src/proto-bahamut.c (irc_user): Bail if user is NULL or has a dummy nickname.
+      (deliver_to_dummy): New function.
+      (irc_privmsg): Try to deliver via dummy method before sending to IRC.
+      (irc_notice): Likewise.
+      (irc_notice_user): Likewise.
+      (AddUser): If the first user mode character is '*', mark as a dummy.
+      (DelUser): Unregister callback functions when destroying local clients.
+    
+    src/proto-p10.c (irc_user): Bail if user is NULL or has a dummy nickname.
+      (deliver_to_dummy): New function.
+      (irc_notice): Try to deliver via dummy method before sending to IRC.
+      (irc_notice_user): Likewise.
+      (irc_privmsg): Likewise.
+      (AddUser): If the first user mode character is '*', mark as a dummy.
+      (DelUser): Unregister callback functions when destroying local clients.
+
+    modified files:
+     ChangeLog src/hash.h src/helpfile.c src/proto-bahamut.c
+     src/proto-p10.c
+
+
 2006-09-22 01:56:07 GMT        Michael Poole <mdpoole@troilus.org>     patch-36
 
     Summary:
index f00212698caa89a35edeb4c3b1aca8fc4765ca7a..99b411413724911363bd1b7fad60dec898b8c871 100644 (file)
@@ -58,6 +58,7 @@
 #define FLAGS_HIDDEN_HOST       0x2000 /* user's host is masked by their account */
 #define FLAGS_REGNICK           0x4000 /* user owns their current nick */
 #define FLAGS_REGISTERING       0x8000 /* user has issued account register command, is waiting for email cookie */
+#define FLAGS_DUMMY             0x10000 /* user is not announced to other servers */
 
 #define IsOper(x)               ((x)->modes & FLAGS_OPER)
 #define IsService(x)            ((x)->modes & FLAGS_SERVICE)
@@ -72,6 +73,7 @@
 #define IsHiddenHost(x)         ((x)->modes & FLAGS_HIDDEN_HOST)
 #define IsReggedNick(x)         ((x)->modes & FLAGS_REGNICK)
 #define IsRegistering(x)       ((x)->modes & FLAGS_REGISTERING)
+#define IsDummy(x)              ((x)->modes & FLAGS_DUMMY)
 #define IsFakeHost(x)           ((x)->fakehost[0] != '\0')
 #define IsLocal(x)              ((x)->uplink == self)
 
index 38a61ec6877d03c8e511e4bba9ec2f26a9a4f632..8819ebb30ea5ec549ff0492038dbed2c19953f08 100644 (file)
@@ -659,7 +659,7 @@ send_message(struct userNode *dest, struct userNode *src, const char *format, ..
     int res;
     va_list ap;
 
-    if (IsLocal(dest)) return 0;
+    if (IsLocal(dest) && !IsDummy(dest)) return 0;
     va_start(ap, format);
     res = vsend_message(dest->nick, src, dest->handle_info, 0, NULL, format, ap);
     va_end(ap);
@@ -671,7 +671,7 @@ send_message_type(int msg_type, struct userNode *dest, struct userNode *src, con
     int res;
     va_list ap;
 
-    if (IsLocal(dest)) return 0;
+    if (IsLocal(dest) && !IsDummy(dest)) return 0;
     va_start(ap, format);
     res = vsend_message(dest->nick, src, dest->handle_info, msg_type, NULL, format, ap);
     va_end(ap);
index c135a00fe849561c7074b4e87c91573da0d74924..d2edc2a3b48629db744d980300835d897631729c 100644 (file)
@@ -114,14 +114,17 @@ is_valid_nick(const char *nick) {
 struct userNode *
 AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *userinfo, time_t timestamp, irc_in_addr_t realip, const char *stamp) {
     struct userNode *uNode, *oldUser;
-    unsigned int nn;
+    unsigned int nn, dummy;
 
     if (!uplink) {
         log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): server does not exist!", uplink, nick);
         return NULL;
     }
 
-    if (!is_valid_nick(nick)) {
+    dummy = modes && modes[0] == '*';
+    if (dummy) {
+        ++modes;
+    } else if (!is_valid_nick(nick)) {
         log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): invalid nickname detected.", uplink, nick);
         return NULL;
     }
@@ -162,6 +165,7 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char *
     }
 
     mod_usermode(uNode, modes);
+    if (dummy) uNode->modes |= FLAGS_DUMMY;
     if (stamp) call_account_func(uNode, stamp);
     if (IsLocal(uNode)) irc_user(uNode);
     for (nn=0; nn<nuf_used; nn++) {
@@ -216,6 +220,7 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char
             irc_kill(killer, user, why);
         }
     }
+    dict_remove(service_msginfo_dict, user->nick);
     modeList_clean(&user->channels);
     user->dead = 1;
     if (dead_users.size) {
@@ -238,6 +243,7 @@ void
 irc_user(struct userNode *user) {
     char modes[32];
     int modelen = 0;
+    if (!user || user->nick[0] != ' ') return;
     if (IsOper(user)) modes[modelen++] = 'o';
     if (IsInvisible(user)) modes[modelen++] = 'i';
     if (IsWallOp(user)) modes[modelen++] = 'w';
@@ -352,19 +358,49 @@ irc_squit(struct server *srv, const char *message, const char *service_message)
     }
 }
 
+static int
+deliver_to_dummy(struct userNode *source, struct userNode *dest, const char *message, int type)
+{
+    struct service_message_info *smi;
+
+    if (!dest || !IsDummy(dest) || !IsLocal(dest))
+        return 0;
+    smi = dict_find(service_msginfo_dict, dest->nick, NULL);
+    switch (type) {
+    default:
+        if (smi && smi->on_privmsg)
+        {
+            smi->on_privmsg(source, dest, message, 0);
+            return 1;
+        }
+        break;
+    case 1:
+        if (smi && smi->on_notice)
+        {
+            smi->on_notice(source, dest, message, 0);
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
 void
 irc_privmsg(struct userNode *from, const char *to, const char *message) {
-    putsock(":%s PRIVMSG %s :%s", from->nick, to, message);
+    if (!deliver_to_dummy(from, GetUserH(to), message, 1))
+        putsock(":%s PRIVMSG %s :%s", from->nick, to, message);
 }
 
 void
 irc_notice(struct userNode *from, const char *to, const char *message) {
-    putsock(":%s NOTICE %s :%s", from->nick, to, message);
+    if (!deliver_to_dummy(from, GetUserH(to), message, 0))
+        putsock(":%s NOTICE %s :%s", from->nick, to, message);
 }
 
 void
 irc_notice_user(struct userNode *from, struct userNode *to, const char *message) {
-    putsock(":%s NOTICE %s :%s", from->nick, to->nick, message);
+    if (!deliver_to_dummy(from, to, message, 0))
+        putsock(":%s NOTICE %s :%s", from->nick, to->nick, message);
 }
 
 void
index 58203239fc105b2064ab8cffeba420c2c8082c8e..bb82d450419ccff7ceaf818c08a7ec0e4a14dd2f 100644 (file)
@@ -1,5 +1,5 @@
 /* proto-p10.c - IRC protocol output
- * Copyright 2000-2004 srvx Development Team
+ * Copyright 2000-2006 srvx Development Team
  *
  * This file is part of srvx.
  *
@@ -455,7 +455,7 @@ void
 irc_user(struct userNode *user)
 {
     char b64ip[25];
-    if (!user)
+    if (!user || IsDummy(user))
         return;
     irc_p10_ntop(b64ip, &user->ip);
     if (user->modes) {
@@ -554,22 +554,48 @@ irc_wallchops(struct userNode *from, const char *to, const char *message)
     putsock("%s " P10_WALLCHOPS " %s :%s", from->numeric, to, message);
 }
 
+static int
+deliver_to_dummy(struct userNode *source, struct userNode *dest, const char *message, int type)
+{
+    unsigned int num;
+
+    if (!dest || !IsDummy(dest) || !IsLocal(dest))
+        return 0;
+    num = dest->num_local;
+    switch (type) {
+    default:
+        if ((num < num_notice_funcs) && notice_funcs[num])
+            notice_funcs[num](source, dest, message, 0);
+        break;
+    case 1:
+        if ((num < num_privmsg_funcs) && privmsg_funcs[num])
+            privmsg_funcs[num](source, dest, message, 0);
+        break;
+    }
+    return 1;
+}
+
 void
 irc_notice(struct userNode *from, const char *to, const char *message)
 {
-    putsock("%s " P10_NOTICE " %s :%s", from->numeric, to, message);
+    if (to[0] != '#' && to[0] != '$'
+        && !deliver_to_dummy(from, GetUserN(to), message, 0))
+        putsock("%s " P10_NOTICE " %s :%s", from->numeric, to, message);
 }
 
 void
 irc_notice_user(struct userNode *from, struct userNode *to, const char *message)
 {
-    putsock("%s " P10_NOTICE " %s :%s", from->numeric, to->numeric, message);
+    if (!deliver_to_dummy(from, to, message, 0))
+        putsock("%s " P10_NOTICE " %s :%s", from->numeric, to->numeric, message);
 }
 
 void
 irc_privmsg(struct userNode *from, const char *to, const char *message)
 {
-    putsock("%s " P10_PRIVMSG " %s :%s", from->numeric, to, message);
+    if (to[0] != '#' && to[0] != '$'
+        && !deliver_to_dummy(from, GetUserN(to), message, 1))
+        putsock("%s " P10_PRIVMSG " %s :%s", from->numeric, to, message);
 }
 
 void
@@ -1964,7 +1990,7 @@ static struct userNode*
 AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, time_t timestamp, const char *realip)
 {
     struct userNode *oldUser, *uNode;
-    unsigned int n, ignore_user;
+    unsigned int n, ignore_user, dummy;
 
     if ((strlen(numeric) < 3) || (strlen(numeric) > 5)) {
         log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): numeric %s wrong length!", uplink, nick, numeric);
@@ -1981,7 +2007,10 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char *
         return NULL;
     }
 
-    if (!is_valid_nick(nick)) {
+    dummy = modes && modes[0] == '*';
+    if (dummy) {
+        ++modes;
+    } else if (!is_valid_nick(nick)) {
         log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): invalid nickname detected.", uplink, nick);
         return NULL;
     }
@@ -2021,6 +2050,8 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char *
     uNode->num_local = base64toint(numeric+strlen(uNode->uplink->numeric), 3) & uNode->uplink->num_mask;
     uNode->uplink->users[uNode->num_local] = uNode;
     mod_usermode(uNode, modes);
+    if (dummy)
+        uNode->modes |= FLAGS_DUMMY;
     if (ignore_user)
         return uNode;
 
@@ -2075,6 +2106,14 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char
             irc_kill(killer, user, why);
     }
 
+    if (IsLocal(user)) {
+        unsigned int num = user->num_local;
+        if (num < num_privmsg_funcs)
+            privmsg_funcs[num] = NULL;
+        if (num < num_notice_funcs)
+            notice_funcs[num] = NULL;
+    }
+
     modeList_clean(&user->channels);
     /* We don't free them, in case we try to privmsg them or something
      * (like when a stupid oper kills themself).  We just put them onto