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