}
struct userNode *
-AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *userinfo, time_t timestamp, struct in_addr realip, const char *stamp) {
+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;
}
struct userNode *
-AddService(const char *nick, const char *desc) {
+AddService(const char *nick, const char *modes, const char *desc, const char *hostname) {
time_t timestamp = now;
struct userNode *old_user = GetUserH(nick);
- struct in_addr ipaddr = { INADDR_LOOPBACK };
+ 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, nick, self->name, "+oikr", desc, timestamp, ipaddr, 0);
+ 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);
- struct in_addr ipaddr = { INADDR_LOOPBACK };
+ static const irc_in_addr_t ipaddr;
if (old_user) {
if (IsLocal(old_user))
return old_user;
modes[modelen] = 0;
putsock("NICK %s %d "FMT_TIME_T" +%s %s %s %s %d %u :%s",
user->nick, user->uplink->hops+2, user->timestamp, modes,
- user->ident, user->hostname, user->uplink->name, 0, ntohl(user->ip.s_addr), user->info);
+ user->ident, user->hostname, user->uplink->name, 0, ntohl(user->ip.in6_32[3]), user->info);
}
void
}
}
+void
+irc_fakehost(UNUSED_ARG(struct userNode *user), UNUSED_ARG(const char *host))
+{
+ /* not supported in bahamut */
+}
+
void
irc_regnick(struct userNode *user)
{
putsock("SVINFO 3 3 0 :"FMT_TIME_T, now);
}
-void
-irc_burst() {
- putsock("BURST");
-}
-
void
irc_introduce(const char *passwd) {
extern time_t burst_begin;
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);
+}
+
void
irc_wallchops(UNUSED_ARG(struct userNode *from), UNUSED_ARG(const char *to), UNUSED_ARG(const char *message)) {
}
return 1;
}
+static CMD_FUNC(cmd_whois) {
+ struct userNode *from;
+ struct userNode *who;
+
+ if (argc < 3)
+ return 0;
+ if (!(from = GetUserH(origin))) {
+ log_module(MAIN_LOG, LOG_ERROR, "Could not find WHOIS origin user %s", origin);
+ return 0;
+ }
+ if(!(who = GetUserH(argv[2]))) {
+ irc_numeric(from, ERR_NOSUCHNICK, "%s@%s :No such nick", argv[2], self->name);
+ return 1;
+ }
+ if (IsHiddenHost(who) && !IsOper(from)) {
+ /* Just stay quiet. */
+ return 1;
+ }
+ irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info);
+#ifdef WITH_PROTOCOL_P10
+ if (his_servername && his_servercomment)
+ irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, his_servername, his_servercomment);
+ else
+#endif
+ irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, who->uplink->name, who->uplink->description);
+
+ if (IsOper(who)) {
+ irc_numeric(from, RPL_WHOISOPERATOR, "%s :is a megalomaniacal power hungry tyrant", who->nick);
+ }
+ irc_numeric(from, RPL_ENDOFWHOIS, "%s :End of /WHOIS list", who->nick);
+ return 1;
+}
+
static CMD_FUNC(cmd_capab) {
static const struct {
const char *name;
AddServer(GetServerH(origin), argv[1], atoi(argv[2]), 0, now, 0, argv[3]);
} else {
self->uplink = AddServer(self, argv[1], atoi(argv[2]), 0, now, 0, argv[3]);
- send_burst();
}
return 1;
}
if (argc < 5) return 0;
if ((atoi(argv[1]) < 3) || (atoi(argv[2]) > 3)) return 0;
/* TODO: something with the timestamp we get from the other guy */
+ send_burst();
return 1;
}
/* new nick from a server */
char id[8];
unsigned long stamp;
- struct in_addr ip;
+ irc_in_addr_t ip;
if (argc < 10) return 0;
stamp = strtoul(argv[8], NULL, 0);
if (stamp) inttobase64(id, stamp, IDLEN);
- ip.s_addr = (argc > 10) ? atoi(argv[9]) : 0;
+ if (argc > 10)
+ ip.in6_32[3] = htonl(atoi(argv[9]));
un = AddUser(GetServerH(argv[7]), argv[1], argv[5], argv[6], argv[4], argv[argc-1], atoi(argv[3]), ip, (stamp ? id : 0));
}
return 1;
case 'p': do_chan_mode(MODE_PRIVATE); break;
case 's': do_chan_mode(MODE_SECRET); break;
case 't': do_chan_mode(MODE_TOPICLIMIT); break;
+ case 'r':
+ if (!(flags & MCP_REGISTERED)) {
+ do_chan_mode(MODE_REGISTERED);
+ } else {
+ mod_chanmode_free(change);
+ return NULL;
+ }
+ break;
#undef do_chan_mode
case 'l':
if (add) {
change->args[ch_arg].mode = MODE_BAN;
if (!add)
change->args[ch_arg].mode |= MODE_REMOVE;
- change->args[ch_arg++].hostmask = modes[in_arg++];
+ change->args[ch_arg++].u.hostmask = modes[in_arg++];
break;
case 'o': case 'v':
{
victim = GetUserH(modes[in_arg++]);
if (!victim)
continue;
- if ((change->args[ch_arg].member = GetUserMode(channel, victim)))
+ if ((change->args[ch_arg].u.member = GetUserMode(channel, victim)))
ch_arg++;
break;
}
break;
}
}
- change->argc = argc; /* in case any turned out to be ignored */
+ change->argc = ch_arg; /* in case any turned out to be ignored */
if (change->modes_set & MODE_SECRET) {
change->modes_set &= ~(MODE_PRIVATE);
change->modes_clear |= MODE_PRIVATE;
DO_MODE_CHAR(DELAYJOINS, 'D');
DO_MODE_CHAR(REGONLY, 'R');
DO_MODE_CHAR(NOCOLORS, 'c');
+ DO_MODE_CHAR(REGISTERED, 'r');
#undef DO_MODE_CHAR
if (change->modes_clear & channel->modes & MODE_KEY)
mod_chanmode_append(&chbuf, 'k', channel->key);
continue;
switch (change->args[arg].mode & ~MODE_REMOVE) {
case MODE_BAN:
- mod_chanmode_append(&chbuf, 'b', change->args[arg].hostmask);
+ mod_chanmode_append(&chbuf, 'b', change->args[arg].u.hostmask);
break;
default:
if (change->args[arg].mode & MODE_CHANOP)
- mod_chanmode_append(&chbuf, 'o', change->args[arg].member->user->nick);
+ mod_chanmode_append(&chbuf, 'o', change->args[arg].u.member->user->nick);
if (change->args[arg].mode & MODE_VOICE)
- mod_chanmode_append(&chbuf, 'v', change->args[arg].member->user->nick);
+ mod_chanmode_append(&chbuf, 'v', change->args[arg].u.member->user->nick);
break;
}
}
DO_MODE_CHAR(DELAYJOINS, 'D');
DO_MODE_CHAR(REGONLY, 'R');
DO_MODE_CHAR(NOCOLORS, 'c');
+ DO_MODE_CHAR(REGISTERED, 'r');
#undef DO_MODE_CHAR
if (change->modes_set & MODE_KEY)
mod_chanmode_append(&chbuf, 'k', change->new_key);
continue;
switch (change->args[arg].mode) {
case MODE_BAN:
- mod_chanmode_append(&chbuf, 'b', change->args[arg].hostmask);
+ mod_chanmode_append(&chbuf, 'b', change->args[arg].u.hostmask);
break;
default:
if (change->args[arg].mode & MODE_CHANOP)
- mod_chanmode_append(&chbuf, 'o', change->args[arg].member->user->nick);
+ mod_chanmode_append(&chbuf, 'o', change->args[arg].u.member->user->nick);
if (change->args[arg].mode & MODE_VOICE)
- mod_chanmode_append(&chbuf, 'v', change->args[arg].member->user->nick);
+ mod_chanmode_append(&chbuf, 'v', change->args[arg].u.member->user->nick);
break;
}
}
DO_MODE_CHAR(LIMIT, 'l');
DO_MODE_CHAR(KEY, 'k');
DO_MODE_CHAR(DELAYJOINS, 'D');
- DO_MODE_CHAR(REGONLY, '$');
+ DO_MODE_CHAR(REGONLY, 'R');
DO_MODE_CHAR(NOCOLORS, 'c');
+ DO_MODE_CHAR(REGISTERED, 'r');
#undef DO_MODE_CHAR
}
if (change->modes_set) {
DO_MODE_CHAR(DELAYJOINS, 'D');
DO_MODE_CHAR(REGONLY, 'R');
DO_MODE_CHAR(NOCOLORS, 'c');
+ DO_MODE_CHAR(REGISTERED, 'r');
#undef DO_MODE_CHAR
switch (change->modes_set & (MODE_KEY|MODE_LIMIT)) {
case MODE_KEY|MODE_LIMIT: