]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - win/configure.cpp
Module class has a member ServerInstance, so remove any extra refs still lingering...
[user/henk/code/inspircd.git] / win / configure.cpp
1 #define _CRT_SECURE_NO_DEPRECATE\r
2 \r
3 #include <windows.h>\r
4 #include <stdio.h>\r
5 #include <string>\r
6 #include <time.h>\r
7 #include "colours.h"\r
8 \r
9 using namespace std;\r
10 void Run();\r
11 void Banner();\r
12 void WriteCompileModules();\r
13 void WriteCompileCommands();\r
14 \r
15 /* detects if we are running windows xp or higher (5.1) */\r
16 bool iswinxp()\r
17 {\r
18         OSVERSIONINFO vi;\r
19         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
20         GetVersionEx(&vi);\r
21         if(vi.dwMajorVersion >= 5)\r
22                 return true;\r
23         \r
24         return false;\r
25 }\r
26 \r
27 int get_int_option(const char * text, int def)\r
28 {\r
29         static char buffer[500];\r
30         int ret;\r
31         printf_c("%s\n[\033[1;32m%u\033[0m] -> ", text, def);\r
32         fgets(buffer, 500, stdin);\r
33         if(sscanf(buffer, "%u", &ret) != 1)\r
34                 ret = def;\r
35 \r
36         printf("\n");\r
37         return ret;\r
38 }\r
39 \r
40 bool get_bool_option(const char * text, bool def)\r
41 {\r
42         static char buffer[500];\r
43         char ret[100];\r
44         printf_c("%s [\033[1;32m%c\033[0m] -> ", text, def ? 'y' : 'n');\r
45         fgets(buffer, 500, stdin);\r
46         if(sscanf(buffer, "%s", ret) != 1)\r
47                 strcpy(ret, def ? "y" : "n");\r
48 \r
49         printf("\n");\r
50         return !strncmp(ret, "y", 1);\r
51 }\r
52 \r
53 void get_string_option(const char * text, char * def, char * buf)\r
54 {\r
55         static char buffer[500];\r
56         printf_c("%s\n[\033[1;32m%s\033[0m] -> ", text, def);\r
57         fgets(buffer, 500, stdin);\r
58         if(sscanf(buffer, "%s", buf) != 1)\r
59                 strcpy(buf, def);\r
60 \r
61         printf("\n");\r
62 }\r
63 \r
64 // escapes a string for use in a c++ file\r
65 bool escape_string(char * str, size_t size)\r
66 {\r
67         size_t len = strlen(str);\r
68         char * d_str = (char*)malloc(len * 2);\r
69     \r
70         size_t i = 0;\r
71         size_t j = 0;\r
72 \r
73         for(; i < len; ++i)\r
74         {\r
75                 if(str[i] == '\\')\r
76                 {\r
77                         d_str[j++] = '\\';\r
78                         d_str[j++] = '\\';\r
79                 }\r
80                 else\r
81                 {\r
82                         d_str[j++] = str[i];\r
83                 }\r
84         }\r
85 \r
86         d_str[j++] = 0;\r
87 \r
88     if(j > size)\r
89         {\r
90                 free(d_str);\r
91                 return false;\r
92         }\r
93 \r
94         strcpy(str, d_str);\r
95         free(d_str);\r
96         return true;\r
97 }\r
98 \r
99 /* gets the svn revision */\r
100 int get_svn_revision(char * buffer, size_t len)\r
101 {\r
102         /* again.. I am lazy :p cbf to pipe output of svn info to us, so i'll just read the file */\r
103         /*\r
104         8\r
105 \r
106         dir\r
107         7033\r
108         */\r
109         char buf[1000];\r
110         FILE * f = fopen("..\\.svn\\entries", "r");\r
111         if(!f) goto bad_rev;\r
112     \r
113         if(!fgets(buf, 1000, f)) goto bad_rev;\r
114         if(!fgets(buf, 1000, f)) goto bad_rev;\r
115         if(!fgets(buf, 1000, f)) goto bad_rev;\r
116         if(!fgets(buf, 1000, f)) goto bad_rev;\r
117         int rev = atoi(buf);\r
118         if(rev == 0) goto bad_rev;\r
119         sprintf(buffer, "%u", rev);\r
120         fclose(f);\r
121         return rev;\r
122         \r
123 bad_rev:\r
124         strcpy(buffer, "non-svn");\r
125         if(f) fclose(f);\r
126         return 0;\r
127 }\r
128 \r
129 int __stdcall WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )\r
130 {\r
131         AllocConsole();\r
132 \r
133         // pipe standard handles to this console\r
134         freopen("CONIN$", "r", stdin);\r
135         freopen("CONOUT$", "w", stdout);\r
136         freopen("CONOUT$", "w", stderr);\r
137 \r
138         Banner();\r
139         Run();\r
140         WriteCompileCommands();\r
141         WriteCompileModules();\r
142         FreeConsole();\r
143         return 0;\r
144 }\r
145 \r
146 void Banner()\r
147 {\r
148         printf_c("\nWelcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)\n"\r
149                          "\033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m\n\n");\r
150         printf_c("*** If you are unsure of any of these values, leave it blank for    ***\n"\r
151                          "*** standard settings that will work, and your server will run      ***\n"\r
152                          "*** using them. Please consult your IRC network admin if in doubt.  ***\n\n"\r
153                          "Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter\n"\r
154                          "a new value. Please note: You will \033[1mHAVE\033[0m to read the docs\n"\r
155                          "dir, otherwise you won't have a config file!\n\n");\r
156 \r
157 }\r
158 \r
159 void Run()\r
160 {\r
161         int max_fd = 1024;\r
162         bool use_iocp = false;\r
163         bool support_ip6links = false;\r
164         char mod_path[MAX_PATH];\r
165         char config_file[MAX_PATH];\r
166         char library_dir[MAX_PATH];\r
167         char base_path[MAX_PATH];\r
168         char bin_dir[MAX_PATH];\r
169         char revision_text[MAX_PATH];\r
170 \r
171         int max_clients = 1024;\r
172         int nicklen = 31;\r
173         int chanlen = 64;\r
174         int modechanges = 20;\r
175         int identlen = 12;\r
176         int quitlen = 255;\r
177         int topiclen = 500;\r
178         int kicklen = 255;\r
179         int rllen = 128;\r
180         int awaylen = 200;\r
181         int revision = get_svn_revision(revision_text, MAX_PATH);\r
182         char version[514];\r
183 \r
184         // grab version\r
185         FILE * fI = fopen("..\\src\\version.sh", "r");\r
186         if(fI)\r
187         {\r
188                 fgets(version, 514, fI);\r
189                 fgets(version, 514, fI);\r
190                 char * p2 = version;\r
191                 while(*p2 != '\"')\r
192                         ++p2;\r
193                 ++p2;\r
194                 strcpy(version, p2);\r
195                 p2 = version;\r
196                 while(*p2 != '\"')\r
197                         ++p2;\r
198                 *p2 = 0;\r
199                 fclose(fI);\r
200         }\r
201         else\r
202                 strcpy(version, "InspIRCD-Unknown");\r
203         printf_c("Your operating system is: \033[1;32mwindows \033[0m\n");\r
204         printf_c("InspIRCd revision ID: \033[1;32m%s \033[0m\n\n", revision ? revision_text : "(Non-SVN build)");\r
205 \r
206         max_fd = get_int_option("What is the maximum file descriptor count you would like to allow?", 1024);\r
207 \r
208         // detect windows\r
209         if(iswinxp())\r
210         {\r
211                 printf_c("You are running Windows 2000 or above, and IOCP support is most likely available.\n"\r
212                              "This removes the socket number limitation of select and is much more efficent.\n"\r
213                                  "If you are unsure, answer yes.\n\n");\r
214 \r
215                 use_iocp = get_bool_option("Do you want to use the IOCP implementation?", true);\r
216         }\r
217 \r
218         support_ip6links = get_bool_option("\nYou have chosen to build an \033[1;32mIPV4-only\033[0m server.\nWould you like to enable support for linking to IPV6-enabled InspIRCd servers?\nIf you are using a recent operating system and are unsure, answer yes.\nIf you answer 'no' here, your InspIRCd server will be unable\nto parse IPV6 addresses (e.g. for CIDR bans)", \r
219                 true);\r
220         \r
221         printf_c("\033[1mAll paths are relative to the binary directory.\033[0m\n");\r
222         get_string_option("In what directory do you wish to install the InspIRCd base?", "..", base_path);\r
223         get_string_option("In what directory are the configuration files?", "../conf", config_file);\r
224         get_string_option("In what directory are the modules to be compiled to?", "../modules", mod_path);\r
225         get_string_option("In what directory is the IRCd binary to be placed?", ".", bin_dir);\r
226         get_string_option("In what directory are the IRCd libraries to be placed?", "../lib", library_dir);\r
227 \r
228         printf_c("The following questions will ask you for various figures relating\n"\r
229                 "To your IRCd install. Please note that these should usually be left\n"\r
230                 "as defaults unless you have a real reason to change them. If they\n"\r
231                 "changed, then the values must be identical on all servers on your\n"\r
232                 "network, or malfunctions and/or crashes may occur, with the exception\n"\r
233                 "of the 'maximum number of clients' setting which may be different on\n"\r
234                 "different servers on the network.\n\n");\r
235 \r
236     \r
237         max_clients = get_int_option("Please enter the maximum number of clients at any one time?", 1024);\r
238         nicklen = get_int_option("Please enter the maximum length of nicknames?", 31);\r
239         chanlen = get_int_option("Please enter the maximum length of channel names?", 64);\r
240         modechanges = get_int_option("Please enter the maximum number of mode changes in one line?", 20);\r
241         identlen = get_int_option("Please enter the maximum length of an ident (username)?", 12);\r
242         quitlen = get_int_option("Please enter the maximum length of a quit message?", 255);\r
243         topiclen = get_int_option("Please enter the maximum length of a channel topic?", 307);\r
244         kicklen = get_int_option("Please enter the maximum length of a kick message?", 255);\r
245         rllen = get_int_option("Please enter the maximum length of a GECOS (real name)?", 128);\r
246         awaylen = get_int_option("Please enter the maximum length of an away message?", 200);\r
247 \r
248         printf_c("\n\033[1;32mPre-build configuration is complete!\n\n");       sc(TNORMAL);\r
249 \r
250         // dump all the options back out\r
251         printf_c("\033[0mBase install path:\033[1;32m        %s\n", base_path);\r
252         printf_c("\033[0mConfig path:\033[1;32m              %s\n", config_file);\r
253         printf_c("\033[0mModule path:\033[1;32m              %s\n", mod_path);\r
254         printf_c("\033[0mLibrary path:\033[1;32m             %s\n", library_dir);\r
255         printf_c("\033[0mSocket Engine:\033[1;32m            %s\n", use_iocp ? "iocp" : "select");\r
256         printf_c("\033[0mMax file descriptors:\033[1;32m     %u\n", max_fd);\r
257         printf_c("\033[0mMax connections:\033[1;32m          %u\n", max_clients);\r
258         printf_c("\033[0mMax nickname length:\033[1;32m      %u\n", nicklen);\r
259         printf_c("\033[0mMax channel length:\033[1;32m       %u\n", chanlen);\r
260         printf_c("\033[0mMax mode length:\033[1;32m          %u\n", modechanges);\r
261         printf_c("\033[0mMax ident length:\033[1;32m         %u\n", identlen);\r
262         printf_c("\033[0mMax quit length:\033[1;32m          %u\n", quitlen);\r
263         printf_c("\033[0mMax topic length:\033[1;32m         %u\n", topiclen);\r
264         printf_c("\033[0mMax kick length:\033[1;32m          %u\n", kicklen);\r
265         printf_c("\033[0mMax name length:\033[1;32m          %u\n", rllen);\r
266         printf_c("\033[0mMax away length:\033[1;32m          %u\n", awaylen);\r
267         printf("\n"); sc(TNORMAL);\r
268         if(get_bool_option("Are these settings correct?", true) == false)\r
269         {\r
270                 Run();\r
271                 return;\r
272         }\r
273         printf("\n");\r
274 \r
275         // escape the pathes\r
276         escape_string(config_file, MAX_PATH);\r
277         escape_string(mod_path, MAX_PATH);\r
278         escape_string(library_dir, MAX_PATH);\r
279 \r
280         printf("\nWriting inspircd_config.h...");\r
281         FILE * f = fopen("inspircd_config.h", "w");\r
282         fprintf(f, "/* Auto generated by configure, do not modify! */\n");\r
283         fprintf(f, "#ifndef __CONFIGURATION_AUTO__\n");\r
284         fprintf(f, "#define __CONFIGURATION_AUTO__\n\n");\r
285         if(use_iocp)\r
286                 fprintf(f, "#define CONFIG_USE_IOCP 1\n\n");\r
287 \r
288         fprintf(f, "#define CONFIG_FILE \"%s/inspircd.conf\"\n", config_file);\r
289         fprintf(f, "#define MOD_PATH \"%s\"\n", mod_path);\r
290         fprintf(f, "#define MAX_DESCRIPTORS %u\n", max_fd);\r
291         fprintf(f, "#define MAXCLIENTS %u\n", max_clients);\r
292         fprintf(f, "#define MAXCLIENTS_S \"%u\"\n", max_clients);\r
293         fprintf(f, "#define SOMAXCONN_S \"128\"\n");\r
294         fprintf(f, "#define NICKMAX %u\n", nicklen+1);\r
295         fprintf(f, "#define CHANMAX %u\n", chanlen+1);\r
296         fprintf(f, "#define MAXMODES %u\n", modechanges);\r
297         fprintf(f, "#define IDENTMAX %u\n", identlen);\r
298         fprintf(f, "#define MAXQUIT %u\n", quitlen);\r
299         fprintf(f, "#define MAXTOPIC %u\n", topiclen);\r
300         fprintf(f, "#define MAXKICK %u\n", kicklen);\r
301         fprintf(f, "#define MAXGECOS %u\n", rllen);\r
302         fprintf(f, "#define MAXAWAY %u\n", awaylen);\r
303         fprintf(f, "#define LIBRARYDIR \"%s\"\n", library_dir);\r
304         fprintf(f, "#define VERSION \"%s\"\n", version);\r
305         fprintf(f, "#define REVISION \"%s\"\n", revision_text);\r
306         if(support_ip6links)\r
307                 fprintf(f, "#define SUPPORT_IP6LINKS 1\n");\r
308 \r
309         OSVERSIONINFO vi;\r
310         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
311         GetVersionEx(&vi);\r
312         fprintf(f, "#define SYSTEM \"Windows %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);\r
313         fprintf(f, "#define MAXBUF 514\n");\r
314 \r
315         fprintf(f, "\n#include \"inspircd_win32wrapper.h\"\n\n");\r
316         fprintf(f, "#endif\n\n");\r
317         fclose(f);\r
318 \r
319         sc(TGREEN); printf(" done\n"); sc(TNORMAL);\r
320         printf("Writing inspircd_se_config.h...");\r
321 \r
322         f = fopen("inspircd_se_config.h", "w");\r
323         fprintf(f, "/* Auto generated by configure, do not modify or commit to svn! */\n");\r
324         fprintf(f, "#ifndef __CONFIGURATION_SOCKETENGINE__\n");\r
325         fprintf(f, "#define __CONFIGURATION_SOCKETENGINE__\n\n");\r
326         fprintf(f, "#include \"socketengine_%s.h\"\n\n", use_iocp ? "iocp" : "select");\r
327         fprintf(f, "#endif\n\n");\r
328         fclose(f);\r
329 \r
330         sc(TGREEN); printf(" done\n"); sc(TNORMAL);\r
331         printf("Writing command and module compilation scripts...");\r
332         WriteCompileCommands();\r
333         WriteCompileModules();\r
334         sc(TGREEN); printf(" done\n"); sc(TNORMAL);\r
335 \r
336         printf("\nconfigure is done.. exiting!\n");\r
337 }\r
338 \r
339 void WriteCompileCommands()\r
340 {\r
341         char commands[300][100];\r
342         int command_count = 0;\r
343         printf("\n  Finding Command Sources...\n");\r
344         WIN32_FIND_DATA fd;\r
345         HANDLE fh = FindFirstFile("..\\src\\cmd_*.cpp", &fd);\r
346         if(fh == INVALID_HANDLE_VALUE)\r
347                 printf_c("\033[1;32m  No command sources could be found! This \033[1m*could*\033[1;32m be a bad thing.. :P\033[0m");\r
348         else\r
349         {\r
350                 sc(TGREEN);\r
351                 do \r
352                 {\r
353                         strcpy(commands[command_count], fd.cFileName);\r
354                         commands[command_count][strlen(fd.cFileName) - 4] = 0;\r
355                         printf("    %s\n", commands[command_count]);\r
356                         ++command_count;\r
357                 } while(FindNextFile(fh, &fd));\r
358                 sc(TNORMAL);\r
359         }\r
360     \r
361         // Write our spiffy new makefile :D\r
362         // I am such a lazy fucker :P\r
363         FILE * f = fopen("..\\src\\commands.mak", "w");\r
364 \r
365         time_t t = time(NULL);\r
366         fprintf(f, "# Generated at %s\n", ctime(&t));\r
367         fprintf(f, "all: makedir ");\r
368 \r
369         // dump modules.. first time :)\r
370         for(int i = 0; i < command_count; ++i)\r
371                 fprintf(f, "%s.so ", commands[i]);\r
372 \r
373         fprintf(f, "\n.cpp.obj:\n");\r
374 #ifdef _DEBUG\r
375         fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../include\" /I \"../include/modes\" /I \"../include/commands\" /I \"../win\" /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /Gm /EHsc /GS /RTC1 /MTd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W3 /Wp64 /Zi /TP $*.cpp ..\\win\\inspircd_memory_functions.cpp /link ..\\bin\\debug\\bin\\inspircd.lib /OUT:\"..\\bin\\debug\\lib\\$*.so\" /PDB:\"..\\bin\\debug\\lib\\$*.pdb\" /IMPLIB:\"..\\bin\\debug\\lib\\$*.lib\"\n\n");\r
376         CreateDirectory("..\\src\\debug", NULL);\r
377         CreateDirectory("..\\bin\\debug\\bin", NULL);\r
378         CreateDirectory("..\\bin\\debug\\lib", NULL);\r
379         CreateDirectory("..\\bin\\debug\\modules", NULL);\r
380 #else\r
381         fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../include\" /I \"../include/modes\" /I \"../include/commands\" /I \"../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /GS /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W3 /Wp64 /Zi /TP $*.cpp ..\\win\\inspircd_memory_functions.cpp /link ..\\bin\\release\\bin\\inspircd.lib /OUT:\"..\\bin\\release\\lib\\$*.so\" /PDB:\"..\\bin\\release\\lib\\$*.pdb\" /IMPLIB:\"..\\bin\\release\\lib\\$*.lib\"\n\n");\r
382         CreateDirectory("..\\src\\release", NULL);\r
383         CreateDirectory("..\\bin\\release\\bin", NULL);\r
384         CreateDirectory("..\\bin\\release\\lib", NULL);\r
385         CreateDirectory("..\\bin\\release\\modules", NULL);\r
386 #endif\r
387 \r
388         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n\n");\r
389         \r
390         // dump modules.. again the second and last time :)\r
391         for(int i = 0; i < command_count; ++i)\r
392                 fprintf(f, "%s.so : %s.obj\n", commands[i], commands[i]);\r
393 \r
394         fprintf(f, "\n");\r
395         fclose(f);\r
396 }\r
397 \r
398 void WriteCompileModules()\r
399 {\r
400         char modules[300][100];\r
401         int module_count = 0;\r
402 \r
403         printf("Finding Modules...\n");\r
404         WIN32_FIND_DATA fd;\r
405         HANDLE fh = FindFirstFile("..\\src\\modules\\m_*.cpp", &fd);\r
406         if(fh == INVALID_HANDLE_VALUE)\r
407                 printf_c("\033[1;32m  No module sources could be found! This \033[1m*could*\033[1;32m be a bad thing.. :P\033[0m");\r
408         else\r
409         {\r
410                 sc(TGREEN);\r
411                 do \r
412                 {\r
413                         strcpy(modules[module_count], fd.cFileName);\r
414                         modules[module_count][strlen(fd.cFileName) - 4] = 0;\r
415                         printf("  %s\n", modules[module_count]);\r
416                         ++module_count;\r
417                 } while(FindNextFile(fh, &fd));\r
418                 sc(TNORMAL);\r
419         }\r
420 \r
421         // Write our spiffy new makefile :D\r
422         // I am such a lazy fucker :P\r
423         FILE * f = fopen("..\\src\\modules\\modules.mak", "w");\r
424 \r
425         time_t t = time(NULL);\r
426         fprintf(f, "# Generated at %s\n", ctime(&t));\r
427         fprintf(f, "all: makedir ");\r
428 \r
429         // dump modules.. first time :)\r
430         for(int i = 0; i < module_count; ++i)\r
431                 fprintf(f, "%s.so ", modules[i]);\r
432 \r
433         fprintf(f, "\n.cpp.obj:\n");\r
434 #ifdef _DEBUG\r
435         fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /Gm /EHsc /GS /RTC1 /MTd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W3 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\debug\\modules\\$*.so\" /PDB:\"..\\..\\bin\\debug\\modules\\$*.pdb\" /IMPLIB:\"..\\..\\bin\\debug\\modules\\$*.lib\"\n\n");\r
436         CreateDirectory("..\\src\\modules\\debug", NULL);\r
437 #else\r
438         fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /GS /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W3 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\release\\modules\\$*.so\" /PDB:\"..\\..\\bin\\release\\modules\\$*.pdb\" /IMPLIB:\"..\\..\\bin\\release\\modules\\$*.lib\"\n\n");\r
439         CreateDirectory("..\\src\\modules\\release", NULL);\r
440 #endif\r
441         \r
442         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n\n");\r
443 \r
444         // dump modules.. again the second and last time :)\r
445         for(int i = 0; i < module_count; ++i)\r
446                 fprintf(f, "%s.so : %s.obj\n", modules[i], modules[i]);\r
447 \r
448         fprintf(f, "\n");\r
449         fclose(f);\r
450 }\r