push
[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 #else
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #endif
28
29 int stricmp (const char *s1, const char *s2) {
30     return stricmplen(s1, s2, -1);
31 }
32
33 int stricmplen(const char *s1, const char *s2, int len) {
34     if (s1 == NULL) 
35         return (s2 == NULL ? 0 : -(*s2));
36     if (s2 == NULL) 
37         return *s1;
38     char c1, c2;
39     int i = 0;
40     while ((c1 = tolower(*s1)) == (c2 = tolower(*s2))) {
41         if (*s1 == '\0') 
42             break;
43         i++;
44         s1++; 
45         s2++;
46         if(len != -1 && i == len) break;
47     }
48     return c1 - c2;
49 }
50
51 /* copied from IRCU 2.10.12 match.c */
52 /*
53  * Compare if a given string (name) matches the given
54  * mask (which can contain wild cards: '*' - match any
55  * number of chars, '?' - match any single character.
56  *
57  * return  0, if match
58  *         1, if no match
59  *
60  *  Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
61  *  Rewritten by Timothy Vogelsang (netski), net@astrolink.org
62  */
63 int match(const char *mask, const char *name)
64 {
65   const char *m = mask, *n = name;
66   const char *m_tmp = mask, *n_tmp = name;
67   int star_p;
68
69   for (;;) switch (*m) {
70   case '\0':
71     if (!*n)
72       return 0;
73   backtrack:
74     if (m_tmp == mask)
75       return 1;
76     m = m_tmp;
77     n = ++n_tmp;
78     if (*n == '\0')
79       return 1;
80     break;
81   case '\\':
82     m++;
83     /* allow escaping to force capitalization */
84     if (*m++ != *n++)
85       goto backtrack;
86     break;
87   case '*': case '?':
88     for (star_p = 0; ; m++) {
89       if (*m == '*')
90         star_p = 1;
91       else if (*m == '?') {
92         if (!*n++)
93           goto backtrack;
94       } else break;
95     }
96     if (star_p) {
97       if (!*m)
98         return 0;
99       else if (*m == '\\') {
100         m_tmp = ++m;
101         if (!*m)
102           return 1;
103         for (n_tmp = n; *n && *n != *m; n++) ;
104       } else {
105         m_tmp = m;
106         for (n_tmp = n; *n && tolower(*n) != tolower(*m); n++) ;
107       }
108     }
109     /* and fall through */
110   default:
111     if (!*n)
112       return *m != '\0';
113     if (tolower(*m) != tolower(*n))
114       goto backtrack;
115     m++;
116     n++;
117     break;
118   }
119 }
120
121
122 static unsigned char random_numbers[256];
123 static int random_numbers_available = 0;
124
125 int get_random(int min, int max) {
126         int requested_bytes = 0;
127         unsigned int rnd_width = max-min;
128         if((rnd_width % (0xFF000000)))
129                 requested_bytes = 4;
130         else if((rnd_width % (0xFF0000)))
131                 requested_bytes = 3;
132         else if((rnd_width % (0xFF00)))
133                 requested_bytes = 2;
134         else
135                 requested_bytes = 1;
136         
137         //get_random_generate:
138         
139         if(random_numbers_available < requested_bytes) {
140                 // generate new random numbers
141                 #ifdef WIN32
142                 HMODULE hLib=LoadLibrary("ADVAPI32.DLL");
143                 if (hLib) {
144                         BOOLEAN (APIENTRY *pfn)(void*, ULONG) = (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036");
145                         if(pfn) {
146                                 ULONG ulCbBuff = sizeof(random_numbers) - random_numbers_available;
147                                 if(pfn(random_numbers + random_numbers_available,ulCbBuff)) {
148                                         random_numbers_available += ulCbBuff;
149                                 }
150                         }
151                         FreeLibrary(hLib);
152                 }
153                 #else
154                 int randomData = open("/dev/random", O_RDONLY);
155                 int randLen = sizeof(random_numbers) - random_numbers_available;
156                 size_t randomDataLen = random_numbers_available;
157                 while (randomDataLen < randLen) {
158                         ssize_t result = read(randomData, ((char*)random_numbers) + randomDataLen, randLen - randomDataLen);
159                         if (result < 0)
160                                 break;
161                         randomDataLen += result;
162                 }
163                 random_numbers_available = randomDataLen;
164                 close(randomData);
165                 #endif
166                 
167                 if(random_numbers_available < requested_bytes) {
168                         //system random number generators failed!
169                         
170                 }
171         }
172         
173         int rnd = 0;
174         int i = 0;
175         do {
176                 if(i)
177                         rnd <<= 8;
178                 rnd |= random_numbers[--random_numbers_available];
179         } while(++i < requested_bytes);
180         
181         // TODO: find better solution for this
182         //if((rnd % rnd_width) > rnd_width)
183         //      goto get_random_generate;
184         
185         return min + (rnd % rnd_width);
186 }
187