Add IPv6 support.
[srvx.git] / src / proto-bahamut.c
index d0828f1c0c2c86b72064750be33672a3a66f968f..4f950aee745559caf5d6fca3980248d1566ce04a 100644 (file)
@@ -112,7 +112,7 @@ 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, 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;
 
@@ -171,10 +171,10 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char *
 }
 
 struct userNode *
-AddService(const char *nick, const char *desc, const char *hostname) {
+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;
@@ -182,14 +182,14 @@ AddService(const char *nick, const char *desc, const char *hostname) {
     }
     if (!hostname)
         hostname = self->name;
-    return AddUser(self, nick, nick, hostname, "+oikr", desc, timestamp, ipaddr, 0);
+    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;
@@ -258,7 +258,7 @@ irc_user(struct userNode *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
@@ -271,6 +271,12 @@ irc_account(struct userNode *user, const char *stamp)
     }
 }
 
+void
+irc_fakehost(UNUSED_ARG(struct userNode *user), UNUSED_ARG(const char *host))
+{
+    /* not supported in bahamut */
+}
+
 void
 irc_regnick(struct userNode *user)
 {
@@ -774,12 +780,13 @@ static CMD_FUNC(cmd_nick) {
         /* 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;
@@ -1240,7 +1247,6 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
             break;
 #define do_chan_mode(FLAG) do { if (add) change->modes_set |= FLAG, change->modes_clear &= ~FLAG; else change->modes_clear |= FLAG, change->modes_set &= ~FLAG; } while(0)
         case 'R': do_chan_mode(MODE_REGONLY); break;
-        case 'r': do_chan_mode(MODE_REGISTERED); break;
         case 'D': do_chan_mode(MODE_DELAYJOINS); break;
         case 'c': do_chan_mode(MODE_NOCOLORS); break;
         case 'i': do_chan_mode(MODE_INVITEONLY); break;
@@ -1249,6 +1255,14 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         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) {
@@ -1283,7 +1297,7 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
             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':
         {
@@ -1298,7 +1312,7 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
             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;
         }
@@ -1389,13 +1403,13 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
             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;
         }
     }
@@ -1429,13 +1443,13 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
             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;
         }
     }