]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/m_xline.c
Revert all presence-related changes
[irc/rqf/shadowircd.git] / modules / m_xline.c
index 1aff1c9b51351e20ba147379cfca587f2a6d7fe7..edda41ec1ce19080795a6fe5d5f0ea4b8ecf090c 100644 (file)
@@ -70,7 +70,8 @@ struct Message unxline_msgtab = {
 mapi_clist_av1 xline_clist[] =  { &xline_msgtab, &unxline_msgtab, NULL };
 DECLARE_MODULE_AV1(xline, NULL, NULL, xline_clist, NULL, NULL, "$Revision: 3161 $");
 
-static int valid_xline(struct Client *, const char *, const char *);
+static char *escape_perm_xline(const char *);
+static int valid_xline(struct Client *, const char *, const char *, int);
 static void apply_xline(struct Client *client_p, const char *name, 
                        const char *reason, int temp_time);
 static void write_xline(struct Client *source_p, struct ConfItem *aconf);
@@ -99,6 +100,7 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char
 {
        struct ConfItem *aconf;
        const char *name;
+       char *escapedname;
        const char *reason;
        const char *target_server = NULL;
        int temp_time;
@@ -143,28 +145,46 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char
 
        reason = parv[loc];
 
+       if (temp_time == 0)
+       {
+               escapedname = escape_perm_xline(name);
+               if (strcmp(escapedname, name))
+                       sendto_one_notice(source_p, ":Changed xline from [%s] to [%s]",
+                                       name, escapedname);
+       }
+       else
+               escapedname = rb_strdup(name);
+
        if(target_server != NULL)
        {
                propagate_xline(source_p, target_server, temp_time,
-                               name, "2", reason);
+                               escapedname, "2", reason);
 
                if(!match(target_server, me.name))
+               {
+                       rb_free(escapedname);
                        return 0;
+               }
        }
        else if(rb_dlink_list_length(&cluster_conf_list) > 0)
-               cluster_xline(source_p, temp_time, name, reason);
+               cluster_xline(source_p, temp_time, escapedname, reason);
 
-       if((aconf = find_xline_mask(name)) != NULL)
+       if((aconf = find_xline_mask(escapedname)) != NULL)
        {
                sendto_one(source_p, ":%s NOTICE %s :[%s] already X-Lined by [%s] - %s",
-                          me.name, source_p->name, name, aconf->name, aconf->passwd);
+                          me.name, source_p->name, escapedname, aconf->name, aconf->passwd);
+               rb_free(escapedname);
                return 0;
        }
 
-       if(!valid_xline(source_p, name, reason))
+       if(!valid_xline(source_p, escapedname, reason, temp_time))
+       {
+               rb_free(escapedname);
                return 0;
+       }
 
-       apply_xline(source_p, name, reason, temp_time);
+       apply_xline(source_p, escapedname, reason, temp_time);
+       rb_free(escapedname);
 
        return 0;
 }
@@ -214,7 +234,7 @@ handle_remote_xline(struct Client *source_p, int temp_time,
                                (temp_time > 0) ? SHARED_TXLINE : SHARED_PXLINE))
                return;
 
-       if(!valid_xline(source_p, name, reason))
+       if(!valid_xline(source_p, name, reason, temp_time))
                return;
 
        /* already xlined */
@@ -227,15 +247,38 @@ handle_remote_xline(struct Client *source_p, int temp_time,
        apply_xline(source_p, name, reason, temp_time);
 }
 
+/* escape_perm_xline()
+ *
+ * inputs      - gecos
+ * outputs     - escaped gecos (allocated with rb_malloc())
+ * side effects - none
+ */
+static char *
+escape_perm_xline(const char *gecos)
+{
+       char *result;
+       int i, j;
+
+       result = rb_malloc(2 * strlen(gecos) + 1);
+       for (i = 0, j = 0; gecos[i] != '\0'; i++)
+       {
+               result[j++] = gecos[i];
+               if (gecos[i] == '"' && gecos[i + 1] == ',')
+                       result[j++] = '\\';
+       }
+       result[j] = '\0';
+       return result;
+}
+
 /* valid_xline()
  *
- * inputs      - client xlining, gecos, reason and whether to warn
+ * inputs      - client xlining, gecos, reason and temp time
  * outputs     -
  * side effects - checks the xline for validity, erroring if needed
  */
 static int
 valid_xline(struct Client *source_p, const char *gecos,
-           const char *reason)
+           const char *reason, int temp_time)
 {
        if(EmptyString(reason))
        {
@@ -245,6 +288,13 @@ valid_xline(struct Client *source_p, const char *gecos,
                return 0;
        }
 
+       if(temp_time == 0 && strstr(gecos, "\",") != NULL)
+       {
+               sendto_one_notice(source_p,
+                                 ":Invalid character sequence '\",' in xline, please replace with '\"\\,'");
+               return 0;
+       }
+
        if(strchr(reason, ':') != NULL)
        {
                sendto_one_notice(source_p,
@@ -326,6 +376,40 @@ write_xline(struct Client *source_p, struct ConfItem *aconf)
        char buffer[BUFSIZE * 2];
        FILE *out;
        const char *filename;
+       char *mangle_gecos;
+
+       if(strstr(aconf->name, "\\s"))
+       {
+               char *tmp = LOCAL_COPY(aconf->name);
+               char *orig = tmp;
+               char *new = tmp; 
+               while(*orig)
+               {
+                       if(*orig == '\\' && *(orig + 1) != '\0')
+                       {
+                               if(*(orig + 1) == 's')
+                               {
+                                       *new++ = ' ';
+                                       orig += 2;   
+                               }
+                               /* otherwise skip that and the escaped
+                                * character after it, so we dont mistake
+                                * \\s as \s --fl
+                                */
+                               else
+                               {   
+                                       *new++ = *orig++;
+                                       *new++ = *orig++;
+                               }
+                       }
+                       else
+                               *new++ = *orig++;
+               }
+
+               *new = '\0';
+               mangle_gecos = tmp;
+       } else
+               mangle_gecos = aconf->name;
 
        filename = ConfigFileEntry.xlinefile;
 
@@ -337,7 +421,7 @@ write_xline(struct Client *source_p, struct ConfItem *aconf)
        }
 
        rb_sprintf(buffer, "\"%s\",\"0\",\"%s\",\"%s\",%ld\n",
-                  aconf->name, aconf->passwd,
+                  mangle_gecos, aconf->passwd,
                   get_oper_name(source_p), (long) rb_current_time());
 
        if(fputs(buffer, out) == -1)