/* proto-bahamut.c - IRC protocol output
- * Copyright 2000-2004 srvx Development Team
+ * Copyright 2000-2006 srvx Development Team
*
* This file is part of srvx.
*
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;
}
}
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++) {
}
struct userNode *
-AddService(const char *nick, const char *modes, const char *desc, const char *hostname) {
+AddLocalUser(const char *nick, const char *ident, const char *hostname, const char *desc, const char *modes)
+{
time_t timestamp = now;
struct userNode *old_user = GetUserH(nick);
static const irc_in_addr_t ipaddr;
+
+ if (!modes)
+ modes = "+oikr";
if (old_user) {
if (IsLocal(old_user))
return old_user;
}
if (!hostname)
hostname = self->name;
- return AddUser(self, nick, nick, hostname, modes ? modes : "+oikr", desc, timestamp, ipaddr, 0);
-}
-
-struct userNode *
-AddClone(const char *nick, const char *ident, const char *hostname, const char *desc) {
- time_t timestamp = now;
- struct userNode *old_user = GetUserH(nick);
- static const irc_in_addr_t ipaddr;
- if (old_user) {
- if (IsLocal(old_user))
- return old_user;
- timestamp = old_user->timestamp - 1;
- }
- return AddUser(self, nick, ident, hostname, "+ir", desc, timestamp, ipaddr, 0);
+ return AddUser(self, nick, ident, hostname, modes, desc, timestamp, ipaddr, 0);
}
void
unsigned int nn;
for (nn=user->channels.used; nn>0;) {
- DelChannelUser(user, user->channels.list[--nn]->channel, false, 0);
+ DelChannelUser(user, user->channels.list[--nn]->channel, NULL, false);
}
for (nn=duf_used; nn>0; ) duf_list[--nn](user, killer, why);
user->uplink->clients--;
irc_kill(killer, user, why);
}
}
+ dict_remove(service_msginfo_dict, user->nick);
modeList_clean(&user->channels);
user->dead = 1;
if (dead_users.size) {
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';
if (IsService(user)) modes[modelen++] = 'k';
- if (IsServNotice(user)) modes[modelen++] = 's';
if (IsDeaf(user)) modes[modelen++] = 'd';
if (IsReggedNick(user)) modes[modelen++] = 'r';
if (IsGlobal(user)) modes[modelen++] = 'g';
}
}
+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
return 1;
}
-static CMD_FUNC(cmd_part) {
- if (argc < 2) return 0;
- parse_foreach(argv[1], part_helper, NULL, NULL, NULL, GetUserH(origin));
- return 1;
-}
-
static CMD_FUNC(cmd_away) {
struct userNode *un;
info->on_privmsg = handler;
}
+void
+unreg_privmsg_func(struct userNode *user) {
+ struct service_message_info *info;
+ info = dict_find(service_msginfo_dict, user->nick, NULL);
+ if (info) {
+ info->on_privmsg = NULL;
+ if (info->on_notice == NULL) {
+ dict_remove(service_msginfo_dict, user->nick);
+ }
+ }
+}
+
void
reg_notice_func(struct userNode *user, privmsg_func_t handler) {
struct service_message_info *info = dict_find(service_msginfo_dict, user->nick, NULL);
info->on_notice = handler;
}
+void
+unreg_notice_func(struct userNode *user) {
+ struct service_message_info *info;
+ info = dict_find(service_msginfo_dict, user->nick, NULL);
+ if (info) {
+ info->on_notice = NULL;
+ if (info->on_privmsg == NULL) {
+ dict_remove(service_msginfo_dict, user->nick);
+ }
+ }
+}
+
void
reg_oper_func(oper_func_t handler)
{
userList_remove(&curr_opers, user);
}
break;
- case 'O': do_user_mode(FLAGS_LOCOP); break;
case 'i': do_user_mode(FLAGS_INVISIBLE);
if (add) invis_clients++; else invis_clients--;
break;
case 'w': do_user_mode(FLAGS_WALLOP); break;
- case 's': do_user_mode(FLAGS_SERVNOTICE); break;
case 'd': do_user_mode(FLAGS_DEAF); break;
case 'r': do_user_mode(FLAGS_REGNICK); break;
case 'k': do_user_mode(FLAGS_SERVICE); break;
case 'g': do_user_mode(FLAGS_GLOBAL); break;
- case 'h': do_user_mode(FLAGS_HELPER); break;
}
#undef do_user_mode
}