]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/proto-p10.c
Changed the wording and format of CSMSG_ADDUSER_PENDING
[irc/evilnet/x3.git] / src / proto-p10.c
index 3074fadcdb3a31c607a3a9199d2ed09905efb7b3..0cb26091b7b7ce5a65caff3ffab2faee4652ed7e 100644 (file)
@@ -85,6 +85,7 @@
 #define CMD_RESTART             "RESTART"
 #define CMD_RPING               "RPING"
 #define CMD_RPONG               "RPONG"
+#define CMD_SASL                "SASL"
 #define CMD_SERVER              "SERVER"
 #define CMD_SERVLIST            "SERVLIST"
 #define CMD_SERVSET             "SERVSET"
 #define TOK_RESTART             "RESTART"
 #define TOK_RPING               "RI"
 #define TOK_RPONG               "RO"
+#define TOK_SASL                "SASL"
 #define TOK_SERVER              "S"
 #define TOK_SERVLIST            "SERVSET"
 #define TOK_SERVSET             "SERVSET"
 #define P10_RESTART             TYPE(RESTART)
 #define P10_RPING               TYPE(RPING)
 #define P10_RPONG               TYPE(RPONG)
+#define P10_SASL                TYPE(SASL)
 #define P10_SERVER              CMD_SERVER
 #define P10_SERVLIST            TYPE(SERVLIST)
 #define P10_SERVSET             TYPE(SERVSET)
@@ -349,8 +352,8 @@ static const char *his_servername;
 static const char *his_servercomment;
 static int extended_accounts;
 
-/* These correspond to 1 << X:      012345678901234567 */
-const char irc_user_mode_chars[] = "o iw dkgn        I";
+/* These correspond to 1 << X:      01234567890123456789012345 */
+const char irc_user_mode_chars[] = "oOiw dkgh    x  BnIX  azDRWHLq";
 
 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);
 
@@ -496,10 +499,10 @@ irc_server(struct server *srv)
 
     inttobase64(extranum, srv->num_mask, (srv->numeric[1] || (srv->num_mask >= 64*64)) ? 3 : 2);
     if (srv == self) {
-        putsock(P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " J10 %s%s +s6 :%s",
+        putsock(P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " J10 %s%s +s6o :%s",
                 srv->name, srv->hops+1, srv->boot, srv->link_time, srv->numeric, extranum, srv->description);
     } else {
-        putsock("%s " P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " %c10 %s%s +s6 :%s",
+        putsock("%s " P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " %c10 %s%s +s6o :%s",
                 self->numeric, srv->name, srv->hops+1, srv->boot, srv->link_time, (srv->self_burst ? 'J' : 'P'), srv->numeric, extranum, srv->description);
     }
 }
@@ -834,8 +837,8 @@ irc_gline(struct server *srv, struct gline *gline, int silent)
 void
 irc_shun(struct server *srv, struct shun *shun)
 {
-    putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " :<%s> %s",
-            self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, shun->issuer, shun->reason);
+    putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " " FMT_TIME_T " :<%s> %s",
+            self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, now, shun->issuer, shun->reason);
 }
 
 void
@@ -850,13 +853,13 @@ irc_settime(const char *srv_name_mask, time_t new_time)
 void
 irc_ungline(const char *mask)
 {
-    putsock("%s " P10_GLINE " * -%s", self->numeric, mask);
+    putsock("%s " P10_GLINE " * -%s " FMT_TIME_T, self->numeric, mask, now);
 }
 
 void
 irc_unshun(const char *mask)
 {
-    putsock("%s " P10_SHUN " * -%s", self->numeric, mask);
+    putsock("%s " P10_SHUN " * -%s " FMT_TIME_T, self->numeric, mask, now);
 }
 
 void
@@ -906,6 +909,10 @@ irc_burst(struct chanNode *chan)
         if ((n+1)<chan->members.used)
             burst_line[pos++] = ',';
     }
+
+    if (len > 0 && (chan->banlist.used > 0 || chan->exemptlist.used > 0))
+        burst_line[pos++] = ' ';
+
     if (chan->banlist.used) {
         /* dump the bans */
         first_ban = 1;
@@ -931,13 +938,18 @@ irc_burst(struct chanNode *chan)
             }
         }
     }
