fixed last commits
[NeonServV5.git] / tools.c
1 #include "tools.h"
2 #include "UserNode.h"
3 #include "ChanNode.h"
4 #include "lang.h"
5 #include "ClientSocket.h"
6
7 static const struct default_language_entry msgtab[] = {
8     {"TIME_MASK_2_ITEMS", "%s and %s"},
9     {"TIME_MASK_3_ITEMS", "%s, %s and %s"},
10     {"TIME_YEAR", "year"},
11     {"TIME_YEARS", "years"},
12     {"TIME_MONTH", "month"},
13     {"TIME_MONTHS", "months"},
14     {"TIME_WEEK", "week"},
15     {"TIME_WEEKS", "weeks"},
16     {"TIME_DAY", "day"},
17     {"TIME_DAYS", "days"},
18     {"TIME_HOUR", "hour"},
19     {"TIME_HOURS", "hours"},
20     {"TIME_MINUTE", "minute"},
21     {"TIME_MINUTES", "minutes"},
22     {"TIME_SECOND", "second"},
23     {"TIME_SECONDS", "seconds"},
24     {NULL, NULL}
25 };
26
27 /* copied from IRCU 2.10.12 match.c */
28 /*
29  * Compare if a given string (name) matches the given
30  * mask (which can contain wild cards: '*' - match any
31  * number of chars, '?' - match any single character.
32  *
33  * return  0, if match
34  *         1, if no match
35  *
36  *  Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
37  *  Rewritten by Timothy Vogelsang (netski), net@astrolink.org
38  */
39 int match(const char *mask, const char *name)
40 {
41   const char *m = mask, *n = name;
42   const char *m_tmp = mask, *n_tmp = name;
43   int star_p;
44
45   for (;;) switch (*m) {
46   case '\0':
47     if (!*n)
48       return 0;
49   backtrack:
50     if (m_tmp == mask)
51       return 1;
52     m = m_tmp;
53     n = ++n_tmp;
54     if (*n == '\0')
55       return 1;
56     break;
57   case '\\':
58     m++;
59     /* allow escaping to force capitalization */
60     if (*m++ != *n++)
61       goto backtrack;
62     break;
63   case '*': case '?':
64     for (star_p = 0; ; m++) {
65       if (*m == '*')
66         star_p = 1;
67       else if (*m == '?') {
68         if (!*n++)
69           goto backtrack;
70       } else break;
71     }
72     if (star_p) {
73       if (!*m)
74         return 0;
75       else if (*m == '\\') {
76         m_tmp = ++m;
77         if (!*m)
78           return 1;
79         for (n_tmp = n; *n && *n != *m; n++) ;
80       } else {
81         m_tmp = m;
82         for (n_tmp = n; *n && tolower(*n) != tolower(*m); n++) ;
83       }
84     }
85     /* and fall through */
86   default:
87     if (!*n)
88       return *m != '\0';
89     if (tolower(*m) != tolower(*n))
90       goto backtrack;
91     m++;
92     n++;
93     break;
94   }
95 }
96
97
98 //TABLES
99 struct Table *table_init(int width, int length, int flags) {
100     int row;
101     struct Table *table = malloc(sizeof(*table));
102     table->contents = malloc(length * sizeof(*table->contents));
103     for(row = 0; row < length; row++) {
104         table->contents[row] = calloc(width, sizeof(*table->contents[row]));
105     }
106     table->length = length;
107     table->width = width;
108     table->flags = flags;
109     table->col_flags = calloc(length, sizeof(int));
110     table->entrys = 0;
111     table->maxwidth = calloc(length, sizeof(int));
112     table->table_lines = NULL;
113     return table;
114 }
115
116 int table_add(struct Table *table, char **entry) {
117     int col;
118     if(table->entrys == table->length) return 0;
119     for(col = 0; col < table->width; col++) {
120         table->contents[table->entrys][col] = ((table->flags & TABLE_FLAG_USE_POINTER) ? entry[col] : strdup(entry[col]));
121         if(strlen(entry[col]) > table->maxwidth[col])
122             table->maxwidth[col] = strlen(entry[col]);
123     }
124     table->entrys++;
125     return 1;
126 }
127
128 int table_set_bold(struct Table *table, int collum, int bold) {
129     if(bold)
130         table->col_flags[collum] |= TABLE_FLAG_COL_BOLD;
131     else
132         table->col_flags[collum] &= ~TABLE_FLAG_COL_BOLD;
133     return 1;
134 }
135
136 char **table_end(struct Table *table) {
137     int row, col, tablewidth = 0, pos,i;
138     if(!table->entrys) return NULL;
139     for(col = 0; col < table->width; col++) {
140         tablewidth += table->maxwidth[col]+1;
141         if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
142             tablewidth += 2;
143     }
144     table->table_lines = malloc(table->entrys * sizeof(table->table_lines));
145     for(row = 0; row < table->entrys; row++) {
146         table->table_lines[row] = malloc(tablewidth * sizeof(*table->table_lines[row]));
147         pos = 0;
148         for(col = 0; col < table->width; col++) {
149             if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
150                 table->table_lines[row][pos++] = '\002';
151             for(i = 0; i < strlen(table->contents[row][col]); i++) {
152                 table->table_lines[row][pos++] = table->contents[row][col][i];
153             }
154             if(col < table->width-1) {
155                 for(;i < table->maxwidth[col]; i++) {
156                     table->table_lines[row][pos++] = ' ';
157                 }
158                 table->table_lines[row][pos++] = ' ';
159             } else
160                 table->table_lines[row][pos++] = '\0';
161             
162             if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
163                 table->table_lines[row][pos++] = '\002';
164         }
165     }
166     return table->table_lines;
167 }
168
169 void table_free(struct Table *table) {
170     int row, col;
171     for(row = 0; row < table->length; row++) {
172         if(!(table->flags & TABLE_FLAG_USE_POINTER) && table->entrys > row) {
173             for(col = 0; col < table->width; col++) {
174                 free(table->contents[row][col]);
175             }
176         }
177         free(table->contents[row]);
178     }
179     free(table->contents);
180     free(table->col_flags);
181     free(table->maxwidth);
182     if(table->table_lines) {
183         for(row = 0; row < table->entrys; row++) {
184             free(table->table_lines[row]);
185         }
186         free(table->table_lines);
187     }
188     free(table);
189 }
190
191 char* timeToStr(struct UserNode *user, int seconds, int items, char *buf) {
192     char item[items][MAXLEN];
193     int tmp, citem = 0;
194     if(citem != items && seconds >= 31536000) { //60*60*24*365 = 31536000
195         
196         tmp = seconds / 31536000;
197         sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_YEAR" : "TIME_YEARS"));
198         seconds -= tmp * 31536000;
199     }
200     if(citem != items && seconds >= 86400) { //60*60*24 = 86400
201         tmp = seconds / 86400;
202         sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_DAY" : "TIME_DAYS"));
203         seconds -= tmp * 86400;
204     }
205     if(citem != items && seconds >= 3600) { //60*60 = 3600
206         tmp = seconds / 3600;
207         sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_HOUR" : "TIME_HOURS"));
208         seconds -= tmp * 3600;
209     }
210     if(citem != items && seconds >= 60) {
211         tmp = seconds / 60;
212         sprintf(item[citem++], "%d %s", tmp, get_language_string(user, tmp == 1 ? "TIME_MINUTE" : "TIME_MINUTES"));
213         seconds -= tmp * 60;
214     }
215     if(citem != items && seconds >= 1) {
216         sprintf(item[citem++], "%d %s", seconds, get_language_string(user, seconds == 1 ? "TIME_SECOND" : "TIME_SECONDS"));
217     }
218     if(citem == 2) {
219         build_language_string(user, buf, "TIME_MASK_2_ITEMS", item[0], item[1]);
220     } else if(citem == 3) {
221         build_language_string(user, buf, "TIME_MASK_3_ITEMS", item[0], item[1], item[2]);
222     } else {
223         int i, ii, p = 0;
224         for(i = 0; i < citem; i++) {
225             for(ii = 0; ii < strlen(item[i]); ii++) {
226                 buf[p++] = item[i][ii];
227             }
228             buf[p++] = ' ';
229         }
230         buf[p-1] = '\0';
231     }
232     return buf;
233 }
234
235 int strToTime(struct UserNode *user, char *str) {
236     /*
237     * y = year = 365 days
238     * M = month = 30 days
239     * w = week = 7 days
240     * d = day
241     * h = hour
242     * m = minute
243     * (s) = second
244     */
245     int total_time = 0, cvalue;
246     char *p, tmpchar;
247     int unit_multiplikator;
248     while(*str) {
249         p = str;
250         while(*p && isdigit(*p)) //get the value
251             p++;
252         tmpchar = *p;
253         *p = '\0';
254         cvalue = isdigit(*str) ? atoi(str) : 0;
255         *p = tmpchar;
256         str = p;
257         while(*p && !isdigit(*p)) //get the unit
258             p++;
259         tmpchar = *p;
260         *p = '\0';
261         if(p - str > 1) { //unit has more than one char
262             if(!stricmp(str, "year") || !stricmp(str, "year") || !stricmp(str, get_language_string(user, "TIME_YEAR")) || !stricmp(str, get_language_string(user, "TIME_YEARS")))
263                 unit_multiplikator = 31536000; //60*60*24*365 = 31536000
264             else if(!stricmp(str, "month") || !stricmp(str, "months") || !stricmp(str, get_language_string(user, "TIME_MONTH")) || !stricmp(str, get_language_string(user, "TIME_MONTHS")))
265                 unit_multiplikator = 2592000; //60*60*24*30 = 2592000
266             else if(!stricmp(str, "week") || !stricmp(str, "weeks") || !stricmp(str, get_language_string(user, "TIME_WEEK")) || !stricmp(str, get_language_string(user, "TIME_WEEKS")))
267                 unit_multiplikator = 604800; //60*60*24*7 = 604800
268             else if(!stricmp(str, "day") || !stricmp(str, "days") || !stricmp(str, get_language_string(user, "TIME_DAY")) || !stricmp(str, get_language_string(user, "TIME_DAYS")))
269                 unit_multiplikator = 86400; //60*60*24 = 86400
270             else if(!stricmp(str, "hour") || !stricmp(str, "hours") || !stricmp(str, get_language_string(user, "TIME_HOUR")) || !stricmp(str, get_language_string(user, "TIME_HOURS")))
271                 unit_multiplikator = 3600; //60*60 = 3600
272             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")))
273                 unit_multiplikator = 60;
274             else
275                 unit_multiplikator = 1;
276         } else {
277             switch(*str) {
278                 case 'y':
279                     unit_multiplikator = 31536000; //60*60*24*365 = 31536000
280                     break;
281                 case 'M':
282                     unit_multiplikator = 2592000; //60*60*24*30 = 2592000
283                     break;
284                 case 'w':
285                     unit_multiplikator = 604800; //60*60*24*7 = 604800
286                     break;
287                 case 'd':
288                     unit_multiplikator = 86400; //60*60*24 = 86400
289                     break;
290                 case 'h':
291                     unit_multiplikator = 3600; //60*60 = 3600
292                     break;
293                 case 'm':
294                     unit_multiplikator = 60;
295                     break;
296                 default:
297                     unit_multiplikator = 1;
298                     break;
299             }
300         }
301         total_time += (cvalue * unit_multiplikator);
302         *p = tmpchar;
303         str = p;
304     }
305     return total_time;
306 }
307
308 struct ModeBuffer* initModeBuffer(struct ClientSocket *client, struct ChanNode *chan) {
309     struct ModeBuffer *modeBuf = malloc(sizeof(*modeBuf));
310     if(!modeBuf) {
311         perror("malloc() failed");
312         return NULL;
313     }
314     modeBuf->client = client;
315     modeBuf->chan = chan;
316     modeBuf->addCount = 0;
317     modeBuf->delCount = 0;
318     return modeBuf;
319 }
320
321 void modeBufferSet(struct ModeBuffer *modeBuf, int add, char mode, char *param) {
322     if(add) {
323         modeBuf->addModes[modeBuf->addCount] = mode;
324         modeBuf->addModesParams[modeBuf->addCount] = (param ? strdup(param) : NULL);
325         modeBuf->addCount++;
326         modeBuf->addModes[modeBuf->addCount] = '\0';
327     } else {
328         modeBuf->delModes[modeBuf->delCount] = mode;
329         modeBuf->delModesParams[modeBuf->delCount] = (param ? strdup(param) : NULL);
330         modeBuf->delCount++;
331         modeBuf->delModes[modeBuf->delCount] = '\0';
332     }
333     if(modeBuf->addCount + modeBuf->delCount == MAXMODES)
334         flushModeBuffer(modeBuf);
335 }
336
337 void flushModeBuffer(struct ModeBuffer *modeBuf) {
338     char modeStr[MAXMODES+3];
339     int modePos = 0;
340     char paramStr[MAXLEN];
341     int paramPos = 0;
342     int i;
343     if(modeBuf->addCount) {
344         modeStr[modePos++] = '+';
345         for(i = 0; i < modeBuf->addCount; i++) {
346             modeStr[modePos++] = modeBuf->addModes[i];
347             if(modeBuf->addModesParams[i]) {
348                 paramPos += sprintf(paramStr + paramPos, " %s", modeBuf->addModesParams[i]);
349             }
350         }
351         modeBuf->addCount = 0;
352     }
353     if(modeBuf->delCount) {
354         modeStr[modePos++] = '-';
355         for(i = 0; i < modeBuf->delCount; i++) {
356             modeStr[modePos++] = modeBuf->delModes[i];
357             if(modeBuf->delModesParams[i]) {
358                 paramPos += sprintf(paramStr + paramPos, " %s", modeBuf->delModesParams[i]);
359             }
360         }
361         modeBuf->delCount = 0;
362     }
363     modeStr[modePos++] = '\0';
364     putsock(modeBuf->client, "MODE %s %s%s", modeBuf->chan->name, modeStr, paramStr);
365 }
366
367 void freeModeBuffer(struct ModeBuffer *modeBuf) {
368     if(modeBuf->addCount + modeBuf->delCount)
369         flushModeBuffer(modeBuf);
370     free(modeBuf);
371 }
372
373 void init_tools() {
374     register_default_language_table(msgtab);
375 }