]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - win/inspircd_win32wrapper.cpp
OOPS! We try again, since I'm smoking craq. LF is 0x0a NOT CR.
[user/henk/code/inspircd.git] / win / inspircd_win32wrapper.cpp
index 1557c8f6e958d053b720d96a706b4a3f19aa3456..b3af867cff67c387685e2041950f2462d78030e7 100644 (file)
@@ -1 +1,513 @@
-/*       +------------------------------------+\r *       | Inspire Internet Relay Chat Daemon |\r *       +------------------------------------+\r *\r *  InspIRCd: (C) 2002-2007 InspIRCd Development Team\r * See: http://www.inspircd.org/wiki/index.php/Credits\r *\r * This program is free but copyrighted software; see\r *            the file COPYING for details.\r *\r * ---------------------------------------------------\r */\r\r#include "inspircd_win32wrapper.h"\r#include "inspircd.h"\r#include <string>\r#include <errno.h>\r#include <assert.h>\rusing namespace std;\r\r#ifndef INADDR_NONE\r#define INADDR_NONE 0xffffffff\r#endif\r\rHANDLE hIPCPipe;\r\rint inet_aton(const char *cp, struct in_addr *addr)\r{\r        unsigned long ip = inet_addr(cp);\r      addr->s_addr = ip;\r     return (addr->s_addr == INADDR_NONE) ? 0 : 1;\r}\r\rconst char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)\r{\r\r   if (af == AF_INET)\r     {\r              struct sockaddr_in in;\r         memset(&in, 0, sizeof(in));\r            in.sin_family = AF_INET;\r               memcpy(&in.sin_addr, src, sizeof(struct in_addr));\r             getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);\r            return dst;\r    }\r      else if (af == AF_INET6)\r       {\r              struct sockaddr_in6 in;\r                memset(&in, 0, sizeof(in));\r            in.sin6_family = AF_INET6;\r             memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));\r           getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);\r           return dst;\r    }\r      return NULL;\r}\r\rint geteuid()\r{\r        return 1;\r}\r\rint inet_pton(int af, const char *src, void *dst)\r{\r       sockaddr_in sa;\r        int len = sizeof(SOCKADDR);\r    int rv = WSAStringToAddress((LPSTR)src, af, NULL, (LPSOCKADDR)&sa, &len);\r      if(rv >= 0)\r    {\r              if(WSAGetLastError() == 10022)                  // Invalid Argument\r                    rv = 0;\r                else\r                   rv = 1;\r        }\r      memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));\r     return rv;\r}\r\rchar * strtok_r(char *_String, const char *_Control, char **_Context)\r{\r  unsigned char *str;\r    const unsigned char *ctl = (const unsigned char*)_Control;\r     unsigned char map[32];\r\r        if (_Context == 0 || !_Control)\r                return 0;\r\r     if (!(_String != NULL || *_Context != NULL))\r           return 0;\r\r     memset(map, 0, 32);\r\r   do {\r           map[*ctl >> 3] |= (1 << (*ctl & 7));\r   } while (*ctl++);\r\r     /* If string is NULL, set str to the saved\r     * pointer (i.e., continue breaking tokens out of the string\r    * from the last strtok call) */\r        if (_String != NULL)\r   {\r              str = (unsigned char*)_String;\r }\r      else\r   {\r              str = (unsigned char*)*_Context;\r       }\r\r     /* Find beginning of token (skip over leading delimiters). Note that\r   * there is no token iff this loop sets str to point to the terminal\r    * null (*str == 0) */\r  while ((map[*str >> 3] & (1 << (*str & 7))) && *str != 0)\r      {\r              str++;\r }\r\r     _String = (char*)str;\r\r /* Find the end of the token. If it is not the end of the string,\r      * put a null there. */\r for ( ; *str != 0 ; str++ )\r    {\r              if (map[*str >> 3] & (1 << (*str & 7)))\r                {\r                      *str++ = 0;\r                    break;\r         }\r      }\r\r     /* Update context */\r   *_Context = (char*)str;\r\r       /* Determine if a token has been found. */\r     if (_String == (char*)str)\r     {\r              return NULL;\r   }\r      else\r   {\r              return _String;\r        }\r}\r\rvoid setcolor(int color_code)\r{\r   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color_code);\r}\r\rDIR * opendir(const char * path)\r{\r    std::string search_path = string(path) + "\\*.*";\r      WIN32_FIND_DATA fd;\r    HANDLE f = FindFirstFile(search_path.c_str(), &fd);\r    if (f != INVALID_HANDLE_VALUE)\r {\r              DIR * d = new DIR;\r             memcpy(&d->find_data, &fd, sizeof(WIN32_FIND_DATA));\r           d->find_handle = f;\r            d->first = true;\r               return d;\r      }\r      else\r   {\r              return 0;\r      }\r}\r\rdirent * readdir(DIR * handle)\r{\r  if (handle->first)\r             handle->first = false;\r else\r   {\r              if (!FindNextFile(handle->find_handle, &handle->find_data))\r                    return 0;\r      }\r\r     strncpy(handle->dirent_pointer.d_name, handle->find_data.cFileName, MAX_PATH);\r return &handle->dirent_pointer;\r}\r\rvoid closedir(DIR * handle)\r{\r       FindClose(handle->find_handle);\r        delete handle;\r}\r\rconst char * dlerror()\r{\r     static char errormessage[500];\r DWORD error = GetLastError();\r  SetLastError(0);\r       if (error == 0)\r                return 0;\r\r     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)errormessage, 500, 0);\r  return errormessage;\r}\r\r#define TRED FOREGROUND_RED | FOREGROUND_INTENSITY\r#define TGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY\r#define TYELLOW FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY\r#define TNORMAL FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE\r#define TWHITE TNORMAL | FOREGROUND_INTENSITY\r#define TBLUE FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY\r\r/* Handles colors in printf */\rint printf_c(const char * format, ...)\r{\r  // Better hope we're not multithreaded, otherwise we'll have chickens crossing the road other side to get the to :P\r    static char message[MAXBUF];\r   static char temp[MAXBUF];\r      int color1, color2;\r\r   /* parse arguments */\r  va_list ap;\r    va_start(ap, format);\r  vsnprintf(message, 500, format, ap);\r   va_end(ap);\r\r   /* search for unix-style escape sequences */\r   int t;\r int c = 0;\r     const char * p = message;\r      while (*p != 0)\r        {\r              if (*p == '\033')\r              {\r                      // Escape sequence -> copy into the temp buffer, and parse the color.\r                  p++;\r                   t = 0;\r                 while ((*p) && (*p != 'm'))\r                    {\r                              temp[t++] = *p;\r                                ++p;\r                   }\r\r                     temp[t] = 0;\r                   p++;\r\r                  if (*temp == '[')\r                      {\r                              if (sscanf(temp, "[%u;%u", &color1, &color2) == 2)\r                             {\r                                      switch(color2)\r                                 {\r                                      case 32:                // Green\r                                               SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);              // Yellow\r                                              break;\r\r                                        default:                // Unknown\r                                             // White\r                                               SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);\r                                          break;\r                                 }\r                              }\r                              else\r                           {\r                                      switch (*(temp+1))\r                                     {\r                                              case '0':\r                                                      // Returning to normal colour.\r                                                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);\r                                                 break;\r\r                                                case '1':\r                                                      // White\r                                                       SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), TWHITE);\r                                                      break;\r\r                                                default:\r                                                       char message[50];\r                                                      sprintf(message, "Unknown color code: %s", temp);\r                                                      MessageBox(0, message, message, MB_OK);\r                                                        break;\r                                 }\r                              }\r                      }\r              }\r\r             putchar(*p);\r           ++c;\r           ++p;\r   }\r\r     return c;\r}\r\rint arg_counter = 1;\rchar optarg[514];\rint getopt_long_only(int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind)\r{\r        // burlex todo: handle the shortops, at the moment it only works with longopts.\r\r       if (___argc == 1 || arg_counter == ___argc)                     // No arguments (apart from filename)\r          return -1;\r\r    const char * opt = ___argv[arg_counter];\r       int return_val = 0;\r\r   // if we're not an option, return an error.\r    if (strnicmp(opt, "--", 2) != 0)\r               return 1;\r      else\r           opt += 2;\r\r\r    // parse argument list\r int i = 0;\r     for (; __longopts[i].name != 0; ++i)\r   {\r              if (!strnicmp(__longopts[i].name, opt, strlen(__longopts[i].name)))\r            {\r                      // woot, found a valid argument =)\r                     char * par = 0;\r                        if ((arg_counter + 1) != ___argc)\r                      {\r                              // grab the parameter from the next argument (if its not another argument)\r                             if (strnicmp(___argv[arg_counter+1], "--", 2) != 0)\r                            {\r                                      arg_counter++;          // Trash this next argument, we won't be needing it.\r                                   par = ___argv[arg_counter];\r                            }\r                      }                       \r\r                      // increment the argument for next time\r                        arg_counter++;\r\r                        // determine action based on type\r                      if (__longopts[i].has_arg == required_argument && !par)\r                        {\r                              // parameter missing and its a required parameter option\r                               return 1;\r                      }\r\r                     // store argument in optarg\r                    if (par)\r                               strncpy(optarg, par, 514);\r\r                    if (__longopts[i].flag != 0)\r                   {\r                              // this is a variable, we have to set it if this argument is found.\r                            *__longopts[i].flag = 1;\r                               return 0;\r                      }\r                      else\r                   {\r                              if (__longopts[i].val == -1 || par == 0)\r                                       return 1;\r                              \r                               return __longopts[i].val;\r                      }                       \r                       break;\r         }\r      }\r\r     // return 1 (invalid argument)\r return 1;\r}\r\r/* IPC Messages */\r#define IPC_MESSAGE_REHASH      1\r#define IPC_MESSAGE_DIE               2\r#define IPC_MESSAGE_RESTART   3\r\rvoid InitIPC()\r{\r    static DWORD buflen = 1024;\r    static const char * pipename = "\\\\.\\mailslot\\Inspircd";\r    hIPCPipe = CreateMailslot(pipename, buflen, 0, 0);\r     if (hIPCPipe == INVALID_HANDLE_VALUE)\r          printf("IPC Pipe could not be created. Are you sure you didn't start InspIRCd twice?\n");\r}\r\rvoid CheckIPC(InspIRCd * Instance)\r{\r      if (hIPCPipe == INVALID_HANDLE_VALUE)\r          return;\r\r       DWORD bytes;\r   DWORD action;\r\r BOOL res = ReadFile(hIPCPipe, &action, sizeof(DWORD), &bytes, 0);\r      if (!res)\r      {\r              if (GetLastError() != ERROR_SEM_TIMEOUT)\r                       Instance->Log(DEFAULT, "IPC Pipe Error %u: %s", GetLastError(), dlerror());\r            return;\r        }\r\r     switch (action)\r        {\r              case IPC_MESSAGE_REHASH:\r                       InspIRCd::Rehash(0);\r           break;\r         \r               case IPC_MESSAGE_DIE:\r                  InspIRCd::Exit(0);\r             break;\r\r                case IPC_MESSAGE_RESTART:\r                      Instance->Restart("IPC_MESSAGE_RESTART received by mailslot.");\r                break;\r }\r}\r\rvoid CloseIPC()\r{\r CloseHandle(hIPCPipe);\r}\r\r\r/* These three functions were created from looking at how ares does it\r * (...and they look far tidier in C++)\r */\r\r/* Get active nameserver */\rbool GetNameServer(HKEY regkey, const char *key, char* &output)\r{\r   DWORD size = 0;\r        DWORD result = RegQueryValueEx(regkey, key, 0, NULL, NULL, &size);\r     if (((result != ERROR_SUCCESS) && (result != ERROR_MORE_DATA)) || (!size))\r             return false;\r\r output = new char[size+1];\r\r    if ((RegQueryValueEx(regkey, key, 0, NULL, (LPBYTE)output, &size) != ERROR_SUCCESS) || (!*output))\r     {\r              delete output;\r         return false;\r  }\r      return true;\r}\r\r/* Check a network interface for its nameserver */\rbool GetInterface(HKEY regkey, const char *key, char* &output)\r{\r    char buf[39];\r  DWORD size = 39;\r       int idx = 0;\r   HKEY top;\r\r     while (RegEnumKeyEx(regkey, idx++, buf, &size, 0, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)\r    {\r              size = 39;\r             if (RegOpenKeyEx(regkey, buf, 0, KEY_QUERY_VALUE, &top) != ERROR_SUCCESS)\r                      continue;\r              int rc = GetNameServer(top, key, output);\r              RegCloseKey(top);\r              if (rc)\r                        return true;\r   }\r      return false;\r}\r\r\rstd::string FindNameServerWin()\r{\r    std::string returnval = "127.0.0.1";\r   HKEY top, key;\r char* dns = NULL;\r\r     /* Lets see if the correct registry hive and tree exist */\r     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &top) == ERROR_SUCCESS)\r    {\r              /* If they do, attempt to get the nameserver name */\r           RegOpenKeyEx(top, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &key);\r              if ((GetNameServer(top, "NameServer", dns)) || (GetNameServer(top, "DhcpNameServer", dns))\r                     || (GetInterface(key, "NameServer", dns)) || (GetInterface(key, "DhcpNameServer", dns)))\r               {\r                      if (dns)\r                       {\r                              returnval = dns;\r                               delete dns;\r                    }\r              }\r              RegCloseKey(key);\r              RegCloseKey(top);\r      }\r      return returnval;\r}\r\r\rvoid ClearConsole()\r{\r    COORD coordScreen = { 0, 0 };    /* here's where we'll home the cursor */\r      HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);\r     DWORD cCharsWritten;\r   CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ \r     DWORD dwConSize;                 /* number of character cells in the current buffer */ \r\r       /* get the number of character cells in the current buffer */ \r\r        if (GetConsoleScreenBufferInfo( hConsole, &csbi ))\r     {\r              dwConSize = csbi.dwSize.X * csbi.dwSize.Y;\r             /* fill the entire screen with blanks */ \r              if (FillConsoleOutputCharacter( hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten ))\r               {\r                      /* get the current text attribute */ \r                  if (GetConsoleScreenBufferInfo( hConsole, &csbi ))\r                     {\r                              /* now set the buffer's attributes accordingly */\r                              if (FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten ))\r                          {\r                                      /* put the cursor at (0, 0) */\r                                 SetConsoleCursorPosition( hConsole, coordScreen );\r                             }\r                      }\r              }\r      }\r      return;\r}\r
\ No newline at end of file
+/*       +------------------------------------+
+ *       | Inspire Internet Relay Chat Daemon |
+ *       +------------------------------------+
+ *
+ *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ *            the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+#include "inspircd_win32wrapper.h"
+#include "inspircd.h"
+#include <string>
+#include <errno.h>
+#include <assert.h>
+using namespace std;
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+HANDLE hIPCPipe;
+
+int inet_aton(const char *cp, struct in_addr *addr)
+{
+       unsigned long ip = inet_addr(cp);
+       addr->s_addr = ip;
+       return (addr->s_addr == INADDR_NONE) ? 0 : 1;
+}
+
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
+{
+
+       if (af == AF_INET)
+       {
+               struct sockaddr_in in;
+               memset(&in, 0, sizeof(in));
+               in.sin_family = AF_INET;
+               memcpy(&in.sin_addr, src, sizeof(struct in_addr));
+               getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
+               return dst;
+       }
+       else if (af == AF_INET6)
+       {
+               struct sockaddr_in6 in;
+               memset(&in, 0, sizeof(in));
+               in.sin6_family = AF_INET6;
+               memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
+               getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
+               return dst;
+       }
+       return NULL;
+}
+
+int geteuid()
+{
+       return 1;
+}
+
+int inet_pton(int af, const char *src, void *dst)
+{
+       sockaddr_in sa;
+       int len = sizeof(SOCKADDR);
+       int rv = WSAStringToAddress((LPSTR)src, af, NULL, (LPSOCKADDR)&sa, &len);
+       if(rv >= 0)
+       {
+               if(WSAGetLastError() == 10022)                  // Invalid Argument
+                       rv = 0;
+               else
+                       rv = 1;
+       }
+       memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));
+       return rv;
+}
+
+char * strtok_r(char *_String, const char *_Control, char **_Context)
+{
+       unsigned char *str;
+       const unsigned char *ctl = (const unsigned char*)_Control;
+       unsigned char map[32];
+
+       if (_Context == 0 || !_Control)
+               return 0;
+
+       if (!(_String != NULL || *_Context != NULL))
+               return 0;
+
+       memset(map, 0, 32);
+
+       do {
+               map[*ctl >> 3] |= (1 << (*ctl & 7));
+       } while (*ctl++);
+
+       /* If string is NULL, set str to the saved
+       * pointer (i.e., continue breaking tokens out of the string
+       * from the last strtok call) */
+       if (_String != NULL)
+       {
+               str = (unsigned char*)_String;
+       }
+       else
+       {
+               str = (unsigned char*)*_Context;
+       }
+
+       /* Find beginning of token (skip over leading delimiters). Note that
+       * there is no token iff this loop sets str to point to the terminal
+       * null (*str == 0) */
+       while ((map[*str >> 3] & (1 << (*str & 7))) && *str != 0)
+       {
+               str++;
+       }
+
+       _String = (char*)str;
+
+       /* Find the end of the token. If it is not the end of the string,
+       * put a null there. */
+       for ( ; *str != 0 ; str++ )
+       {
+               if (map[*str >> 3] & (1 << (*str & 7)))
+               {
+                       *str++ = 0;
+                       break;
+               }
+       }
+
+       /* Update context */
+       *_Context = (char*)str;
+
+       /* Determine if a token has been found. */
+       if (_String == (char*)str)
+       {
+               return NULL;
+       }
+       else
+       {
+               return _String;
+       }
+}
+
+void setcolor(int color_code)
+{
+       SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color_code);
+}
+
+DIR * opendir(const char * path)
+{
+       std::string search_path = string(path) + "\\*.*";
+       WIN32_FIND_DATA fd;
+       HANDLE f = FindFirstFile(search_path.c_str(), &fd);
+       if (f != INVALID_HANDLE_VALUE)
+       {
+               DIR * d = new DIR;
+               memcpy(&d->find_data, &fd, sizeof(WIN32_FIND_DATA));
+               d->find_handle = f;
+               d->first = true;
+               return d;
+       }
+       else
+       {
+               return 0;
+       }
+}
+
+dirent * readdir(DIR * handle)
+{
+       if (handle->first)
+               handle->first = false;
+       else
+       {
+               if (!FindNextFile(handle->find_handle, &handle->find_data))
+                       return 0;
+       }
+
+       strncpy(handle->dirent_pointer.d_name, handle->find_data.cFileName, MAX_PATH);
+       return &handle->dirent_pointer;
+}
+
+void closedir(DIR * handle)
+{
+       FindClose(handle->find_handle);
+       delete handle;
+}
+
+const char * dlerror()
+{
+       static char errormessage[500];
+       DWORD error = GetLastError();
+       SetLastError(0);
+       if (error == 0)
+               return 0;
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)errormessage, 500, 0);
+       return errormessage;
+}
+
+#define TRED FOREGROUND_RED | FOREGROUND_INTENSITY
+#define TGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
+#define TYELLOW FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
+#define TNORMAL FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE
+#define TWHITE TNORMAL | FOREGROUND_INTENSITY
+#define TBLUE FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY
+
+/* Handles colors in printf */
+int printf_c(const char * format, ...)
+{
+       // Better hope we're not multithreaded, otherwise we'll have chickens crossing the road other side to get the to :P
+       static char message[MAXBUF];
+       static char temp[MAXBUF];
+       int color1, color2;
+
+       /* parse arguments */
+       va_list ap;
+       va_start(ap, format);
+       vsnprintf(message, 500, format, ap);
+       va_end(ap);
+
+       /* search for unix-style escape sequences */
+       int t;
+       int c = 0;
+       const char * p = message;
+       while (*p != 0)
+       {
+               if (*p == '\033')
+               {
+                       // Escape sequence -> copy into the temp buffer, and parse the color.
+                       p++;
+                       t = 0;
+                       while ((*p) && (*p != 'm'))
+                       {
+                               temp[t++] = *p;
+                               ++p;
+                       }
+
+                       temp[t] = 0;
+                       p++;
+
+                       if (*temp == '[')
+                       {
+                               if (sscanf(temp, "[%u;%u", &color1, &color2) == 2)
+                               {
+                                       switch(color2)
+                                       {
+                                       case 32:                // Green
+                                               SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);              // Yellow
+                                               break;
+
+                                       default:                // Unknown
+                                               // White
+                                               SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                               break;
+                                       }
+                               }
+                               else
+                               {
+                                       switch (*(temp+1))
+                                       {
+                                               case '0':
+                                                       // Returning to normal colour.
+                                                       SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
+                                                       break;
+
+                                               case '1':
+                                                       // White
+                                                       SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), TWHITE);
+                                                       break;
+
+                                               default:
+                                                       char message[50];
+                                                       sprintf(message, "Unknown color code: %s", temp);
+                                                       MessageBox(0, message, message, MB_OK);
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+
+               putchar(*p);
+               ++c;
+               ++p;
+       }
+
+       return c;
+}
+
+int arg_counter = 1;
+char optarg[514];
+int getopt_long_only(int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind)
+{
+       // burlex todo: handle the shortops, at the moment it only works with longopts.
+
+       if (___argc == 1 || arg_counter == ___argc)                     // No arguments (apart from filename)
+               return -1;
+
+       const char * opt = ___argv[arg_counter];
+       int return_val = 0;
+
+       // if we're not an option, return an error.
+       if (strnicmp(opt, "--", 2) != 0)
+               return 1;
+       else
+               opt += 2;
+
+
+       // parse argument list
+       int i = 0;
+       for (; __longopts[i].name != 0; ++i)
+       {
+               if (!strnicmp(__longopts[i].name, opt, strlen(__longopts[i].name)))
+               {
+                       // woot, found a valid argument =)
+                       char * par = 0;
+                       if ((arg_counter + 1) != ___argc)
+                       {
+                               // grab the parameter from the next argument (if its not another argument)
+                               if (strnicmp(___argv[arg_counter+1], "--", 2) != 0)
+                               {
+                                       arg_counter++;          // Trash this next argument, we won't be needing it.
+                                       par = ___argv[arg_counter];
+                               }
+                       }                       
+
+                       // increment the argument for next time
+                       arg_counter++;
+
+                       // determine action based on type
+                       if (__longopts[i].has_arg == required_argument && !par)
+                       {
+                               // parameter missing and its a required parameter option
+                               return 1;
+                       }
+
+                       // store argument in optarg
+                       if (par)
+                               strncpy(optarg, par, 514);
+
+                       if (__longopts[i].flag != 0)
+                       {
+                               // this is a variable, we have to set it if this argument is found.
+                               *__longopts[i].flag = 1;
+                               return 0;
+                       }
+                       else
+                       {
+                               if (__longopts[i].val == -1 || par == 0)
+                                       return 1;
+                               
+                               return __longopts[i].val;
+                       }                       
+                       break;
+               }
+       }
+
+       // return 1 (invalid argument)
+       return 1;
+}
+
+/* IPC Messages */
+#define IPC_MESSAGE_REHASH     1
+#define IPC_MESSAGE_DIE                2
+#define IPC_MESSAGE_RESTART    3
+
+void InitIPC()
+{
+       static DWORD buflen = 1024;
+       static const char * pipename = "\\\\.\\mailslot\\Inspircd";
+       hIPCPipe = CreateMailslot(pipename, buflen, 0, 0);
+       if (hIPCPipe == INVALID_HANDLE_VALUE)
+               printf("IPC Pipe could not be created. Are you sure you didn't start InspIRCd twice?\n");
+}
+
+void CheckIPC(InspIRCd * Instance)
+{
+       if (hIPCPipe == INVALID_HANDLE_VALUE)
+               return;
+
+       DWORD bytes;
+       DWORD action;
+
+       BOOL res = ReadFile(hIPCPipe, &action, sizeof(DWORD), &bytes, 0);
+       if (!res)
+       {
+               if (GetLastError() != ERROR_SEM_TIMEOUT)
+                       Instance->Log(DEFAULT, "IPC Pipe Error %u: %s", GetLastError(), dlerror());
+               return;
+       }
+
+       switch (action)
+       {
+               case IPC_MESSAGE_REHASH:
+                       InspIRCd::Rehash(0);
+               break;
+               
+               case IPC_MESSAGE_DIE:
+                       InspIRCd::Exit(0);
+               break;
+
+               case IPC_MESSAGE_RESTART:
+                       Instance->Restart("IPC_MESSAGE_RESTART received by mailslot.");
+               break;
+       }
+}
+
+void CloseIPC()
+{
+       CloseHandle(hIPCPipe);
+}
+
+
+/* These three functions were created from looking at how ares does it
+ * (...and they look far tidier in C++)
+ */
+
+/* Get active nameserver */
+bool GetNameServer(HKEY regkey, const char *key, char* &output)
+{
+       DWORD size = 0;
+       DWORD result = RegQueryValueEx(regkey, key, 0, NULL, NULL, &size);
+       if (((result != ERROR_SUCCESS) && (result != ERROR_MORE_DATA)) || (!size))
+               return false;
+
+       output = new char[size+1];
+
+       if ((RegQueryValueEx(regkey, key, 0, NULL, (LPBYTE)output, &size) != ERROR_SUCCESS) || (!*output))
+       {
+               delete output;
+               return false;
+       }
+       return true;
+}
+
+/* Check a network interface for its nameserver */
+bool GetInterface(HKEY regkey, const char *key, char* &output)
+{
+       char buf[39];
+       DWORD size = 39;
+       int idx = 0;
+       HKEY top;
+
+       while (RegEnumKeyEx(regkey, idx++, buf, &size, 0, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
+       {
+               size = 39;
+               if (RegOpenKeyEx(regkey, buf, 0, KEY_QUERY_VALUE, &top) != ERROR_SUCCESS)
+                       continue;
+               int rc = GetNameServer(top, key, output);
+               RegCloseKey(top);
+               if (rc)
+                       return true;
+       }
+       return false;
+}
+
+
+std::string FindNameServerWin()
+{
+       std::string returnval = "127.0.0.1";
+       HKEY top, key;
+       char* dns = NULL;
+
+       /* Lets see if the correct registry hive and tree exist */
+       if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &top) == ERROR_SUCCESS)
+       {
+               /* If they do, attempt to get the nameserver name */
+               RegOpenKeyEx(top, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &key);
+               if ((GetNameServer(top, "NameServer", dns)) || (GetNameServer(top, "DhcpNameServer", dns))
+                       || (GetInterface(key, "NameServer", dns)) || (GetInterface(key, "DhcpNameServer", dns)))
+               {
+                       if (dns)
+                       {
+                               returnval = dns;
+                               delete dns;
+                       }
+               }
+               RegCloseKey(key);
+               RegCloseKey(top);
+       }
+       return returnval;
+}
+
+
+void ClearConsole()
+{
+       COORD coordScreen = { 0, 0 };    /* here's where we'll home the cursor */
+       HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+       DWORD cCharsWritten;
+       CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ 
+       DWORD dwConSize;                 /* number of character cells in the current buffer */ 
+
+       /* get the number of character cells in the current buffer */ 
+
+       if (GetConsoleScreenBufferInfo( hConsole, &csbi ))
+       {
+               dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
+               /* fill the entire screen with blanks */ 
+               if (FillConsoleOutputCharacter( hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten ))
+               {
+                       /* get the current text attribute */ 
+                       if (GetConsoleScreenBufferInfo( hConsole, &csbi ))
+                       {
+                               /* now set the buffer's attributes accordingly */
+                               if (FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten ))
+                               {
+                                       /* put the cursor at (0, 0) */
+                                       SetConsoleCursorPosition( hConsole, coordScreen );
+                               }
+                       }
+               }
+       }
+       return;
+}