fixed memory leak in tools.c and fixed allocation size of ChanUser entries
[NeonServV5.git] / src / modcmd.c
index 78b04c810df89b08c37f82d5a986a9d93fc21a2b..629435d9a672e2f64e359bd9164fe2fbdd7d0265 100644 (file)
@@ -159,7 +159,7 @@ static struct cmd_binding *modcmd_linker_command(struct ClientSocket *client, st
                 break;
         }
         *args_ptr = args;
-        if(cbind->func->func == modcmd_linker) {
+        if(cbind && cbind->func->func == modcmd_linker) {
             return modcmd_linker_command(client, user, cbind, bind_index, args_ptr);
         }
         return cbind;
@@ -170,6 +170,7 @@ static struct cmd_binding *modcmd_linker_command(struct ClientSocket *client, st
         int subcompos = 0;
         for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) {
             if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && stricmplen(cbind->cmd, command, commandlen) == 0) {
+                if(strstr(cbind->cmd + commandlen, " ")) continue; //ignore if there is another space in the command (sub-sub-command :D)
                 subcompos += sprintf(subcommands + subcompos, (subcompos ? ", %s" : "%s"), cbind->cmd + commandlen);
             }
         }
@@ -455,6 +456,7 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
             str_b = cbind->channel_access;
         access_list[0] = '\0';
         if(str_b) {
+            struct ChanUser *chanuser = getChanUser(user, chan);
             str_c = strdup(str_b);
             str_b = str_c;
             while((str_a = str_b)) {
@@ -463,6 +465,15 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
                     *str_b = '\0';
                     str_b++;
                 }
+                if(*str_a == '@' || *str_a == '+') {
+                    //privs can override this access requirement
+                    int priv = 0;
+                    if(*str_a == '@') priv = CHANUSERFLAG_OPPED;
+                    else if(*str_a == '%') priv = CHANUSERFLAG_HALFOPPED;
+                    else if(*str_a == '+') priv = CHANUSERFLAG_VOICED;
+                    if(chanuser && (chanuser->flags & priv)) continue;
+                    str_a++;
+                }
                 if(*str_a == '#') {
                     str_a++;
                     access_pos += sprintf(access_list+access_pos, ", `%s`", str_a);