added some code
[NextIRCd.git] / src / tools.c
1 /* tools.c - NextIRCd
2  * Copyright (C) 2012-2013  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 #include <stdlib.h>
19 #include <ctype.h>
20 #include "tools.h"
21
22 #ifdef WIN32
23 #include <windows.h>
24 #endif
25
26 int stricmp (const char *s1, const char *s2) {
27     return stricmplen(s1, s2, -1);
28 }
29
30 int stricmplen(const char *s1, const char *s2, int len) {
31     if (s1 == NULL) 
32         return (s2 == NULL ? 0 : -(*s2));
33     if (s2 == NULL) 
34         return *s1;
35     char c1, c2;
36     int i = 0;
37     while ((c1 = tolower(*s1)) == (c2 = tolower(*s2))) {
38         if (*s1 == '\0') 
39             break;
40         i++;
41         s1++; 
42         s2++;
43         if(len != -1 && i == len) break;
44     }
45     return c1 - c2;
46 }
47
48 /* copied from IRCU 2.10.12 match.c */
49 /*
50  * Compare if a given string (name) matches the given
51  * mask (which can contain wild cards: '*' - match any
52  * number of chars, '?' - match any single character.
53  *
54  * return  0, if match
55  *         1, if no match
56  *
57  *  Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
58  *  Rewritten by Timothy Vogelsang (netski), net@astrolink.org
59  */
60 int match(const char *mask, const char *name)
61 {
62   const char *m = mask, *n = name;
63   const char *m_tmp = mask, *n_tmp = name;
64   int star_p;
65
66   for (;;) switch (*m) {
67   case '\0':
68     if (!*n)
69       return 0;
70   backtrack:
71     if (m_tmp == mask)
72       return 1;
73     m = m_tmp;
74     n = ++n_tmp;
75     if (*n == '\0')
76       return 1;
77     break;
78   case '\\':
79     m++;
80     /* allow escaping to force capitalization */
81     if (*m++ != *n++)
82       goto backtrack;
83     break;
84   case '*': case '?':
85     for (star_p = 0; ; m++) {
86       if (*m == '*')
87         star_p = 1;
88       else if (*m == '?') {
89         if (!*n++)
90           goto backtrack;
91       } else break;
92     }
93     if (star_p) {
94       if (!*m)
95         return 0;
96       else if (*m == '\\') {
97         m_tmp = ++m;
98         if (!*m)
99           return 1;
100         for (n_tmp = n; *n && *n != *m; n++) ;
101       } else {
102         m_tmp = m;
103         for (n_tmp = n; *n && tolower(*n) != tolower(*m); n++) ;
104       }
105     }
106     /* and fall through */
107   default:
108     if (!*n)
109       return *m != '\0';
110     if (tolower(*m) != tolower(*n))
111       goto backtrack;
112     m++;
113     n++;
114     break;
115   }
116 }
117
118
119 static unsigned char random_numbers[256];
120 static int random_numbers_available = 0;
121
122 int get_random(int min, int max) {
123         int requested_bytes = 0;
124         unsigned int rnd_width = max-min;
125         if((rnd_width % (0xFF000000)))
126                 requested_bytes = 4;
127         else if((rnd_width % (0xFF0000)))
128                 requested_bytes = 3;
129         else if((rnd_width % (0xFF00)))
130                 requested_bytes = 2;
131         else
132                 requested_bytes = 1;
133         
134         //get_random_generate:
135         
136         if(random_numbers_available < requested_bytes) {
137                 // generate new random numbers
138                 #ifdef WIN32
139                 HMODULE hLib=LoadLibrary("ADVAPI32.DLL");
140                 if (hLib) {
141                         BOOLEAN (APIENTRY *pfn)(void*, ULONG) = (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036");
142                         if(pfn) {
143                                 ULONG ulCbBuff = sizeof(random_numbers) - random_numbers_available;
144                                 if(pfn(random_numbers + random_numbers_available,ulCbBuff)) {
145                                         random_numbers_available += ulCbBuff;
146                                 }
147                         }
148                         FreeLibrary(hLib);
149                 }
150                 #else
151                 int randomData = open("/dev/random", O_RDONLY);
152                 int randLen = sizeof(random_numbers) - random_numbers_available;
153                 size_t randomDataLen = random_numbers_available;
154                 while (randomDataLen < randLen) {
155                         ssize_t result = read(randomData, ((char*)random_numbers) + randomDataLen, randLen - randomDataLen);
156                         if (result < 0)
157                                 break;
158                         randomDataLen += result;
159                 }
160                 random_numbers_available = randomDataLen;
161                 close(randomData);
162                 #endif
163                 
164                 if(random_numbers_available < requested_bytes) {
165                         //system random number generators failed!
166                         
167                 }
168         }
169         
170         int rnd = 0;
171         int i = 0;
172         do {
173                 if(i)
174                         rnd <<= 8;
175                 rnd |= random_numbers[--random_numbers_available];
176         } while(++i < requested_bytes);
177         
178         // TODO: find better solution for this
179         //if((rnd % rnd_width) > rnd_width)
180         //      goto get_random_generate;
181         
182         return min + (rnd % rnd_width);
183 }
184