Merge branch 'development'
[NeonServV5.git] / src / tools.c
index 43f27cd35ac052148a7c39247aaeea4dbf78a0b2..0232671c5050767aca56177a5bf5a7731ce0449d 100644 (file)
@@ -1,8 +1,26 @@
+/* tools.c - NeonServ v5.6
+ * Copyright (C) 2011-2012  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
 #include "tools.h"
 #include "UserNode.h"
 #include "ChanNode.h"
 #include "lang.h"
 #include "ClientSocket.h"
+#include "IPNode.h"
+#include "log.h"
 
 static const struct default_language_entry msgtab[] = {
     {"TIME_MASK_2_ITEMS", "%s and %s"}, /* {ARGS: "2 days", "1 hour"} */
@@ -106,9 +124,9 @@ struct Table *table_init(int width, int length, int flags) {
     table->length = length;
     table->width = width;
     table->flags = flags;
-    table->col_flags = calloc(length, sizeof(int));
+    table->col_flags = calloc(width, sizeof(int));
     table->entrys = 0;
-    table->maxwidth = calloc(length, sizeof(int));
+    table->maxwidth = calloc(width, sizeof(int));
     table->table_lines = NULL;
     return table;
 }
@@ -164,7 +182,7 @@ int table_set_bold(struct Table *table, int collum, int bold) {
 }
 
 char **table_end(struct Table *table) {
-    int row, col, tablewidth = 0, pos,i;
+    int row, col, tablewidth = 0, pos,i,j,k;
     if(!table->entrys) return NULL;
     for(col = 0; col < table->width; col++) {
         tablewidth += table->maxwidth[col]+1;
@@ -179,17 +197,25 @@ char **table_end(struct Table *table) {
             if(!(table->col_flags[col] & TABLE_FLAG_COL_CONTENTS)) continue;
             if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
                 table->table_lines[row][pos++] = '\002';
+            i = 0;
+            j = 0;
             if(table->contents[row][col]) {
-                for(i = 0; i < strlen(table->contents[row][col]); i++) {
+                for(; i < strlen(table->contents[row][col]); i++) {
                     table->table_lines[row][pos++] = table->contents[row][col][i];
+                    if(table->contents[row][col][i] == '\002') j++;
+                    else if(table->contents[row][col][i] == '\003') {
+                        j++;
+                        for(k = 1; k <= 2; k++) {
+                            if(isdigit(table->contents[row][col][i+k]))
+                                j++;
+                            else 
+                                break;
+                        }
+                    }
                 }
-            } else {
-                i = 4;
-                table->table_lines[row][pos++] = 'N';
-                table->table_lines[row][pos++] = 'U';
-                table->table_lines[row][pos++] = 'L';
-                table->table_lines[row][pos++] = 'L';
-            }
+            } else if(table->col_flags[col] & TABLE_FLAG_COL_SKIP_NULL)
+                continue;
+            i -= j;
             if(col < table->width-1) {
                 for(;i < table->maxwidth[col]; i++) {
                     table->table_lines[row][pos++] = ' ';
@@ -350,10 +376,20 @@ int strToTime(struct UserNode *user, char *str) {
     return total_time;
 }
 
+int getCurrentSecondsOfDay() {
+    time_t now = time(0);
+    struct tm *timeofday = localtime(&now);
+    int seconds = 0;
+    seconds += timeofday->tm_hour * 3600;
+    seconds += timeofday->tm_min * 60;
+    seconds += timeofday->tm_sec;
+    return seconds;
+}
+
 struct ModeBuffer* initModeBuffer(struct ClientSocket *client, struct ChanNode *chan) {
     struct ModeBuffer *modeBuf = malloc(sizeof(*modeBuf));
     if(!modeBuf) {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return NULL;
     }
     modeBuf->client = client;
@@ -383,6 +419,7 @@ void flushModeBuffer(struct ModeBuffer *modeBuf) {
     char modeStr[MAXMODES+3];
     int modePos = 0;
     char paramStr[MAXLEN];
+    *paramStr = '\0';
     int paramPos = 0;
     int i;
     if(modeBuf->addCount) {
@@ -391,6 +428,8 @@ void flushModeBuffer(struct ModeBuffer *modeBuf) {
             modeStr[modePos++] = modeBuf->addModes[i];
             if(modeBuf->addModesParams[i]) {
                 paramPos += sprintf(paramStr + paramPos, " %s", modeBuf->addModesParams[i]);
+                free(modeBuf->addModesParams[i]);
+                modeBuf->addModesParams[i] = NULL;
             }
         }
         modeBuf->addCount = 0;
@@ -401,6 +440,8 @@ void flushModeBuffer(struct ModeBuffer *modeBuf) {
             modeStr[modePos++] = modeBuf->delModes[i];
             if(modeBuf->delModesParams[i]) {
                 paramPos += sprintf(paramStr + paramPos, " %s", modeBuf->delModesParams[i]);
+                free(modeBuf->delModesParams[i]);
+                modeBuf->delModesParams[i] = NULL;
             }
         }
         modeBuf->delCount = 0;
@@ -463,7 +504,7 @@ char* make_banmask(char *input, char* buffer) {
         ident = input;
         *p = '\0';
         host = p+1;
-    } else if((p = strstr(input, "."))) {
+    } else if((p = strstr(input, ".")) || (p = strstr(input, ":"))) {
         host = input;
     } else if(*input == '*' && input[1] != '\0' && !strstr(input+1, "*")) {
         //AUTH MASK
@@ -492,7 +533,7 @@ int isFakeHost(char *host) {
     char *p1, *p2 = host;
     
     //find the last dot to identify if the hostmask is a fake host
-    while((p1 = strstr(p2, "."))) {
+    while((p1 = strchr(p2, '.'))) {
         p2 = p1 + 1;
     }
     //TLD database: http://www.iana.org/domains/root/db/
@@ -501,6 +542,74 @@ int isFakeHost(char *host) {
     return (strlen(p2+1) > 4);
 }
 
+int mask_match(char *mask, struct UserNode *user) {
+    char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+    char matchmask[strlen(mask)+3];
+    strcpy(matchmask, mask);
+    char *host = strchr(mask, '@');
+    if(host) {
+        struct IPNode *ip = createIPNode(host);
+        int bits = (ip->flags & IPNODE_IS_IPV6 ? 128 : 32);
+        if((host = strchr(host, '/'))) {
+            bits = atoi(host+1);
+        }
+        if(ip && user->ip&& !ipmatch(user->ip, ip, bits)) {
+            host[1] = '*';
+            host[2] = '\0';
+        }
+    }
+    sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
+    return match(matchmask, usermask);
+}
+
+static unsigned long crc_table[256];
+
+static void crc32_init() {
+    unsigned long crc;
+    int i, j;
+    for(i = 0; i < 256; i++) {
+        crc = i;
+        for(j = 8; j > 0; j--) {
+            if(crc & 1)
+                               crc = (crc >> 1) ^ 0xEDB88320L;
+            else
+                crc >>= 1;
+        }
+        crc_table[i] = crc;
+    }
+}
+
+unsigned long crc32(const char *text) {
+    register unsigned long crc = 0xFFFFFFFF;
+    unsigned int c, i = 0;
+    while((c = (unsigned int)text[i++]) != 0)
+        crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_table[(crc^c) & 0xFF];
+    return (crc^0xFFFFFFFF);
+}
+
+int stricmp (const char *s1, const char *s2) {
+    return stricmplen(s1, s2, -1);
+}
+
+int stricmplen(const char *s1, const char *s2, int len) {
+    if (s1 == NULL) 
+        return (s2 == NULL ? 0 : -(*s2));
+    if (s2 == NULL) 
+        return *s1;
+    char c1, c2;
+    int i = 0;
+    while ((c1 = tolower(*s1)) == (c2 = tolower(*s2))) {
+        if (*s1 == '\0') 
+            break;
+        i++;
+        s1++; 
+        s2++;
+        if(len != -1 && i == len) break;
+    }
+    return c1 - c2;
+}
+
 void init_tools() {
     register_default_language_table(msgtab);
+    crc32_init();
 }