+/* +------------------------------------+\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
\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
\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
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
\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
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
\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
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
}\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
{\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
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