]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - win/inspircd_win32wrapper.cpp
Remove printf_c from wrapper, this code also segfaulted when it was used.
[user/henk/code/inspircd.git] / win / inspircd_win32wrapper.cpp
index dbca07862df56edd57d5c108c3f2fe7fcb7a2e31..3a929d09e375bcc175e0d5fdeebaaf0761a5e54f 100644 (file)
@@ -1,3 +1,16 @@
+/*       +------------------------------------+\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
@@ -13,35 +26,33 @@ HANDLE hIPCPipe;
 \r
 int 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
+       unsigned long ip = inet_addr(cp);\r
+       addr->s_addr = ip;\r
+       return (addr->s_addr == INADDR_NONE) ? 0 : 1;\r
 }\r
 \r
 const 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\r
-            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\r
-            sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);\r
-        return dst;\r
-    }\r
-    return NULL;\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
 \r
 int geteuid()\r
@@ -51,81 +62,88 @@ int geteuid()
 \r
 int 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
-    memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));\r
-    return rv;\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
 \r
 char * 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
+       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
+       if (_Context == 0 || !_Control)\r
+               return 0;\r
 \r
-    if(!(_String != NULL || *_Context != NULL))\r
-        return 0;\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
+       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
 \r
 void setcolor(int color_code)\r
 {\r
-    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color_code);\r
+       SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color_code);\r
 }\r
 \r
 DIR * opendir(const char * path)\r
@@ -133,7 +151,7 @@ DIR * opendir(const char * path)
        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
+       if (f != INVALID_HANDLE_VALUE)\r
        {\r
                DIR * d = new DIR;\r
                memcpy(&d->find_data, &fd, sizeof(WIN32_FIND_DATA));\r
@@ -149,11 +167,11 @@ DIR * opendir(const char * path)
 \r
 dirent * readdir(DIR * handle)\r
 {\r
-       if(handle->first)\r
+       if (handle->first)\r
                handle->first = false;\r
        else\r
        {\r
-               if(!FindNextFile(handle->find_handle, &handle->find_data))\r
+               if (!FindNextFile(handle->find_handle, &handle->find_data))\r
                        return 0;\r
        }\r
 \r
@@ -172,94 +190,27 @@ const char * dlerror()
        static char errormessage[500];\r
        DWORD error = GetLastError();\r
        SetLastError(0);\r
-       if(error == 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
-int 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[500];\r
-       static char temp[10];\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 != 'm')\r
-                       {\r
-                               temp[t++] = *p;\r
-                               ++p;\r
-                       }\r
-                       \r
-                       temp[t] = 0;\r
-                       p++;\r
-                       if(!stricmp(temp, "[0"))\r
-                       {\r
-                               // Returning to normal colour.\r
-                               SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);\r
-                       }\r
-                       else 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
-                               char message[50];\r
-                               sprintf("Unknown color code: %s", temp);\r
-                               MessageBox(0, message, message, MB_OK);\r
-                       }\r
-               }\r
-\r
-               putchar(*p);\r
-               ++c;\r
-               ++p;\r
-       }\r
-\r
-       return c;\r
-}\r
-\r
 int arg_counter = 1;\r
 char optarg[514];\r
 int 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
+       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
+       if (strnicmp(opt, "--", 2) != 0)\r
                return 1;\r
        else\r
                opt += 2;\r
@@ -267,18 +218,18 @@ int getopt_long_only(int ___argc, char *const *___argv, const char *__shortopts,
 \r
        // parse argument list\r
        int i = 0;\r
-       for(; __longopts[i].name != 0; ++i)\r
+       for (; __longopts[i].name != 0; ++i)\r
        {\r
-        if(!strnicmp(__longopts[i].name, opt, strlen(__longopts[i].name)))\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
+                       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
+                               if (strnicmp(___argv[arg_counter+1], "--", 2) != 0)\r
                                {\r
-                    arg_counter++;             // Trash this next argument, we won't be needing it.\r
+                                       arg_counter++;          // Trash this next argument, we won't be needing it.\r
                                        par = ___argv[arg_counter];\r
                                }\r
                        }                       \r
@@ -287,17 +238,17 @@ int getopt_long_only(int ___argc, char *const *___argv, const char *__shortopts,
                        arg_counter++;\r
 \r
                        // determine action based on type\r
-                       if(__longopts[i].has_arg == required_argument && !par)\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
+                       if (par)\r
                                strncpy(optarg, par, 514);\r
 \r
-            if(__longopts[i].flag != 0)\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
@@ -305,7 +256,7 @@ int getopt_long_only(int ___argc, char *const *___argv, const char *__shortopts,
                        }\r
                        else\r
                        {\r
-                               if(__longopts[i].val == -1 || par == 0)\r
+                               if (__longopts[i].val == -1 || par == 0)\r
                                        return 1;\r
                                \r
                                return __longopts[i].val;\r
@@ -327,43 +278,39 @@ void InitIPC()
 {\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
+       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
 \r
 void CheckIPC(InspIRCd * Instance)\r
 {\r
-       if(hIPCPipe == INVALID_HANDLE_VALUE)\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
+       if (!res)\r
        {\r
-               if(GetLastError() != ERROR_SEM_TIMEOUT)\r
-                       printf("IPC Pipe Error %u: %s", GetLastError(), dlerror());\r
+               if (GetLastError() != ERROR_SEM_TIMEOUT)\r
+                       Instance->Log(DEFAULT, "IPC Pipe Error %u: %s", GetLastError(), dlerror());\r
                return;\r
        }\r
 \r
-       printf("Got IPC Message: %u\n", action);\r
-       switch(action)\r
+       switch (action)\r
        {\r
-       case IPC_MESSAGE_REHASH:\r
-               printf("Rehashing...\n");\r
-               InspIRCd::Rehash(0);\r
+               case IPC_MESSAGE_REHASH:\r
+                       InspIRCd::Rehash(0);\r
                break;\r
                \r
-       case IPC_MESSAGE_DIE:\r
-               printf("Shutting down...\n");\r
-               InspIRCd::Exit(0);\r
+               case IPC_MESSAGE_DIE:\r
+                       InspIRCd::Exit(0);\r
                break;\r
 \r
-       case IPC_MESSAGE_RESTART:\r
-               printf("Restarting...\n");\r
-               Instance->Restart("IPC_MESSAGE_RESTART received by mailslot.");\r
+               case IPC_MESSAGE_RESTART:\r
+                       Instance->Restart("IPC_MESSAGE_RESTART received by mailslot.");\r
                break;\r
        }\r
 }\r
@@ -373,3 +320,105 @@ void CloseIPC()
        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 */\r
+bool 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 */\r
+bool 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
+\r
+std::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
+\r
+void 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