]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - win/configure.cpp
Add support for OnNamesListItem, discussed with w00t a few days ago. This makes NAMES...
[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         int max_fd = 10200;
188         bool use_iocp = false;
189         bool support_ip6links = true;
190         bool use_openssl = false;
191         bool ipv6 = true;
192         char mod_path[MAX_PATH];
193         char config_file[MAX_PATH];
194         char library_dir[MAX_PATH];
195         char base_path[MAX_PATH];
196         char bin_dir[MAX_PATH];
197         char revision_text[MAX_PATH];
198         char openssl_inc_path[MAX_PATH];
199         char openssl_lib_path[MAX_PATH];
200
201         int max_clients = 10200;
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         max_fd = get_int_option("What is the maximum file descriptor count you would like to allow?", 10200);
241
242         // detect windows
243         if(iswinxp())
244         {
245                 printf_c("You are running Windows 2000 or above, and IOCP support is most likely available.\n"
246                              "Thisis much more efficent but is currently EXPERIMENTAL and UNSUPPORTED.\n"
247                                  "If you are unsure, answer no.\n\n");
248
249                 use_iocp = get_bool_option("Do you want to use the IOCP implementation?", false);
250         }
251
252         ipv6 = get_bool_option("Do you want to enable IPv6?", false);
253
254         if (!ipv6)
255                 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);
256         else
257                 support_ip6links = true;
258         
259         printf_c("\033[1mAll paths are relative to the binary directory.\033[0m\n");
260         get_string_option("In what directory do you wish to install the InspIRCd base?", "..", base_path);
261         get_string_option("In what directory are the configuration files?", "../conf", config_file);
262         get_string_option("In what directory are the modules to be compiled to?", "../modules", mod_path);
263         get_string_option("In what directory is the IRCd binary to be placed?", ".", bin_dir);
264         get_string_option("In what directory are the IRCd libraries to be placed?", "../lib", library_dir);
265
266         printf_c("The following questions will ask you for various figures relating\n"
267                 "To your IRCd install. Please note that these should usually be left\n"
268                 "as defaults unless you have a real reason to change them. If they\n"
269                 "changed, then the values must be identical on all servers on your\n"
270                 "network, or malfunctions and/or crashes may occur, with the exception\n"
271                 "of the 'maximum number of clients' setting which may be different on\n"
272                 "different servers on the network.\n\n");
273
274     
275         max_clients = get_int_option("Please enter the maximum number of clients at any one time?", 10200);
276         nicklen = get_int_option("Please enter the maximum length of nicknames?", 31);
277         chanlen = get_int_option("Please enter the maximum length of channel names?", 64);
278         modechanges = get_int_option("Please enter the maximum number of mode changes in one line?", 20);
279         identlen = get_int_option("Please enter the maximum length of an ident (username)?", 12);
280         quitlen = get_int_option("Please enter the maximum length of a quit message?", 255);
281         topiclen = get_int_option("Please enter the maximum length of a channel topic?", 307);
282         kicklen = get_int_option("Please enter the maximum length of a kick message?", 255);
283         rllen = get_int_option("Please enter the maximum length of a GECOS (real name)?", 128);
284         awaylen = get_int_option("Please enter the maximum length of an away message?", 200);
285
286         // NOTE: this may seem hackish (generating a batch build script), but it assures the user knows
287         // what they're doing, and we don't have to mess with copying files and changing around modules.mak
288         // for the extra libraries. --fez
289         // in case it exists, remove old m_ssl_openssl.cpp
290         remove("..\\src\\modules\\m_ssl_openssl.cpp");
291         printf_c("You can compile InspIRCd modules that add OpenSSL or GnuTLS support for SSL functionality.\n"
292                 "To do so you will need the appropriate link libraries and header files on your system.\n");
293         use_openssl = get_bool_option("Would you like to compile the IRCd with OpenSSL support?", false);
294         if (use_openssl)
295         {
296                 get_string_option("Please enter the full path to your OpenSSL include directory\n"
297                         "(e.g., C:\\openssl\\include, but NOT the openssl subdirectory under include\\)\n"
298                         "(also, path should not end in '\\')",
299                         "C:\\openssl\\include", openssl_inc_path);
300
301                 // NOTE: if inspircd ever changes so that it compiles with /MT instead of the /MTd switch, then
302                 // the dependency on libeay32mtd.lib and ssleay32mtd.lib will change to just libeay32.lib and
303                 // ssleay32.lib. --fez
304
305                 get_string_option("Please enter the full path to your OpenSSL library directory\n"
306                         "(e.g., C:\\openssl\\lib, which should contain libeay32mtd.lib and ssleay32mtd.lib)",
307                         "C:\\openssl\\lib", openssl_lib_path);
308
309                 // write batch file
310                 FILE *fp = fopen("compile_openssl.bat", "w");
311                 fprintf(fp, "@echo off\n");
312                 fprintf(fp, "echo This batch script compiles m_ssl_openssl for InspIRCd.\n");
313                 fprintf(fp, "echo NOTE: this batch file should be invoked from the Visual Studio Command Prompt (vsvars32.bat)\n");
314                 fprintf(fp, "set OPENSSL_INC_PATH=\"%s\"\n", openssl_inc_path);
315                 fprintf(fp, "set OPENSSL_LIB_PATH=\"%s\"\n", openssl_lib_path);
316                 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");
317                 fprintf(fp, "cd ..\\src\\modules\n");
318                 fprintf(fp, "copy extra\\m_ssl_openssl.cpp .\n");
319                 fprintf(fp, "echo \t%%COMPILE%%\n");
320                 fprintf(fp, "%%COMPILE%%\n");
321                 fprintf(fp, "cd ..\\..\\win\n");
322                 fprintf(fp, "echo done... now check for errors.\n");
323                 fclose(fp);
324
325                 printf_c("\033[1;32m!!!NOTICE!!! The file 'compile_openssl.bat' has been written to your 'win' directory.  Launch it\n"
326                         "!!! from the Visual Studio Command Prompt !!! to compile the m_ssl_openssl module.\n"
327                         "Wait until after compiling inspircd to run it.\n"
328                         "Also, ssleay32.dll and libeay32.dll will be required for the IRCd to run.\033[0m\n");
329         }
330
331         printf_c("\n\033[1;32mPre-build configuration is complete!\n\n");       sc(TNORMAL);
332
333         // dump all the options back out
334         printf_c("\033[0mBase install path:\033[1;32m        %s\n", base_path);
335         printf_c("\033[0mConfig path:\033[1;32m              %s\n", config_file);
336         printf_c("\033[0mModule path:\033[1;32m              %s\n", mod_path);
337         printf_c("\033[0mLibrary path:\033[1;32m             %s\n", library_dir);
338         printf_c("\033[0mSocket Engine:\033[1;32m            %s\n", use_iocp ? "iocp" : "select");
339         printf_c("\033[0mMax file descriptors:\033[1;32m     %u\n", max_fd);
340         printf_c("\033[0mMax connections:\033[1;32m          %u\n", max_clients);
341         printf_c("\033[0mMax nickname length:\033[1;32m      %u\n", nicklen);
342         printf_c("\033[0mMax channel length:\033[1;32m       %u\n", chanlen);
343         printf_c("\033[0mMax mode length:\033[1;32m          %u\n", modechanges);
344         printf_c("\033[0mMax ident length:\033[1;32m         %u\n", identlen);
345         printf_c("\033[0mMax quit length:\033[1;32m          %u\n", quitlen);
346         printf_c("\033[0mMax topic length:\033[1;32m         %u\n", topiclen);
347         printf_c("\033[0mMax kick length:\033[1;32m          %u\n", kicklen);
348         printf_c("\033[0mMax name length:\033[1;32m          %u\n", rllen);
349         printf_c("\033[0mMax away length:\033[1;32m          %u\n", awaylen);
350         printf("\n"); sc(TNORMAL);
351         if(get_bool_option("Are these settings correct?", true) == false)
352         {
353                 Run();
354                 return;
355         }
356         printf("\n");
357
358         // escape the pathes
359         escape_string(config_file, MAX_PATH);
360         escape_string(mod_path, MAX_PATH);
361         escape_string(library_dir, MAX_PATH);
362
363         printf("\nWriting inspircd_config.h...");
364         FILE * f = fopen("inspircd_config.h", "w");
365         fprintf(f, "/* Auto generated by configure, do not modify! */\n");
366         fprintf(f, "#ifndef __CONFIGURATION_AUTO__\n");
367         fprintf(f, "#define __CONFIGURATION_AUTO__\n\n");
368         if(use_iocp)
369                 fprintf(f, "#define CONFIG_USE_IOCP 1\n\n");
370         if (ipv6)
371                 fprintf(f, "#define IPV6 1\n\n");
372
373         fprintf(f, "#define CONFIG_FILE \"%s/inspircd.conf\"\n", config_file);
374         fprintf(f, "#define MOD_PATH \"%s\"\n", mod_path);
375         fprintf(f, "#define MAX_DESCRIPTORS %u\n", max_fd);
376         fprintf(f, "#define MAXCLIENTS %u\n", max_clients);
377         fprintf(f, "#define MAXCLIENTS_S \"%u\"\n", max_clients);
378         fprintf(f, "#define SOMAXCONN_S \"128\"\n");
379         fprintf(f, "#define NICKMAX %u\n", nicklen+1);
380         fprintf(f, "#define CHANMAX %u\n", chanlen+1);
381         fprintf(f, "#define MAXMODES %u\n", modechanges);
382         fprintf(f, "#define IDENTMAX %u\n", identlen);
383         fprintf(f, "#define MAXQUIT %u\n", quitlen);
384         fprintf(f, "#define MAXTOPIC %u\n", topiclen);
385         fprintf(f, "#define MAXKICK %u\n", kicklen);
386         fprintf(f, "#define MAXGECOS %u\n", rllen);
387         fprintf(f, "#define MAXAWAY %u\n", awaylen);
388         fprintf(f, "#define LIBRARYDIR \"%s\"\n", library_dir);
389         fprintf(f, "#define VERSION \"%s\"\n", version);
390         fprintf(f, "#define REVISION \"%s\"\n", revision_text);
391         if(support_ip6links)
392                 fprintf(f, "#define SUPPORT_IP6LINKS 1\n");
393
394         OSVERSIONINFO vi;
395         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
396         GetVersionEx(&vi);
397 #ifdef WIN64
398         fprintf(f, "#define SYSTEM \"Windows_x64 %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);
399 #else
400         fprintf(f, "#define SYSTEM \"Windows_x32 %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);
401 #endif
402         fprintf(f, "#define MAXBUF 514\n");
403
404         fprintf(f, "\n#include \"inspircd_win32wrapper.h\"\n\n");
405         fprintf(f, "#include \"threadengines/threadengine_win32.h\"\n\n");
406         fprintf(f, "#endif\n\n");
407         fclose(f);
408
409         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
410         printf("Writing inspircd_se_config.h...");
411
412         f = fopen("inspircd_se_config.h", "w");
413         fprintf(f, "/* Auto generated by configure, do not modify or commit to svn! */\n");
414         fprintf(f, "#ifndef __CONFIGURATION_SOCKETENGINE__\n");
415         fprintf(f, "#define __CONFIGURATION_SOCKETENGINE__\n\n");
416         fprintf(f, "#include \"socketengines/socketengine_%s.h\"\n\n", use_iocp ? "iocp" : "select");
417         fprintf(f, "#endif\n\n");
418         fclose(f);
419
420         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
421         printf("Writing command and module compilation scripts...");
422         WriteCompileCommands();
423         WriteCompileModules();
424         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
425
426         printf("\nconfigure is done.. exiting!\n");
427 }
428
429 void WriteCompileCommands()
430 {
431         char commands[300][100];
432         int command_count = 0;
433         printf("\n  Finding Command Sources...\n");
434         WIN32_FIND_DATA fd;
435         HANDLE fh = FindFirstFile("..\\src\\commands\\cmd_*.cpp", &fd);
436         if(fh == INVALID_HANDLE_VALUE)
437                 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");
438         else
439         {
440                 sc(TGREEN);
441                 do 
442                 {
443                         strcpy(commands[command_count], fd.cFileName);
444                         commands[command_count][strlen(fd.cFileName) - 4] = 0;
445                         printf("    %s\n", commands[command_count]);
446                         ++command_count;
447                 } while(FindNextFile(fh, &fd));
448                 sc(TNORMAL);
449         }
450     
451         // Write our spiffy new makefile :D
452         // I am such a lazy fucker :P
453         FILE * f = fopen("..\\src\\commands\\commands.mak", "w");
454
455         time_t t = time(NULL);
456         fprintf(f, "# Generated at %s\n", ctime(&t));
457         fprintf(f, "all: makedir ");
458
459         // dump modules.. first time :)
460         for(int i = 0; i < command_count; ++i)
461                 fprintf(f, "%s.so ", commands[i]);
462
463         fprintf(f, "\n.cpp.obj:\n");
464 #ifdef WIN64
465         // /MACHINE:X64
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_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");
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_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");
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 #else
480         #ifdef _DEBUG
481                 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");
482                 CreateDirectory("..\\src\\debug", NULL);
483                 CreateDirectory("..\\bin\\debug\\bin", NULL);
484                 CreateDirectory("..\\bin\\debug\\lib", NULL);
485                 CreateDirectory("..\\bin\\debug\\modules", NULL);
486         #else
487                 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");
488                 CreateDirectory("..\\src\\release", NULL);
489                 CreateDirectory("..\\bin\\release\\bin", NULL);
490                 CreateDirectory("..\\bin\\release\\lib", NULL);
491                 CreateDirectory("..\\bin\\release\\modules", NULL);
492         #endif
493 #endif
494
495         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n  if not exist release mkdir release\n\n");
496         
497         // dump modules.. again the second and last time :)
498         for(int i = 0; i < command_count; ++i)
499                 fprintf(f, "%s.so : %s.obj\n", commands[i], commands[i]);
500
501         fprintf(f, "\n");
502         fclose(f);
503 }
504
505 void WriteCompileModules()
506 {
507         char modules[300][100];
508         int module_count = 0;
509
510         printf("Finding Modules...\n");
511         WIN32_FIND_DATA fd;
512         HANDLE fh = FindFirstFile("..\\src\\modules\\m_*.cpp", &fd);
513         if(fh == INVALID_HANDLE_VALUE)
514                 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");
515         else
516         {
517                 sc(TGREEN);
518                 do 
519                 {
520                         strcpy(modules[module_count], fd.cFileName);
521                         modules[module_count][strlen(fd.cFileName) - 4] = 0;
522                         printf("  %s\n", modules[module_count]);
523                         ++module_count;
524                 } while(FindNextFile(fh, &fd));
525                 sc(TNORMAL);
526         }
527
528         // Write our spiffy new makefile :D
529         // I am such a lazy fucker :P
530         FILE * f = fopen("..\\src\\modules\\modules.mak", "w");
531
532         time_t t = time(NULL);
533         fprintf(f, "# Generated at %s\n", ctime(&t));
534         fprintf(f, "all: makedir ");
535
536         // dump modules.. first time :)
537         for(int i = 0; i < module_count; ++i)
538                 fprintf(f, "%s.so ", modules[i]);
539
540         fprintf(f, "\n.cpp.obj:\n");
541 #ifdef WIN64
542         // /MACHINE:X64
543         #ifdef _DEBUG
544                 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");
545                 CreateDirectory("..\\src\\modules\\debug_x64", NULL);
546         #else
547                 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");
548                 CreateDirectory("..\\src\\modules\\release_x64", NULL);
549         #endif
550 #else
551         #ifdef _DEBUG
552                 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");
553                 CreateDirectory("..\\src\\modules\\debug", NULL);
554                 CreateDirectory("..\\src\\modules\\debug\\lib", NULL);
555                 CreateDirectory("..\\src\\modules\\debug\\modules", NULL);
556                 CreateDirectory("..\\src\\modules\\debug\\bin", NULL);
557         #else
558                 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");
559                 CreateDirectory("..\\src\\modules\\release", NULL);
560                 CreateDirectory("..\\src\\modules\\release\\lib", NULL);
561                 CreateDirectory("..\\src\\modules\\release\\modules", NULL);
562                 CreateDirectory("..\\src\\modules\\release\\bin", NULL);
563         #endif
564 #endif
565         
566         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n  if not exist release mkdir release\n\n");
567
568         // dump modules.. again the second and last time :)
569         for(int i = 0; i < module_count; ++i)
570                 fprintf(f, "%s.so : %s.obj\n", modules[i], modules[i]);
571
572         fprintf(f, "\n");
573         fclose(f);
574 }