X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=tools.c;h=097684855d8230a66cb21819ceb9240dce68a5cb;hb=795115bf680185ae01043bd1222b78bfed8c1d87;hp=cb00985435eb4142e9b130aa908e024e93fd14d5;hpb=e882e640e4e36173bdc586ddc235fdb0d9d8e34d;p=NeonServV5.git diff --git a/tools.c b/tools.c index cb00985..0976848 100644 --- a/tools.c +++ b/tools.c @@ -1,20 +1,26 @@ #include "tools.h" #include "UserNode.h" +#include "ChanNode.h" #include "lang.h" +#include "ClientSocket.h" static const struct default_language_entry msgtab[] = { - {"TIME_MASK_2_ITEMS", "%s and %s"}, - {"TIME_MASK_3_ITEMS", "%s, %s and %s"}, - {"TIME_YEAR", "%d year"}, - {"TIME_YEARS", "%d years"}, - {"TIME_DAY", "%d day"}, - {"TIME_DAYS", "%d days"}, - {"TIME_HOUR", "%d hour"}, - {"TIME_HOURS", "%d hours"}, - {"TIME_MINUTE", "%d minute"}, - {"TIME_MINUTES", "%d minutes"}, - {"TIME_SECOND", "%d second"}, - {"TIME_SECONDS", "%d seconds"}, + {"TIME_MASK_2_ITEMS", "%s and %s"}, /* {ARGS: "2 days", "1 hour"} */ + {"TIME_MASK_3_ITEMS", "%s, %s and %s"}, /* {ARGS: "2 days", "1 hour", "20 minutes"} */ + {"TIME_YEAR", "year"}, + {"TIME_YEARS", "years"}, + {"TIME_MONTH", "month"}, + {"TIME_MONTHS", "months"}, + {"TIME_WEEK", "week"}, + {"TIME_WEEKS", "weeks"}, + {"TIME_DAY", "day"}, + {"TIME_DAYS", "days"}, + {"TIME_HOUR", "hour"}, + {"TIME_HOURS", "hours"}, + {"TIME_MINUTE", "minute"}, + {"TIME_MINUTES", "minutes"}, + {"TIME_SECOND", "second"}, + {"TIME_SECONDS", "seconds"}, {NULL, NULL} }; @@ -111,14 +117,44 @@ int table_add(struct Table *table, char **entry) { int col; if(table->entrys == table->length) return 0; for(col = 0; col < table->width; col++) { - table->contents[table->entrys][col] = ((table->flags & TABLE_FLAG_USE_POINTER) ? entry[col] : strdup(entry[col])); - if(strlen(entry[col]) > table->maxwidth[col]) + table->contents[table->entrys][col] = ((table->flags & TABLE_FLAG_USE_POINTER) || !entry[col] ? entry[col] : strdup(entry[col])); + if(table->contents[table->entrys][col]) + table->col_flags[col] |= TABLE_FLAG_COL_CONTENTS; + if(entry[col] && strlen(entry[col]) > table->maxwidth[col]) table->maxwidth[col] = strlen(entry[col]); } table->entrys++; return 1; } +int table_change(struct Table *table, int row, char **entry) { + int col; + if(row >= table->length) return 0; + for(col = 0; col < table->width; col++) { + if(table->contents[row][col] && !(table->flags & TABLE_FLAG_USE_POINTER)) + free(table->contents[row][col]); + table->contents[row][col] = ((table->flags & TABLE_FLAG_USE_POINTER) || !entry[col] ? entry[col] : strdup(entry[col])); + if(table->contents[row][col]) + table->col_flags[col] |= TABLE_FLAG_COL_CONTENTS; + if(entry[col] && strlen(entry[col]) > table->maxwidth[col]) + table->maxwidth[col] = strlen(entry[col]); + } + return 1; +} + +int table_change_field(struct Table *table, int row, int col, char *entry) { + if(row >= table->length) return 0; + if(col >= table->width) return 0; + if(table->contents[row][col] && !(table->flags & TABLE_FLAG_USE_POINTER)) + free(table->contents[row][col]); + table->contents[row][col] = (((table->flags & TABLE_FLAG_USE_POINTER) || !entry) ? entry : strdup(entry)); + if(table->contents[row][col]) + table->col_flags[col] |= TABLE_FLAG_COL_CONTENTS; + if(entry && strlen(entry) > table->maxwidth[col]) + table->maxwidth[col] = strlen(entry); + return 1; +} + int table_set_bold(struct Table *table, int collum, int bold) { if(bold) table->col_flags[collum] |= TABLE_FLAG_COL_BOLD; @@ -140,20 +176,22 @@ char **table_end(struct Table *table) { table->table_lines[row] = malloc(tablewidth * sizeof(*table->table_lines[row])); pos = 0; for(col = 0; col < table->width; col++) { + 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'; for(i = 0; i < strlen(table->contents[row][col]); i++) { table->table_lines[row][pos++] = table->contents[row][col][i]; } - for(;i < table->maxwidth[col]; i++) { + if(col < table->width-1) { + for(;i < table->maxwidth[col]; i++) { + table->table_lines[row][pos++] = ' '; + } table->table_lines[row][pos++] = ' '; - } + } else + table->table_lines[row][pos++] = '\0'; + if(table->col_flags[col] & TABLE_FLAG_COL_BOLD) table->table_lines[row][pos++] = '\002'; - if(col < table->width-1) - table->table_lines[row][pos++] = ' '; - else - table->table_lines[row][pos++] = '\0'; } } return table->table_lines; @@ -164,7 +202,8 @@ void table_free(struct Table *table) { for(row = 0; row < table->length; row++) { if(!(table->flags & TABLE_FLAG_USE_POINTER) && table->entrys > row) { for(col = 0; col < table->width; col++) { - free(table->contents[row][col]); + if(table->contents[row][col]) + free(table->contents[row][col]); } } free(table->contents[row]); @@ -181,52 +220,278 @@ void table_free(struct Table *table) { free(table); } -int timeToStr(struct UserNode *user, int seconds, int items, char *buf) { - char *item[items]; +char* timeToStr(struct UserNode *user, int seconds, int items, char *buf) { + char item[items][MAXLEN]; int tmp, citem = 0; if(citem != items && seconds >= 31536000) { //60*60*24*365 = 31536000 tmp = seconds / 31536000; - item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_YEAR" : "TIME_YEARS"), tmp); + sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_YEAR" : "TIME_YEARS")); seconds -= tmp * 31536000; } if(citem != items && seconds >= 86400) { //60*60*24 = 86400 tmp = seconds / 86400; - item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_DAY" : "TIME_DAYS"), tmp); + sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_DAY" : "TIME_DAYS")); seconds -= tmp * 86400; } - if(citem != items && seconds >= 3600) { //60*60 = 86400 + if(citem != items && seconds >= 3600) { //60*60 = 3600 tmp = seconds / 3600; - item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_HOUR" : "TIME_HOURS"), tmp); + sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_HOUR" : "TIME_HOURS")); seconds -= tmp * 3600; } if(citem != items && seconds >= 60) { tmp = seconds / 60; - item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_MINUTE" : "TIME_MINUTES"), tmp); + sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_MINUTE" : "TIME_MINUTES")); seconds -= tmp * 60; } if(citem != items && seconds >= 1) { - item[citem++] = build_language_string(user, NULL, (seconds == 1 ? "TIME_SECOND" : "TIME_SECONDS"), seconds); + sprintf(item[citem++], "%d %s", seconds, get_language_string(user, seconds == 1 ? "TIME_SECOND" : "TIME_SECONDS")); } - if(items == 2) { + if(citem == 2) { build_language_string(user, buf, "TIME_MASK_2_ITEMS", item[0], item[1]); - } else if(items == 3) { + } else if(citem == 3) { build_language_string(user, buf, "TIME_MASK_3_ITEMS", item[0], item[1], item[2]); } else { int i, ii, p = 0; - for(i = 0; i < items; i++) { + for(i = 0; i < citem; i++) { for(ii = 0; ii < strlen(item[i]); ii++) { buf[p++] = item[i][ii]; } buf[p++] = ' '; } - buf[p-1] = '\0'; + buf[(p ? p-1 : 0)] = '\0'; } - return 1; + return buf; +} + +int strToTime(struct UserNode *user, char *str) { + /* + * y = year = 365 days + * M = month = 30 days + * w = week = 7 days + * d = day + * h = hour + * m = minute + * (s) = second + */ + int total_time = 0, cvalue; + char *p, tmpchar; + int unit_multiplikator; + while(*str) { + p = str; + while(*p && !isdigit(*p)) //skip leading chars + p++; + str = p; + while(*p && isdigit(*p)) //get the value + p++; + tmpchar = *p; + *p = '\0'; + cvalue = isdigit(*str) ? atoi(str) : 0; + *p = tmpchar; + while(*p == ' ') //skip spaces + p++; + str = p; + while(*p && !isdigit(*p)) //get the unit + p++; + tmpchar = *p; + *p = '\0'; + if(p - str > 1) { //unit has more than one char + if(!stricmp(str, "year") || !stricmp(str, "year") || !stricmp(str, get_language_string(user, "TIME_YEAR")) || !stricmp(str, get_language_string(user, "TIME_YEARS"))) + unit_multiplikator = 31536000; //60*60*24*365 = 31536000 + else if(!stricmp(str, "month") || !stricmp(str, "months") || !stricmp(str, get_language_string(user, "TIME_MONTH")) || !stricmp(str, get_language_string(user, "TIME_MONTHS"))) + unit_multiplikator = 2592000; //60*60*24*30 = 2592000 + else if(!stricmp(str, "week") || !stricmp(str, "weeks") || !stricmp(str, get_language_string(user, "TIME_WEEK")) || !stricmp(str, get_language_string(user, "TIME_WEEKS"))) + unit_multiplikator = 604800; //60*60*24*7 = 604800 + else if(!stricmp(str, "day") || !stricmp(str, "days") || !stricmp(str, get_language_string(user, "TIME_DAY")) || !stricmp(str, get_language_string(user, "TIME_DAYS"))) + unit_multiplikator = 86400; //60*60*24 = 86400 + else if(!stricmp(str, "hour") || !stricmp(str, "hours") || !stricmp(str, get_language_string(user, "TIME_HOUR")) || !stricmp(str, get_language_string(user, "TIME_HOURS"))) + unit_multiplikator = 3600; //60*60 = 3600 + else if(!stricmp(str, "minute") || !stricmp(str, "minutes") || !stricmp(str, "min") || !stricmp(str, "mins") || !stricmp(str, get_language_string(user, "TIME_MINUTE")) || !stricmp(str, get_language_string(user, "TIME_MINUTES"))) + unit_multiplikator = 60; + else + unit_multiplikator = 1; + } else { + switch(*str) { + case 'y': + unit_multiplikator = 31536000; //60*60*24*365 = 31536000 + break; + case 'M': + unit_multiplikator = 2592000; //60*60*24*30 = 2592000 + break; + case 'w': + unit_multiplikator = 604800; //60*60*24*7 = 604800 + break; + case 'd': + unit_multiplikator = 86400; //60*60*24 = 86400 + break; + case 'h': + unit_multiplikator = 3600; //60*60 = 3600 + break; + case 'm': + unit_multiplikator = 60; + break; + default: + unit_multiplikator = 1; + break; + } + } + total_time += (cvalue * unit_multiplikator); + *p = tmpchar; + str = p; + } + return total_time; +} + +struct ModeBuffer* initModeBuffer(struct ClientSocket *client, struct ChanNode *chan) { + struct ModeBuffer *modeBuf = malloc(sizeof(*modeBuf)); + if(!modeBuf) { + perror("malloc() failed"); + return NULL; + } + modeBuf->client = client; + modeBuf->chan = chan; + modeBuf->addCount = 0; + modeBuf->delCount = 0; + return modeBuf; +} + +void modeBufferSet(struct ModeBuffer *modeBuf, int add, char mode, char *param) { + if(add) { + modeBuf->addModes[modeBuf->addCount] = mode; + modeBuf->addModesParams[modeBuf->addCount] = (param ? strdup(param) : NULL); + modeBuf->addCount++; + modeBuf->addModes[modeBuf->addCount] = '\0'; + } else { + modeBuf->delModes[modeBuf->delCount] = mode; + modeBuf->delModesParams[modeBuf->delCount] = (param ? strdup(param) : NULL); + modeBuf->delCount++; + modeBuf->delModes[modeBuf->delCount] = '\0'; + } + if(modeBuf->addCount + modeBuf->delCount == MAXMODES) + flushModeBuffer(modeBuf); +} + +void flushModeBuffer(struct ModeBuffer *modeBuf) { + char modeStr[MAXMODES+3]; + int modePos = 0; + char paramStr[MAXLEN]; + int paramPos = 0; + int i; + if(modeBuf->addCount) { + modeStr[modePos++] = '+'; + for(i = 0; i < modeBuf->addCount; i++) { + modeStr[modePos++] = modeBuf->addModes[i]; + if(modeBuf->addModesParams[i]) { + paramPos += sprintf(paramStr + paramPos, " %s", modeBuf->addModesParams[i]); + } + } + modeBuf->addCount = 0; + } + if(modeBuf->delCount) { + modeStr[modePos++] = '-'; + for(i = 0; i < modeBuf->delCount; i++) { + modeStr[modePos++] = modeBuf->delModes[i]; + if(modeBuf->delModesParams[i]) { + paramPos += sprintf(paramStr + paramPos, " %s", modeBuf->delModesParams[i]); + } + } + modeBuf->delCount = 0; + } + modeStr[modePos++] = '\0'; + putsock(modeBuf->client, "MODE %s %s%s", modeBuf->chan->name, modeStr, paramStr); } +void freeModeBuffer(struct ModeBuffer *modeBuf) { + if(modeBuf->addCount + modeBuf->delCount) + flushModeBuffer(modeBuf); + free(modeBuf); +} +int is_ircmask(const char *text) { + while (*text && (isalnum((char)*text) || strchr("-_[]|\\`^{}?*", *text))) + text++; + if (*text++ != '!') + return 0; + while (*text && *text != '@' && !isspace((char)*text)) + text++; + if (*text++ != '@') + return 0; + while (*text && !isspace((char)*text)) + text++; + return !*text; +} +char* generate_banmask(struct UserNode *user, char *buffer) { + char *userhost = user->host; + + if(isFakeHost(user->host)) { + sprintf(buffer, "*!*@%s", userhost); + return buffer; + } + + //check if the hostname has more than 4 connections (trusted host) + if(countUsersWithHost(userhost) > 4) { + sprintf(buffer, "*!%s@%s", user->ident, userhost); + return buffer; + } else { + sprintf(buffer, "*!*@%s", userhost); + return buffer; + } +} + +char* make_banmask(char *input, char* buffer) { + char *nick = NULL, *ident = NULL, *host = NULL; + char tmp[HOSTLEN]; + char *p; + if((p = strstr(input, "!"))) { + nick = input; + *p = '\0'; + ident = p+1; + if((p = strstr(ident, "@"))) { + *p = '\0'; + host = p+1; + } + } else if((p = strstr(input, "@"))) { + ident = input; + *p = '\0'; + host = p+1; + } else if((p = strstr(input, "."))) { + host = input; + } else if(*input == '*' && input[1] != '\0' && !strstr(input+1, "*")) { + //AUTH MASK + p = getAuthFakehost(input+1); + if(p) + host = p; + else { + sprintf(tmp, "%s.*", input+1); + host = tmp; + } + } else { + struct UserNode *user = searchUserByNick(input); + if(user) + return generate_banmask(user, buffer); + else + nick = input; + } + if(nick && *nick == '\0') nick = NULL; + if(ident && *ident == '\0') ident = NULL; + if(host && *host == '\0') host = NULL; + sprintf(buffer, "%s!%s@%s", (nick ? nick : "*"), (ident ? ident : "*"), (host ? host : "*")); + return buffer; +} + +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, "."))) { + p2 = p1 + 1; + } + //TLD database: http://www.iana.org/domains/root/db/ + //the longest TLD i found was 6 chars long (ignoring the stange exotic ones :D) + //but we even ignore '.museum' and '.travel' so we can say that the TLD of our mask needs to be less than 4 chars to be a real domain + return (strlen(p2+1) > 4); +} void init_tools() { register_default_language_table(msgtab);