From e44152b845d78f9e8ad0b2ca3957d70f4ff7e5b1 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Fri, 22 Sep 2006 02:15:55 +0000 Subject: [PATCH] Add "dummy client" support. 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 | 34 +++++++++++++++++++++++++++++ src/hash.h | 2 ++ src/helpfile.c | 4 ++-- src/proto-bahamut.c | 46 ++++++++++++++++++++++++++++++++++----- src/proto-p10.c | 53 +++++++++++++++++++++++++++++++++++++++------ 5 files changed, 125 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd3963b..bbcef8f 100644 --- 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 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 patch-36 Summary: diff --git a/src/hash.h b/src/hash.h index f002126..99b4114 100644 --- a/src/hash.h +++ b/src/hash.h @@ -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) diff --git a/src/helpfile.c b/src/helpfile.c index 38a61ec..8819ebb 100644 --- a/src/helpfile.c +++ b/src/helpfile.c @@ -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); diff --git a/src/proto-bahamut.c b/src/proto-bahamut.c index c135a00..d2edc2a 100644 --- a/src/proto-bahamut.c +++ b/src/proto-bahamut.c @@ -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; nnnick); 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 diff --git a/src/proto-p10.c b/src/proto-p10.c index 5820323..bb82d45 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -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 -- 2.20.1