+
     if (chan->exemptlist.used) {
         /* dump the exempts */
         first_exempt = 1;
 
         for (n=0; n<chan->exemptlist.used; ) {
             if (first_exempt && (pos < 500)) {
-                burst_line[pos++] = ' ';
+                if (chan->banlist.used < 1) {
+                    burst_line[pos++] = ':';
+                    burst_line[pos++] = '%';
+                    burst_line[pos++] = ' ';
+                }
                 burst_line[pos++] = '~';
                 burst_line[pos++] = ' ';
             }
@@ -1094,23 +1106,27 @@ void
 irc_topic(struct userNode *service, struct userNode *who, struct chanNode *what, const char *topic)
 {
 
-   int type = 4, host_in_topic = 0, hasident = 0;
-   const char *hstr, *tstr;
+   int type = 4, host_in_topic = 0, hasident = 0, hhtype = 0;
+   const char *hstr, *tstr, *hhstr, *htstr;
    char *host, *hostmask;
    char shost[MAXLEN];
    char sident[MAXLEN];
 
    tstr = conf_get_data("server/type", RECDB_QSTRING);
    hstr = conf_get_data("server/host_in_topic", RECDB_QSTRING);
+   hhstr = conf_get_data("server/hidden_host", RECDB_QSTRING);
+   htstr = conf_get_data("server/hidden_host_type", RECDB_QSTRING);
    if(tstr)
      type = atoi(tstr);
    else
      type = 4;/* default to 040 style topics */
+   if (htstr)
+     hhtype = atoi(htstr);
 
    if (hstr) {
-      if (IsFakeHost(who))
+      if (IsHiddenHost(who) && IsFakeHost(who))
           safestrncpy(shost, who->fakehost, sizeof(shost));
-      else if (IsSetHost(who)) {
+      else if (IsHiddenHost(who) && IsSetHost(who)) {
           hostmask = strdup(who->sethost);
           if ((host = (strrchr(hostmask, '@')))) {
               hasident = 1;
@@ -1124,6 +1140,10 @@ irc_topic(struct userNode *service, struct userNode *who, struct chanNode *what,
               safestrncpy(sident, who->ident, sizeof(shost));
 
           safestrncpy(shost, host, sizeof(shost));
+      } else if (IsHiddenHost(who) && ((hhtype == 1) || (hhtype == 3)) && who->handle_info && hhstr) {
+          snprintf(shost, sizeof(shost), "%s.%s", who->handle_info->handle, hhstr);
+      } else if (IsHiddenHost(who) && ((hhtype == 2) || (hhtype == 3)) && who->crypthost[0]) {
+          safestrncpy(shost, who->crypthost, sizeof(shost));
       } else
           safestrncpy(shost, who->hostname, sizeof(shost));
 
@@ -1161,6 +1181,34 @@ void
 irc_mark(struct userNode *user, char *mark)
 {
     char *host = user->hostname;
+    int type = 4;
+    const char *tstr = NULL;
+    unsigned int ii = 0;
+    int markfound = 0;
+
+    tstr = conf_get_data("server/type", RECDB_QSTRING);
+    if(tstr)
+        type = atoi(tstr);
+    else
+        type = 4;
+
+    if (user->marks)
+        for (ii=0; ii<user->marks->used; ii++)
+            if (!irccasecmp(user->marks->list[ii], mark))
+                markfound = 1;
+
+    if (!markfound)
+    {
+        if (!user->marks)
+            user->marks = alloc_string_list(1);
+        string_list_append(user->marks, strdup(mark));
+    }
+
+    if (type >= 9)
+    {
+        putsock("%s " CMD_MARK " %s MARK %s", self->numeric, user->nick, mark);
+        return;
+    }
 
     /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
     if(user->mark)
@@ -1208,6 +1256,12 @@ void irc_sno(unsigned int mask, char const* format, ...) {
     putsock("%s " CMD_SNO " %d :%s", self->numeric, mask, buffer);
 }
 
+void
+irc_sasl(struct server* dest, const char *identifier, const char *subcmd, const char *data)
+{
+    putsock("%s " P10_SASL " %s %s %s %s", self->numeric, dest->numeric, identifier, subcmd, data);
+}
+
 static void send_burst(void);
 
 static void
@@ -1426,6 +1480,22 @@ static CMD_FUNC(cmd_rping)
     return 1;
 }
 
+static CMD_FUNC(cmd_sasl)
+{
+    struct server *serv;
+
+    if (argc < 5)
+        return 0;
+
+    serv = GetServerH(origin);
+    if (!serv)
+      return 0;
+
+    call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[5] : NULL));
+
+    return 1;
+}
+
 static CMD_FUNC(cmd_ping)
 {
     struct server *srv;
@@ -1801,7 +1871,9 @@ static CMD_FUNC(cmd_burst)
     struct modeNode *mNode;
     long mode;
     int oplevel = -1;
+    int type = 0;
     char *user, *end, sep;
+    char *tstr;
     time_t in_timestamp;
     char* parm = NULL;
 
@@ -1809,6 +1881,11 @@ static CMD_FUNC(cmd_burst)
         return 0;
     modes[0] = 0;
 
+    tstr = conf_get_data("server/type", RECDB_QSTRING);
+    if(tstr) {
+        type = atoi(tstr);
+    }
+
     exemptlist[0] = 0;
     banlist[0] = 0;
 
@@ -1819,7 +1896,7 @@ static CMD_FUNC(cmd_burst)
             int n_modes;
             for (pos=argv[next], n_modes = 1; *pos; pos++)
                 if ((*pos == 'k') || (*pos == 'l') || (*pos == 'A')
-                    || (*pos == 'U'))
+                    || (*pos == 'U') || ((type > 7) && (*pos == 'L')))
                     n_modes++;
             if (next + n_modes > argc)
                 n_modes = argc - next;
@@ -1828,24 +1905,14 @@ static CMD_FUNC(cmd_burst)
             break;
         }
         case '%': {
+            ctype = 1;
             for(parm = mysep(&argv[next], " "); /* parm = first param */
                   parm;   /* While param is not null */
                   parm = mysep(&argv[next], " ")  /* parm = next param */
                )
             {
-              switch (parm[0]) {
-                case '%': {
-                  ctype = 1;
-                  break;
-                }
-                case '~': {
-                  ctype = 2;
-                  break;
-                }
-                default: {
-                  break;
-                }
-              }
+              if (0 == strcmp("~", parm))
+                ctype = 2;
               if (ctype == 1) {
                 if (bcheck == 0) {
                   /* strip % char off start of very first ban */
@@ -1939,25 +2006,47 @@ static CMD_FUNC(cmd_burst)
  */
 static CMD_FUNC(cmd_mark)
 {
+    const char *tstr;
+    int type = 4;
     struct userNode *target;
     /* 
      * log_module(MAIN_LOG, LOG_ERROR, "DEBUG: mark, user %s, type %s, arg %s", argv[1], argv[2], argv[3]);
      */
 
+    tstr = conf_get_data("server/type", RECDB_QSTRING);
+    if(tstr)
+       type = atoi(tstr);
+    else
+       type = 4;/* default to 040 style topics */
+
     if(argc < 4)
         return 0;
     if(!strcasecmp(argv[2], "DNSBL")) {
         /* DNSBL <modes> */
         return 1;
     }
-    else if(!strcasecmp(argv[2], "DNSBL_DATA")) {
+    else if(!strcasecmp(argv[2], "DNSBL_DATA") || !strcasecmp(argv[2], "MARK")) {
+        int markfound = 0;
+        unsigned int ii = 0;
         /* DNSBL_DATA name */
         target = GetUserH(argv[1]);
         if(!target) {
             log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose dnsbl mark is changing.", argv[1]);
             return 0;
         }
-        target->mark = strdup(argv[3]);
+        if (type >= 9) {
+            if (target->marks)
+                for (ii=0; ii<target->marks->used; ii++)
+                    if (!irccasecmp(target->marks->list[ii], argv[3]))
+                         markfound = 1;
+            if (!markfound)
+            {
+                if (!target->marks)
+                    target->marks = alloc_string_list(1);
+                string_list_append(target->marks, strdup(argv[3]));
+            }
+        } else
+            target->mark = strdup(argv[3]);
         return 1;
         
     }
@@ -2234,9 +2323,11 @@ static CMD_FUNC(cmd_kill)
          * Ghost response to a KILL we sent out earlier.  So we only
          * whine if the target is local.
          */
-        if (!strncmp(argv[1], self->numeric, strlen(self->numeric)))
+        if (!strncmp(argv[1], self->numeric, strlen(self->numeric))) {
             log_module(MAIN_LOG, LOG_ERROR, "Unable to find kill victim %s", argv[1]);
-        return 0;
+            return 0;
+        }
+        return 1;
     }
 
     if (IsLocal(user) && IsService(user)) {
@@ -2666,6 +2757,9 @@ init_parse(void)
     dict_insert(irc_func_dict, CMD_RPONG, cmd_dummy);
     dict_insert(irc_func_dict, TOK_RPONG, cmd_dummy);
 
+    dict_insert(irc_func_dict, CMD_SASL, cmd_sasl);
+    dict_insert(irc_func_dict, TOK_SASL, cmd_sasl);
+
     /* In P10, DESTRUCT doesn't do anything except be broadcast to servers.
      * Apparently to obliterate channels from any servers that think they
      * exist?
@@ -2983,7 +3077,7 @@ AddLocalUser(const char *nick, const char *ident, const char *hostname, const ch
     if (!hostname)
         hostname = self->name;
     make_numeric(self, local_num, numeric);
-    return AddUser(self, nick, ident, hostname, modes, numeric, desc, now, "AAAAAA");
+    return AddUser(self, nick, ident, hostname, modes, numeric, desc, timestamp, "AAAAAA");
 }
 
 struct userNode *
@@ -3198,6 +3292,8 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char
         free(user->mark);
         user->mark = NULL;
     }
+    free_string_list(user->marks);
+    user->marks = NULL;
 
     /* clean up geoip data if any */
     if(user->country_code) free(user->country_code);
@@ -3323,6 +3419,14 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
                 assign_fakehost(user, host, 0);
             }
             break;
+        case 'a': do_user_mode(FLAGS_ADMIN); break;
+        case 'z': do_user_mode(FLAGS_SSL); break;
+        case 'D': do_user_mode(FLAGS_PRIVDEAF); break;
+        case 'R': do_user_mode(FLAGS_ACCOUNTONLY); break;
+        case 'W': do_user_mode(FLAGS_WHOIS); break;
+        case 'H': do_user_mode(FLAGS_HIDEOPER); break;
+        case 'L': do_user_mode(FLAGS_NOLINK); break;
+        case 'q': do_user_mode(FLAGS_COMMONCHANSONLY); break;
        }
 #undef do_user_mode
     }
@@ -3443,7 +3547,8 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         case 'A':
             if (add) {
                 if ((in_arg >= argc)
-                    || keyncpy(change->new_upass, modes[in_arg++], sizeof(change->new_upass)))
+                    || keyncpy(change->new_apass, modes[in_arg++], sizeof(change->new_apass)))
+                    goto error;
                 change->modes_set |= MODE_APASS;
             } else {
                 change->modes_clear |= MODE_APASS;
@@ -3620,6 +3725,7 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(NOQUITMSGS, 'Q');
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
+        DO_MODE_CHAR(ADMINSONLY, 'a');
         DO_MODE_CHAR(REGISTERED, 'z');
         DO_MODE_CHAR(SSLONLY, 'Z');
        DO_MODE_CHAR(HIDEMODE, 'L');
@@ -3676,6 +3782,7 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(NOQUITMSGS, 'Q');
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
+        DO_MODE_CHAR(ADMINSONLY, 'a');
         DO_MODE_CHAR(REGISTERED, 'z');
         DO_MODE_CHAR(SSLONLY, 'Z');
        DO_MODE_CHAR(HIDEMODE, 'L');
@@ -3751,6 +3858,7 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(NOQUITMSGS, 'Q');
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
+        DO_MODE_CHAR(ADMINSONLY, 'a');
         DO_MODE_CHAR(REGISTERED, 'z');
         DO_MODE_CHAR(SSLONLY, 'Z');
        DO_MODE_CHAR(HIDEMODE, 'L');
@@ -3775,62 +3883,23 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(NOQUITMSGS, 'Q');
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
+        DO_MODE_CHAR(ADMINSONLY, 'a');
         DO_MODE_CHAR(REGISTERED, 'z');
         DO_MODE_CHAR(SSLONLY, 'Z');
        DO_MODE_CHAR(HIDEMODE, 'L');
-#undef DO_MODE_CHAR
-        switch (change->modes_set & (MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS)) {
-        /* Doing this implementation has been a pain in the arse, I hope I didn't forget a possible combination */
-        case MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS:
-            used += sprintf(outbuff+used, "lkAU %d %s %s %s", change->new_limit, change->new_key,change->new_apass, change->new_upass);
-            break;
-
-        case MODE_KEY|MODE_LIMIT|MODE_APASS:
-            used += sprintf(outbuff+used, "lkA %d %s %s", change->new_limit, change->new_key, change->new_apass);
-            break;
-        case MODE_KEY|MODE_LIMIT|MODE_UPASS:
-            used += sprintf(outbuff+used, "lkU %d %s %s", change->new_limit, change->new_key, change->new_upass);
-            break;
-        case MODE_KEY|MODE_APASS|MODE_UPASS:
-            used += sprintf(outbuff+used, "kAU %s %s %s", change->new_key, change->new_apass, change->new_upass);
-            break;
 
-        case MODE_KEY|MODE_APASS:
-            used += sprintf(outbuff+used, "kA %s %s", change->new_key, change->new_apass);
-            break;
-        case MODE_KEY|MODE_UPASS:
-            used += sprintf(outbuff+used, "kU %s %s", change->new_key, change->new_upass);
-            break;
-        case MODE_KEY|MODE_LIMIT:
-            used += sprintf(outbuff+used, "lk %d %s", change->new_limit, change->new_key);
-            break;
-
-        case MODE_LIMIT|MODE_UPASS:
-            used += sprintf(outbuff+used, "lU %d %s", change->new_limit, change->new_upass);
-            break;
-        case MODE_LIMIT|MODE_APASS:
-            used += sprintf(outbuff+used, "lA %d %s", change->new_limit, change->new_apass);
-            break;
-        case MODE_APASS|MODE_UPASS:
-            used += sprintf(outbuff+used, "AU %s %s", change->new_apass, change->new_upass);
-
-        case MODE_LIMIT|MODE_APASS|MODE_UPASS:
-            used += sprintf(outbuff+used, "lAU %d %s %s", change->new_limit, change->new_apass, change->new_upass);
-            break;
+       DO_MODE_CHAR(KEY, 'k');
+       DO_MODE_CHAR(LIMIT, 'l');
+       DO_MODE_CHAR(APASS, 'A');
+       DO_MODE_CHAR(UPASS, 'U');
+#undef DO_MODE_CHAR
 
-        case MODE_APASS:
-            used += sprintf(outbuff+used, "A %s", change->new_apass);
-            break;
-        case MODE_UPASS:
-            used += sprintf(outbuff+used, "U %s", change->new_upass);
-            break;
-        case MODE_KEY:
-            used += sprintf(outbuff+used, "k %s", change->new_key);
-            break;
-        case MODE_LIMIT:
-            used += sprintf(outbuff+used, "l %d", change->new_limit);
-            break;
-        }
+#define DO_MODE_PARM(BIT, PARM) if (change->modes_set & MODE_##BIT) used += sprintf(outbuff+used, " %s", PARM);
+       DO_MODE_PARM(KEY, change->new_key);
+       if (change->modes_set & MODE_LIMIT) used += sprintf(outbuff+used, " %d", change->new_limit);
+       DO_MODE_PARM(APASS, change->new_apass);
+       DO_MODE_PARM(UPASS, change->new_upass);
+#undef DO_MODE_PARM
     }
     outbuff[used] = 0;
     return outbuff;