+ 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;