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