]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - win/configure.cpp
a72a95b73b58dfc5334705e4cd7ddfb332799994
[user/henk/code/inspircd.git] / win / configure.cpp
1 /*         +------------------------------------+
2  *         | Inspire Internet Relay Chat Daemon |
3  *         +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *                      the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #define _CRT_SECURE_NO_DEPRECATE
15
16 #define WIN32_LEAN_AND_MEAN
17 #include <windows.h>
18 #include <stdio.h>
19 #include <string>
20 #include <time.h>
21 #include "inspircd_win32wrapper.h"
22 #include "colours.h"
23
24 using namespace std;
25 void Run();
26 void Banner();
27 void WriteCompileModules();
28 void WriteCompileCommands();
29
30 /* detects if we are running windows xp or higher (5.1) */
31 bool iswinxp()
32 {
33         OSVERSIONINFO vi;
34         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
35         GetVersionEx(&vi);
36         if(vi.dwMajorVersion >= 5)
37                 return true;
38         
39         return false;
40 }
41
42 int get_int_option(const char * text, int def)
43 {
44         static char buffer[500];
45         int ret;
46         printf_c("%s\n[\033[1;32m%u\033[0m] -> ", text, def);
47         fgets(buffer, 500, stdin);
48         if(sscanf(buffer, "%u", &ret) != 1)
49                 ret = def;
50
51         printf("\n");
52         return ret;
53 }
54
55 bool get_bool_option(const char * text, bool def)
56 {
57         static char buffer[500];
58         char ret[100];
59         printf_c("%s [\033[1;32m%c\033[0m] -> ", text, def ? 'y' : 'n');
60         fgets(buffer, 500, stdin);
61         if(sscanf(buffer, "%s", ret) != 1)
62                 strcpy(ret, def ? "y" : "n");
63
64         printf("\n");
65         return !strncmp(ret, "y", 1);
66 }
67
68 void get_string_option(const char * text, char * def, char * buf)
69 {
70         static char buffer[500];
71         if (*def)
72                 printf_c("%s\n[\033[1;32m%s\033[0m] -> ", text, def);
73         else
74                 printf_c("%s\n[] -> ", text);
75         fgets(buffer, 500, stdin);
76         if(sscanf(buffer, "%s", buf) != 1)
77                 strcpy(buf, def);
78
79         printf("\n");
80 }
81
82 // escapes a string for use in a c++ file
83 bool escape_string(char * str, size_t size)
84 {
85         size_t len = strlen(str);
86         char * d_str = (char*)malloc(len * 2);
87         
88         size_t i = 0;
89         size_t j = 0;
90
91         for(; i < len; ++i)
92         {
93                 if(str[i] == '\\')
94                 {
95                         d_str[j++] = '\\';
96                         d_str[j++] = '\\';
97                 }
98                 else
99                 {
100                         d_str[j++] = str[i];
101                 }
102         }
103
104         d_str[j++] = 0;
105
106         if(j > size)
107         {
108                 free(d_str);
109                 return false;
110         }
111
112         strcpy(str, d_str);
113         free(d_str);
114         return true;
115 }
116
117 /* gets the svn revision */
118 int get_svn_revision(char * buffer, size_t len)
119 {
120         /* again.. I am lazy :p cbf to pipe output of svn info to us, so i'll just read the file */
121         /*
122         8
123
124         dir
125         7033
126         */
127         char buf[1000];
128         int rev = 0;
129         
130         FILE * f = fopen("..\\.svn\\entries", "r");
131         if (f)
132         {
133                 for (int q = 0; q < 4; ++q)
134                         fgets(buf, 1000, f);
135
136                 rev = atoi(buf);
137                 sprintf(buffer, "%u", rev);
138                 fclose(f);
139         }
140         
141         return rev;
142         
143 bad_rev:
144         strcpy(buffer, "non-svn");
145         if(f) fclose(f);
146         return 0;
147 }
148
149 int __stdcall WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )
150 {
151         FILE * j = fopen("inspircd_config.h", "r");
152         if (j)
153         {
154                 if (MessageBox(0, "inspircd_config.h already exists. Remove it and build from clean?", "Configure program", MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2) != IDYES)
155                 {
156                         fclose(j);
157                         exit(0);
158                 }
159         }
160
161         AllocConsole();
162
163         // pipe standard handles to this console
164         freopen("CONIN$", "r", stdin);
165         freopen("CONOUT$", "w", stdout);
166         freopen("CONOUT$", "w", stderr);
167
168         Banner();
169         Run();
170         FreeConsole();
171         return 0;
172 }
173
174 void Banner()
175 {
176         printf_c("\nWelcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)\n"
177                          "\033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m\n\n");
178         printf_c("*** If you are unsure of any of these values, leave it blank for      ***\n"
179                          "*** standard settings that will work, and your server will run          ***\n"
180                          "*** using them. Please consult your IRC network admin if in doubt.  ***\n\n"
181                          "Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter\n"
182                          "a new value. Please note: You will \033[1mHAVE\033[0m to read the docs\n"
183                          "dir, otherwise you won't have a config file!\n\n");
184
185 }
186
187 void Run()
188 {
189         bool use_iocp = false;
190         bool support_ip6links = true;
191         bool use_openssl = false;
192         bool ipv6 = true;
193         char mod_path[MAX_PATH];
194         char config_file[MAX_PATH];
195         char library_dir[MAX_PATH];
196         char base_path[MAX_PATH];
197         char bin_dir[MAX_PATH];
198         char revision_text[MAX_PATH];
199         char openssl_inc_path[MAX_PATH];
200         char openssl_lib_path[MAX_PATH];
201
202         int nicklen = 31;
203         int chanlen = 64;
204         int modechanges = 20;
205         int identlen = 12;
206         int quitlen = 255;
207         int topiclen = 500;
208         int kicklen = 255;
209         int rllen = 128;
210         int awaylen = 200;
211         int revision = get_svn_revision(revision_text, MAX_PATH);
212         char version[514];
213
214         // grab version
215         FILE * fI = fopen("..\\src\\version.sh", "r");
216         if(fI)
217         {
218                 fgets(version, 514, fI);
219                 fgets(version, 514, fI);
220                 char * p2 = version;
221                 while(*p2 != '\"')
222                         ++p2;
223                 ++p2;
224                 strcpy(version, p2);
225                 p2 = version;
226                 while(*p2 != '\"')
227                         ++p2;
228                 *p2 = 0;
229                 fclose(fI);
230         }
231         else
232                 strcpy(version, "InspIRCD-Unknown");
233 #ifdef WIN64
234         printf_c("Your operating system is: \033[1;32mwindows_x64 \033[0m\n");
235 #else
236         printf_c("Your operating system is: \033[1;32mwindows_x32 \033[0m\n");
237 #endif
238         printf_c("InspIRCd revision ID: \033[1;32m%s \033[0m\n\n", revision ? revision_text : "(Non-SVN build)");
239
240         // detect windows
241         if(iswinxp())
242         {
243                 printf_c("You are running Windows 2000 or above, and IOCP support is most likely available.\n"
244                                  "Thisis much more efficent but is currently EXPERIMENTAL and UNSUPPORTED.\n"
245                                  "If you are unsure, answer no.\n\n");
246
247                 use_iocp = get_bool_option("Do you want to use the IOCP implementation?", false);
248         }
249
250         ipv6 = get_bool_option("Do you want to enable IPv6?", false);
251
252         if (!ipv6)
253                 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)", true);
254         else
255                 support_ip6links = true;
256         
257         printf_c("\033[1mAll paths are relative to the binary directory.\033[0m\n");
258         get_string_option("In what directory do you wish to install the InspIRCd base?", "..", base_path);
259         get_string_option("In what directory are the configuration files?", "../conf", config_file);
260         get_string_option("In what directory are the modules to be compiled to?", "../modules", mod_path);
261         get_string_option("In what directory is the IRCd binary to be placed?", ".", bin_dir);
262         get_string_option("In what directory are the IRCd libraries to be placed?", "../lib", library_dir);
263
264         printf_c("The following questions will ask you for various figures relating\n"
265                 "To your IRCd install. Please note that these should usually be left\n"
266                 "as defaults unless you have a real reason to change them. If they\n"
267                 "changed, then the values must be identical on all servers on your\n"
268                 "network, or malfunctions and/or crashes may occur, with the exception\n"
269                 "of the 'maximum number of clients' setting which may be different on\n"
270                 "different servers on the network.\n\n");
271
272         nicklen = get_int_option("Please enter the maximum length of nicknames?", 31);
273         chanlen = get_int_option("Please enter the maximum length of channel names?", 64);
274         modechanges = get_int_option("Please enter the maximum number of mode changes in one line?", 20);
275         identlen = get_int_option("Please enter the maximum length of an ident (username)?", 12);
276         quitlen = get_int_option("Please enter the maximum length of a quit message?", 255);
277         topiclen = get_int_option("Please enter the maximum length of a channel topic?", 307);
278         kicklen = get_int_option("Please enter the maximum length of a kick message?", 255);
279         rllen = get_int_option("Please enter the maximum length of a GECOS (real name)?", 128);
280         awaylen = get_int_option("Please enter the maximum length of an away message?", 200);
281
282         // NOTE: this may seem hackish (generating a batch build script), but it assures the user knows
283         // what they're doing, and we don't have to mess with copying files and changing around modules.mak
284         // for the extra libraries. --fez
285         // in case it exists, remove old m_ssl_openssl.cpp
286         remove("..\\src\\modules\\m_ssl_openssl.cpp");
287         printf_c("You can compile InspIRCd modules that add OpenSSL or GnuTLS support for SSL functionality.\n"
288                 "To do so you will need the appropriate link libraries and header files on your system.\n");
289         use_openssl = get_bool_option("Would you like to compile the IRCd with OpenSSL support?", false);
290         if (use_openssl)
291         {
292                 get_string_option("Please enter the full path to your OpenSSL include directory\n"
293                         "(e.g., C:\\openssl\\include, but NOT the openssl subdirectory under include\\)\n"
294                         "(also, path should not end in '\\')",
295                         "C:\\openssl\\include", openssl_inc_path);
296
297                 // NOTE: if inspircd ever changes so that it compiles with /MT instead of the /MTd switch, then
298                 // the dependency on libeay32mtd.lib and ssleay32mtd.lib will change to just libeay32.lib and
299                 // ssleay32.lib. --fez
300
301                 get_string_option("Please enter the full path to your OpenSSL library directory\n"
302                         "(e.g., C:\\openssl\\lib, which should contain libeay32mtd.lib and ssleay32mtd.lib)",
303                         "C:\\openssl\\lib", openssl_lib_path);
304
305                 // write batch file
306                 FILE *fp = fopen("compile_openssl.bat", "w");
307                 fprintf(fp, "@echo off\n");
308                 fprintf(fp, "echo This batch script compiles m_ssl_openssl for InspIRCd.\n");
309                 fprintf(fp, "echo NOTE: this batch file should be invoked from the Visual Studio Command Prompt (vsvars32.bat)\n");
310                 fprintf(fp, "set OPENSSL_INC_PATH=\"%s\"\n", openssl_inc_path);
311                 fprintf(fp, "set OPENSSL_LIB_PATH=\"%s\"\n", openssl_lib_path);
312                 fprintf(fp, "set COMPILE=cl /nologo -Dssize_t=long /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP /I %%OPENSSL_INC_PATH%% m_ssl_openssl.cpp ..\\..\\win\\inspircd_memory_functions.cpp %%OPENSSL_INC_PATH%%\\openssl\\applink.c /link /LIBPATH:%%OPENSSL_LIB_PATH%% ..\\..\\bin\\release\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\release\\modules\\m_ssl_openssl.so\" /PDB:\"..\\..\\bin\\release\\modules\\m_ssl_openssl.pdb\" /IMPLIB:\"..\\..\\bin\\release\\modules\\m_ssl_openssl.lib\"\n");
313                 fprintf(fp, "cd ..\\src\\modules\n");
314                 fprintf(fp, "copy extra\\m_ssl_openssl.cpp .\n");
315                 fprintf(fp, "echo \t%%COMPILE%%\n");
316                 fprintf(fp, "%%COMPILE%%\n");
317                 fprintf(fp, "cd ..\\..\\win\n");
318                 fprintf(fp, "echo done... now check for errors.\n");
319                 fclose(fp);
320
321                 printf_c("\033[1;32m!!!NOTICE!!! The file 'compile_openssl.bat' has been written to your 'win' directory.  Launch it\n"
322                         "!!! from the Visual Studio Command Prompt !!! to compile the m_ssl_openssl module.\n"
323                         "Wait until after compiling inspircd to run it.\n"
324                         "Also, ssleay32.dll and libeay32.dll will be required for the IRCd to run.\033[0m\n");
325         }
326
327         printf_c("\n\033[1;32mPre-build configuration is complete!\n\n");       sc(TNORMAL);
328
329         // dump all the options back out
330         printf_c("\033[0mBase install path:\033[1;32m           %s\n", base_path);
331         printf_c("\033[0mConfig path:\033[1;32m                   %s\n", config_file);
332         printf_c("\033[0mModule path:\033[1;32m                   %s\n", mod_path);
333         printf_c("\033[0mLibrary path:\033[1;32m                         %s\n", library_dir);
334         printf_c("\033[0mSocket Engine:\033[1;32m                       %s\n", use_iocp ? "iocp" : "select");
335         printf_c("\033[0mMax nickname length:\033[1;32m   %u\n", nicklen);
336         printf_c("\033[0mMax channel length:\033[1;32m     %u\n", chanlen);
337         printf_c("\033[0mMax mode length:\033[1;32m               %u\n", modechanges);
338         printf_c("\033[0mMax ident length:\033[1;32m             %u\n", identlen);
339         printf_c("\033[0mMax quit length:\033[1;32m               %u\n", quitlen);
340         printf_c("\033[0mMax topic length:\033[1;32m             %u\n", topiclen);
341         printf_c("\033[0mMax kick length:\033[1;32m               %u\n", kicklen);
342         printf_c("\033[0mMax name length:\033[1;32m               %u\n", rllen);
343         printf_c("\033[0mMax away length:\033[1;32m               %u\n", awaylen);
344         printf("\n"); sc(TNORMAL);
345         if(get_bool_option("Are these settings correct?", true) == false)
346         {
347                 Run();
348                 return;
349         }
350         printf("\n");
351
352         // escape the pathes
353         escape_string(config_file, MAX_PATH);
354         escape_string(mod_path, MAX_PATH);
355         escape_string(library_dir, MAX_PATH);
356
357         printf("\nWriting inspircd_config.h...");
358         FILE * f = fopen("inspircd_config.h", "w");
359         fprintf(f, "/* Auto generated by configure, do not modify! */\n");
360         fprintf(f, "#ifndef __CONFIGURATION_AUTO__\n");
361         fprintf(f, "#define __CONFIGURATION_AUTO__\n\n");
362         if(use_iocp)
363                 fprintf(f, "#define CONFIG_USE_IOCP 1\n\n");
364         if (ipv6)
365                 fprintf(f, "#define IPV6 1\n\n");
366
367         fprintf(f, "#define CONFIG_FILE \"%s/inspircd.conf\"\n", config_file);
368         fprintf(f, "#define MOD_PATH \"%s\"\n", mod_path);
369         fprintf(f, "#define SOMAXCONN_S \"128\"\n");
370         fprintf(f, "#define NICKMAX %u\n", nicklen+1);
371         fprintf(f, "#define CHANMAX %u\n", chanlen+1);
372         fprintf(f, "#define MAXMODES %u\n", modechanges);
373         fprintf(f, "#define IDENTMAX %u\n", identlen);
374         fprintf(f, "#define MAXQUIT %u\n", quitlen);
375         fprintf(f, "#define MAXTOPIC %u\n", topiclen);
376         fprintf(f, "#define MAXKICK %u\n", kicklen);
377         fprintf(f, "#define MAXGECOS %u\n", rllen);
378         fprintf(f, "#define MAXAWAY %u\n", awaylen);
379         fprintf(f, "#define LIBRARYDIR \"%s\"\n", library_dir);
380         fprintf(f, "#define VERSION \"%s\"\n", version);
381         fprintf(f, "#define REVISION \"%s\"\n", revision_text);
382         if(support_ip6links)
383                 fprintf(f, "#define SUPPORT_IP6LINKS 1\n");
384
385         OSVERSIONINFO vi;
386         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
387         GetVersionEx(&vi);
388 #ifdef WIN64
389         fprintf(f, "#define SYSTEM \"Windows_x64 %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);
390 #else
391         fprintf(f, "#define SYSTEM \"Windows_x32 %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);
392 #endif
393         fprintf(f, "#define MAXBUF 514\n");
394
395         fprintf(f, "\n#include \"inspircd_win32wrapper.h\"\n\n");
396         fprintf(f, "#include \"threadengines/threadengine_win32.h\"\n\n");
397         fprintf(f, "#endif\n\n");
398         fclose(f);
399
400         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
401         printf("Writing inspircd_se_config.h...");
402
403         f = fopen("inspircd_se_config.h", "w");
404         fprintf(f, "/* Auto generated by configure, do not modify or commit to svn! */\n");
405         fprintf(f, "#ifndef __CONFIGURATION_SOCKETENGINE__\n");
406         fprintf(f, "#define __CONFIGURATION_SOCKETENGINE__\n\n");
407         fprintf(f, "#include \"socketengines/socketengine_%s.h\"\n\n", use_iocp ? "iocp" : "select");
408         fprintf(f, "#endif\n\n");
409         fclose(f);
410
411         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
412         printf("Writing command and module compilation scripts...");
413         WriteCompileCommands();
414         WriteCompileModules();
415         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
416
417         printf("\nconfigure is done.. exiting!\n");
418 }
419
420 void WriteCompileCommands()
421 {
422         char commands[300][100];
423         int command_count = 0;
424         printf("\n  Finding Command Sources...\n");
425         WIN32_FIND_DATA fd;
426         HANDLE fh = FindFirstFile("..\\src\\commands\\cmd_*.cpp", &fd);
427         if(fh == INVALID_HANDLE_VALUE)
428                 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");
429         else
430         {
431                 sc(TGREEN);
432                 do 
433                 {
434                         strcpy(commands[command_count], fd.cFileName);
435                         commands[command_count][strlen(fd.cFileName) - 4] = 0;
436                         printf("        %s\n", commands[command_count]);
437                         ++command_count;
438                 } while(FindNextFile(fh, &fd));
439                 sc(TNORMAL);
440         }
441         
442         // Write our spiffy new makefile :D
443         // I am such a lazy fucker :P
444         FILE * f = fopen("..\\src\\commands\\commands.mak", "w");
445
446         time_t t = time(NULL);
447         fprintf(f, "# Generated at %s\n", ctime(&t));
448         fprintf(f, "all: makedir ");
449
450         // dump modules.. first time :)
451         for(int i = 0; i < command_count; ++i)
452                 fprintf(f, "%s.so ", commands[i]);
453
454         fprintf(f, "\n.cpp.obj:\n");
455 #ifdef WIN64
456         // /MACHINE:X64
457         #ifdef _DEBUG
458                 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 /Gm /RTC1 /MTd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug_x64\\bin\\inspircd.lib /OUT:\"..\\..\\bin\\debug_x64\\lib\\$*.so\" /PDB:\"..\\..\\bin\\debug_x64\\lib\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\debug_x64\\lib\\$*.lib\"\n\n");
459                 CreateDirectory("..\\src\\debug", NULL);
460                 CreateDirectory("..\\bin\\debug\\bin", NULL);
461                 CreateDirectory("..\\bin\\debug\\lib", NULL);
462                 CreateDirectory("..\\bin\\debug\\modules", NULL);
463         #else
464                 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 /Gm /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release_x64\\bin\\inspircd.lib /OUT:\"..\\..\\bin\\release_x64\\lib\\$*.so\" /PDB:\"..\\..\\bin\\release_x64\\lib\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\release_x64\\lib\\$*.lib\"\n\n");
465                 CreateDirectory("..\\src\\release", NULL);
466                 CreateDirectory("..\\bin\\release\\bin", NULL);
467                 CreateDirectory("..\\bin\\release\\lib", NULL);
468                 CreateDirectory("..\\bin\\release\\modules", NULL);
469         #endif
470 #else
471         #ifdef _DEBUG
472                 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 /Gm /RTC1 /MTd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /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");
473                 CreateDirectory("..\\src\\debug", NULL);
474                 CreateDirectory("..\\bin\\debug\\bin", NULL);
475                 CreateDirectory("..\\bin\\debug\\lib", NULL);
476                 CreateDirectory("..\\bin\\debug\\modules", NULL);
477         #else
478                 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 /Gm /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /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");
479                 CreateDirectory("..\\src\\release", NULL);
480                 CreateDirectory("..\\bin\\release\\bin", NULL);
481                 CreateDirectory("..\\bin\\release\\lib", NULL);
482                 CreateDirectory("..\\bin\\release\\modules", NULL);
483         #endif
484 #endif
485
486         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n  if not exist release mkdir release\n\n");
487         
488         // dump modules.. again the second and last time :)
489         for(int i = 0; i < command_count; ++i)
490                 fprintf(f, "%s.so : %s.obj\n", commands[i], commands[i]);
491
492         fprintf(f, "\n");
493         fclose(f);
494 }
495
496 void WriteCompileModules()
497 {
498         char modules[300][100];
499         int module_count = 0;
500
501         printf("Finding Modules...\n");
502         WIN32_FIND_DATA fd;
503         HANDLE fh = FindFirstFile("..\\src\\modules\\m_*.cpp", &fd);
504         if(fh == INVALID_HANDLE_VALUE)
505                 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");
506         else
507         {
508                 sc(TGREEN);
509                 do 
510                 {
511                         strcpy(modules[module_count], fd.cFileName);
512                         modules[module_count][strlen(fd.cFileName) - 4] = 0;
513                         printf("  %s\n", modules[module_count]);
514                         ++module_count;
515                 } while(FindNextFile(fh, &fd));
516                 sc(TNORMAL);
517         }
518
519         // Write our spiffy new makefile :D
520         // I am such a lazy fucker :P
521         FILE * f = fopen("..\\src\\modules\\modules.mak", "w");
522
523         time_t t = time(NULL);
524         fprintf(f, "# Generated at %s\n", ctime(&t));
525         fprintf(f, "all: makedir ");
526
527         // dump modules.. first time :)
528         for(int i = 0; i < module_count; ++i)
529                 fprintf(f, "%s.so ", modules[i]);
530
531         fprintf(f, "\n.cpp.obj:\n");
532 #ifdef WIN64
533         // /MACHINE:X64
534         #ifdef _DEBUG
535                 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 /Gm /RTC1 /MTd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug_x64\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\debug_x64\\modules\\$*.so\" /PDB:\"..\\..\\bin\\debug_x64\\modules\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\debug_x64\\modules\\$*.lib\"\n\n");
536                 CreateDirectory("..\\src\\modules\\debug_x64", NULL);
537         #else
538                 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 /Gm /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release_x64\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\release_x64\\modules\\$*.so\" /PDB:\"..\\..\\bin\\release_x64\\modules\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\release_x64\\modules\\$*.lib\"\n\n");
539                 CreateDirectory("..\\src\\modules\\release_x64", NULL);
540         #endif
541 #else
542         #ifdef _DEBUG
543                 fprintf(f, "  cl /nologo -Dssize_t=long /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 /Gm /RTC1 /MTd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /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");
544                 CreateDirectory("..\\src\\modules\\debug", NULL);
545                 CreateDirectory("..\\src\\modules\\debug\\lib", NULL);
546                 CreateDirectory("..\\src\\modules\\debug\\modules", NULL);
547                 CreateDirectory("..\\src\\modules\\debug\\bin", NULL);
548         #else
549                 fprintf(f, "  cl /nologo -Dssize_t=long /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /MT /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /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");
550                 CreateDirectory("..\\src\\modules\\release", NULL);
551                 CreateDirectory("..\\src\\modules\\release\\lib", NULL);
552                 CreateDirectory("..\\src\\modules\\release\\modules", NULL);
553                 CreateDirectory("..\\src\\modules\\release\\bin", NULL);
554         #endif
555 #endif
556         
557         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n  if not exist release mkdir release\n\n");
558
559         // dump modules.. again the second and last time :)
560         for(int i = 0; i < module_count; ++i)
561                 fprintf(f, "%s.so : %s.obj\n", modules[i], modules[i]);
562
563         fprintf(f, "\n");
564         fclose(f);
565 }