push
[NextIRCd.git] / src / tools.c
index 8a72127951bfc6f323b1c8d1a222366d558665fd..c639a25803b18b1a77f60b2eb46063c7aac83f24 100644 (file)
 #include <ctype.h>
 #include "tools.h"
 
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
 int stricmp (const char *s1, const char *s2) {
     return stricmplen(s1, s2, -1);
 }
@@ -41,3 +48,140 @@ int stricmplen(const char *s1, const char *s2, int len) {
     return c1 - c2;
 }
 
+/* copied from IRCU 2.10.12 match.c */
+/*
+ * Compare if a given string (name) matches the given
+ * mask (which can contain wild cards: '*' - match any
+ * number of chars, '?' - match any single character.
+ *
+ * return  0, if match
+ *         1, if no match
+ *
+ *  Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
+ *  Rewritten by Timothy Vogelsang (netski), net@astrolink.org
+ */
+int match(const char *mask, const char *name)
+{
+  const char *m = mask, *n = name;
+  const char *m_tmp = mask, *n_tmp = name;
+  int star_p;
+
+  for (;;) switch (*m) {
+  case '\0':
+    if (!*n)
+      return 0;
+  backtrack:
+    if (m_tmp == mask)
+      return 1;
+    m = m_tmp;
+    n = ++n_tmp;
+    if (*n == '\0')
+      return 1;
+    break;
+  case '\\':
+    m++;
+    /* allow escaping to force capitalization */
+    if (*m++ != *n++)
+      goto backtrack;
+    break;
+  case '*': case '?':
+    for (star_p = 0; ; m++) {
+      if (*m == '*')
+        star_p = 1;
+      else if (*m == '?') {
+        if (!*n++)
+          goto backtrack;
+      } else break;
+    }
+    if (star_p) {
+      if (!*m)
+        return 0;
+      else if (*m == '\\') {
+        m_tmp = ++m;
+        if (!*m)
+          return 1;
+        for (n_tmp = n; *n && *n != *m; n++) ;
+      } else {
+        m_tmp = m;
+        for (n_tmp = n; *n && tolower(*n) != tolower(*m); n++) ;
+      }
+    }
+    /* and fall through */
+  default:
+    if (!*n)
+      return *m != '\0';
+    if (tolower(*m) != tolower(*n))
+      goto backtrack;
+    m++;
+    n++;
+    break;
+  }
+}
+
+
+static unsigned char random_numbers[256];
+static int random_numbers_available = 0;
+
+int get_random(int min, int max) {
+       int requested_bytes = 0;
+       unsigned int rnd_width = max-min;
+       if((rnd_width % (0xFF000000)))
+               requested_bytes = 4;
+       else if((rnd_width % (0xFF0000)))
+               requested_bytes = 3;
+       else if((rnd_width % (0xFF00)))
+               requested_bytes = 2;
+       else
+               requested_bytes = 1;
+       
+       //get_random_generate:
+       
+       if(random_numbers_available < requested_bytes) {
+               // generate new random numbers
+               #ifdef WIN32
+               HMODULE hLib=LoadLibrary("ADVAPI32.DLL");
+               if (hLib) {
+                       BOOLEAN (APIENTRY *pfn)(void*, ULONG) = (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036");
+                       if(pfn) {
+                               ULONG ulCbBuff = sizeof(random_numbers) - random_numbers_available;
+                               if(pfn(random_numbers + random_numbers_available,ulCbBuff)) {
+                                       random_numbers_available += ulCbBuff;
+                               }
+                       }
+                       FreeLibrary(hLib);
+               }
+               #else
+               int randomData = open("/dev/random", O_RDONLY);
+               int randLen = sizeof(random_numbers) - random_numbers_available;
+               size_t randomDataLen = random_numbers_available;
+               while (randomDataLen < randLen) {
+                       ssize_t result = read(randomData, ((char*)random_numbers) + randomDataLen, randLen - randomDataLen);
+                       if (result < 0)
+                               break;
+                       randomDataLen += result;
+               }
+               random_numbers_available = randomDataLen;
+               close(randomData);
+               #endif
+               
+               if(random_numbers_available < requested_bytes) {
+                       //system random number generators failed!
+                       
+               }
+       }
+       
+       int rnd = 0;
+       int i = 0;
+       do {
+               if(i)
+                       rnd <<= 8;
+               rnd |= random_numbers[--random_numbers_available];
+       } while(++i < requested_bytes);
+       
+       // TODO: find better solution for this
+       //if((rnd % rnd_width) > rnd_width)
+       //      goto get_random_generate;
+       
+       return min + (rnd % rnd_width);
+}
+