OVERdrive-IRC patches for InspIRCd

configure 39KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229
  1. #!/usr/bin/env perl
  2. #
  3. # InspIRCd -- Internet Relay Chat Daemon
  4. #
  5. # Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
  6. # Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
  7. # Copyright (C) 2003, 2006-2008 Craig Edwards <craigedwards@brainbox.cc>
  8. # Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net>
  9. # Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
  10. # Copyright (C) 2007 John Brooks <john.brooks@dereferenced.net>
  11. # Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
  12. # Copyright (C) 2003-2006 Craig McLure <craig@chatspike.net>
  13. #
  14. # This file is part of InspIRCd. InspIRCd is free software: you can
  15. # redistribute it and/or modify it under the terms of the GNU General Public
  16. # License as published by the Free Software Foundation, version 2.
  17. #
  18. # This program is distributed in the hope that it will be useful, but WITHOUT
  19. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  21. # details.
  22. #
  23. # You should have received a copy of the GNU General Public License
  24. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. #
  26. BEGIN {
  27. require 5.8.0;
  28. push @INC, '.';
  29. }
  30. use strict;
  31. use warnings FATAL => qw(all);
  32. use File::Copy ();
  33. use Socket;
  34. use Cwd;
  35. use Getopt::Long;
  36. # Utility functions for our buildsystem
  37. use make::utilities;
  38. use make::configure;
  39. use make::gnutlscert;
  40. use make::opensslcert;
  41. ###############################################################################################
  42. #
  43. # NON-EDITABLE VARIABLES
  44. #
  45. ###############################################################################################
  46. our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
  47. $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
  48. $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
  49. $opt_system, $opt_uid);
  50. our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir, $opt_data_dir, $opt_log_dir);
  51. sub list_extras ();
  52. sub enable_extras (@);
  53. sub disable_extras (@);
  54. my @opt_enableextras;
  55. my @opt_disableextras;
  56. GetOptions (
  57. 'enable-gnutls' => \$opt_use_gnutls,
  58. 'rebuild' => \$opt_rebuild,
  59. 'system' => \$opt_system,
  60. 'uid=s' => \$opt_uid,
  61. 'enable-openssl' => \$opt_use_openssl,
  62. 'disable-interactive' => \$opt_nointeractive,
  63. 'enable-ports' => \$opt_ports,
  64. 'enable-epoll' => \$opt_epoll,
  65. 'enable-kqueue' => \$opt_kqueue,
  66. 'disable-ports' => \$opt_noports,
  67. 'disable-epoll' => \$opt_noepoll,
  68. 'disable-kqueue' => \$opt_nokqueue,
  69. 'disable-ipv6' => \$opt_noipv6,
  70. 'with-cc=s' => \$opt_cc,
  71. 'with-maxbuf=i' => \$opt_maxbuf,
  72. 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
  73. 'prefix=s' => \$opt_base_dir,
  74. 'config-dir=s' => \$opt_config_dir,
  75. 'module-dir=s' => \$opt_module_dir,
  76. 'binary-dir=s' => \$opt_binary_dir,
  77. 'data-dir=s' => \$opt_data_dir,
  78. 'log-dir=s' => \$opt_log_dir,
  79. 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
  80. 'help' => sub { showhelp(); },
  81. 'update' => sub { update(); },
  82. 'clean' => sub { clean(); },
  83. 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
  84. 'enable-extras=s@' => \@opt_enableextras, # ^
  85. 'disable-extras=s@' => \@opt_disableextras, # ^
  86. 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
  87. 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
  88. );
  89. if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
  90. @opt_enableextras = split /,/, join(',', @opt_enableextras);
  91. @opt_disableextras = split /,/, join(',', @opt_disableextras);
  92. enable_extras(@opt_enableextras);
  93. disable_extras(@opt_disableextras);
  94. list_extras;
  95. print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
  96. exit 0;
  97. }
  98. our $interactive = !(
  99. (defined $opt_base_dir) ||
  100. (defined $opt_config_dir) ||
  101. (defined $opt_module_dir) ||
  102. (defined $opt_base_dir) ||
  103. (defined $opt_binary_dir) ||
  104. (defined $opt_data_dir) ||
  105. (defined $opt_log_dir) ||
  106. (defined $opt_nointeractive) ||
  107. (defined $opt_cc) ||
  108. (defined $opt_noipv6) ||
  109. (defined $opt_kqueue) ||
  110. (defined $opt_epoll) ||
  111. (defined $opt_ports) ||
  112. (defined $opt_use_openssl) ||
  113. (defined $opt_nokqueue) ||
  114. (defined $opt_noepoll) ||
  115. (defined $opt_noports) ||
  116. (defined $opt_maxbuf) ||
  117. (defined $opt_system) ||
  118. (defined $opt_uid) ||
  119. (defined $opt_use_gnutls) ||
  120. (defined $opt_freebsd_port)
  121. );
  122. chomp(our $topdir = getcwd());
  123. our $this = resolve_directory($topdir); # PWD, Regardless.
  124. our @modlist = (); # Declare for Module List..
  125. our %config = (); # Initiate Configuration Hash..
  126. our $cache_loaded = getcache();
  127. $config{ME} = resolve_directory($topdir); # Present Working Directory
  128. $config{BASE_DIR} ||= $config{ME};
  129. if (defined $opt_base_dir) {
  130. $config{BASE_DIR} = $opt_base_dir;
  131. } elsif (defined $opt_system) {
  132. $config{BASE_DIR} = '/var/lib/inspircd';
  133. }
  134. if (defined $opt_system) {
  135. $config{UID} = $opt_uid || 'ircd';
  136. $config{CONFIG_DIR} = '/etc/inspircd';
  137. $config{MODULE_DIR} = '/usr/lib/inspircd';
  138. $config{BINARY_DIR} = '/usr/sbin/';
  139. $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
  140. $config{DATA_DIR} = '/var/inspircd';
  141. $config{LOG_DIR} = '/var/log/inspircd';
  142. } else {
  143. $config{UID} = $opt_uid || $config{UID} || $<;
  144. $config{CONFIG_DIR} ||= resolve_directory($config{BASE_DIR}."/etc"); # Configuration Directory
  145. $config{MODULE_DIR} ||= resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
  146. $config{BINARY_DIR} ||= resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
  147. $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build"); # Build Directory
  148. $config{DATA_DIR} ||= resolve_directory($config{BASE_DIR}."/data"); # Data directory
  149. $config{LOG_DIR} ||= resolve_directory($config{BASE_DIR}."/logs"); # Log directory
  150. }
  151. if (defined $opt_config_dir) {
  152. $config{CONFIG_DIR} = $opt_config_dir;
  153. }
  154. if (defined $opt_module_dir) {
  155. $config{MODULE_DIR} = $opt_module_dir;
  156. }
  157. if (defined $opt_binary_dir) {
  158. $config{BINARY_DIR} = $opt_binary_dir;
  159. }
  160. if (defined $opt_data_dir) {
  161. $config{DATA_DIR} = $opt_data_dir;
  162. }
  163. if (defined $opt_log_dir) {
  164. $config{LOG_DIR} = $opt_log_dir;
  165. }
  166. chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null`); # GNUTLS Version.
  167. if (defined $opt_freebsd_port)
  168. {
  169. chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
  170. chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
  171. $config{USE_FREEBSD_BASE_SSL} = "n";
  172. }
  173. else
  174. {
  175. if ($^O eq "freebsd")
  176. {
  177. # default: use base ssl
  178. chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
  179. chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
  180. }
  181. else
  182. {
  183. chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
  184. $config{HAS_OPENSSL_PORT} = "";
  185. $config{USE_FREEBSD_BASE_SSL} = "n";
  186. }
  187. }
  188. chomp(our $gnutls_ver = $config{HAS_GNUTLS});
  189. chomp(our $openssl_ver = $config{HAS_OPENSSL});
  190. $config{USE_GNUTLS} ||= "n";
  191. if (defined $opt_use_gnutls)
  192. {
  193. $config{USE_GNUTLS} = "y"; # Use gnutls.
  194. }
  195. $config{USE_OPENSSL} ||= "n"; # Use openssl.
  196. if (defined $opt_use_openssl)
  197. {
  198. $config{USE_OPENSSL} = "y";
  199. }
  200. if (!defined $opt_disable_debug) {
  201. $config{OPTIMISATI} = "-g1"; # Optimisation Flag
  202. } else {
  203. $config{OPTIMISATI} = "-O2";
  204. }
  205. $config{HAS_STRLCPY} = "false"; # strlcpy Check.
  206. $config{HAS_STDINT} = "false"; # stdint.h check
  207. $config{USE_KQUEUE} = "y"; # kqueue enabled
  208. if (defined $opt_nokqueue) {
  209. $config{USE_KQUEUE} = "n";
  210. }
  211. $config{USE_POLL} = "y"; # poll enabled
  212. $config{USE_EPOLL} = "y"; # epoll enabled
  213. if (defined $opt_noepoll)
  214. {
  215. $config{USE_EPOLL} = "n";
  216. }
  217. $config{USE_PORTS} = "y"; # epoll enabled
  218. if (defined $opt_noports)
  219. {
  220. $config{USE_PORTS} = "n";
  221. }
  222. $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
  223. $config{OSNAME} = $^O; # Operating System Name
  224. $config{IS_DARWIN} = "NO"; # Is OSX?
  225. $config{STARTSCRIPT} = "inspircd"; # start script?
  226. $config{DESTINATION} = "BASE"; # Is target path.
  227. if ($config{OSNAME} =~ /darwin/i)
  228. {
  229. $config{IS_DARWIN} = "YES";
  230. $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
  231. $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
  232. }
  233. elsif ($config{OSNAME} =~ /freebsd/i)
  234. {
  235. chomp(my $fbsd_version = `uname -r`);
  236. $fbsd_version =~ s/^(\d+\.\d+).*/$1/g;
  237. $config{CC} = $fbsd_version >= 10.0 ? 'clang++' : 'g++';
  238. }
  239. else
  240. {
  241. $config{CC} = "g++"; # C++ compiler
  242. }
  243. if (defined $opt_cc)
  244. {
  245. $config{CC} = $opt_cc;
  246. }
  247. `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/;
  248. $config{GCCVER} = defined $1 ? $1 : '';
  249. $config{GCCMINOR} = defined $2 ? $2 : '0';
  250. $config{MAXBUF} = "512"; # Max buffer size
  251. if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) {
  252. $config{HAS_OPENSSL} = $1;
  253. } else {
  254. $config{HAS_OPENSSL} = "";
  255. }
  256. if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
  257. print "`$config{CC}` was not found! A C++ compiler is required to build InspIRCd!\n";
  258. print "You can pass a custom compiler to $0 using --with-cc=[name].\n";
  259. exit;
  260. }
  261. # Get and Set some important vars..
  262. getmodules();
  263. sub clean
  264. {
  265. unlink(".config.cache");
  266. }
  267. our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
  268. sub update
  269. {
  270. eval {
  271. chomp($topdir = getcwd());
  272. $this = resolve_directory($topdir); # PWD, Regardless.
  273. getmodules();
  274. # Does the cache file exist?
  275. if (!getcache()) {
  276. # No, No it doesn't.. *BASH*
  277. print "You have not run ./configure before. Please do this before trying to run the update script.\n";
  278. exit 0;
  279. } else {
  280. # We've Loaded the cache file and all our variables..
  281. print "Updating files...\n";
  282. if (defined($opt_disable_debug) && $opt_disable_debug == 1)
  283. {
  284. print "Disabling debug information (-g).\n";
  285. $config{OPTIMISATI} = "";
  286. }
  287. $has_epoll = $config{HAS_EPOLL};
  288. $has_ports = $config{HAS_PORTS};
  289. $has_kqueue = $config{HAS_KQUEUE};
  290. writefiles(1);
  291. makecache();
  292. print "Complete.\n";
  293. exit;
  294. }
  295. };
  296. if ($@)
  297. {
  298. print "Configure update failed: $@\n";
  299. }
  300. exit;
  301. }
  302. sub test_compile {
  303. my $feature = shift;
  304. my $fail = 0;
  305. $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
  306. $fail ||= system "./test_$feature";
  307. unlink "test_$feature";
  308. return !$fail;
  309. }
  310. print "Running non-interactive configure...\n" unless $interactive;
  311. print "Checking for cache from previous configure... ";
  312. print ($cache_loaded ? "found\n" : "not found\n");
  313. $config{SYSTEM} = lc $^O;
  314. print "Checking operating system version... $config{SYSTEM}\n";
  315. `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/;
  316. $config{GCCVER} = defined $1 ? $1 : '';
  317. $config{GCCMINOR} = defined $2 ? $2 : '0';
  318. printf "Checking if stdint.h exists... ";
  319. $config{HAS_STDINT} = test_compile('stdint');
  320. print $config{HAS_STDINT} ? "yes\n" : "no\n";
  321. printf "Checking if strlcpy exists... ";
  322. $config{HAS_STRLCPY} = test_compile('strlcpy');
  323. print $config{HAS_STRLCPY} ? "yes\n" : "no\n";
  324. printf "Checking if kqueue exists... ";
  325. $has_kqueue = test_compile('kqueue');
  326. print $has_kqueue ? "yes\n" : "no\n";
  327. printf "Checking for epoll support... ";
  328. $has_epoll = test_compile('epoll');
  329. print $has_epoll ? "yes\n" : "no\n";
  330. printf "Checking for eventfd support... ";
  331. $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
  332. print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
  333. printf "Checking if Solaris I/O completion ports are available... ";
  334. $has_ports = 0;
  335. our $system = `uname -s`;
  336. chomp ($system);
  337. $has_ports = 1 if ($system eq "SunOS");
  338. if ($has_ports) {
  339. my $kernel = `uname -r`;
  340. chomp($kernel);
  341. if (($kernel !~ /^5\.1./)) {
  342. $has_ports = 0;
  343. }
  344. }
  345. print "yes\n" if $has_ports == 1;
  346. print "no\n" if $has_ports == 0;
  347. $config{HAS_EPOLL} = $has_epoll;
  348. $config{HAS_KQUEUE} = $has_kqueue;
  349. printf "Checking for libgnutls... ";
  350. if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
  351. if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
  352. print "yes\n";
  353. $config{HAS_GNUTLS} = "y";
  354. } else {
  355. print "no\n";
  356. $config{HAS_GNUTLS} = "n";
  357. }
  358. } else {
  359. print "no\n";
  360. $config{HAS_GNUTLS} = "n";
  361. }
  362. printf "Checking for openssl... ";
  363. if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
  364. if (defined($openssl_ver) && ($openssl_ver ne "")) {
  365. print "yes\n";
  366. $config{HAS_OPENSSL} = "y";
  367. } else {
  368. print "no\n";
  369. $config{HAS_OPENSSL} = "n";
  370. }
  371. } else {
  372. print "no\n";
  373. $config{HAS_OPENSSL} = "n";
  374. }
  375. printf "Checking if you are running an ancient, unsupported OS... ";
  376. if ($config{OSNAME} =~ /FreeBSD/i)
  377. {
  378. my $version = `uname -r`;
  379. if ($version =~ /^4\./)
  380. {
  381. print "yes.\n";
  382. print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
  383. print "To build, you will need to add the following to CXXFLAGS:\n";
  384. print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
  385. }
  386. else
  387. {
  388. print "no ($version)\n";
  389. }
  390. }
  391. else
  392. {
  393. print "no ($config{OSNAME})\n";
  394. }
  395. ################################################################################
  396. # BEGIN INTERACTIVE PART #
  397. ################################################################################
  398. # Clear the Screen..
  399. if ($interactive)
  400. {
  401. print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
  402. my $wholeos = $^O;
  403. my $rev = getrevision();
  404. # Display Introduction Message..
  405. print <<"STOP" ;
  406. Welcome to the \e[1mInspIRCd\e[0m configuration program! (\e[1minteractive mode\e[0m)
  407. \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
  408. *** If you are unsure of any of these values, leave it blank for ***
  409. *** standard settings that will work, and your server will run ***
  410. *** using them. Please consult your IRC network admin if in doubt. ***
  411. Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
  412. a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
  413. dir, otherwise you won't have a config file!
  414. Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
  415. Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
  416. STOP
  417. if ($rev eq "r0") {
  418. print " (Non-SVN build)";
  419. }
  420. print ".\n\n";
  421. $config{CHANGE_COMPILER} = "n";
  422. print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
  423. while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
  424. print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
  425. should NOT be used. You should probably specify a newer compiler.\n\n";
  426. yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
  427. if ($config{CHANGE_COMPILER} =~ /y/i) {
  428. print "What command do you want to use to invoke your compiler?\n";
  429. print "[\e[1;32m$config{CC}\e[0m] -> ";
  430. chomp($config{CC} = <STDIN>);
  431. if ($config{CC} eq "") {
  432. $config{CC} = "g++";
  433. }
  434. chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
  435. if ($foo ne "") {
  436. `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/;
  437. $config{GCCVER} = defined $1 ? $1 : '';
  438. $config{GCCMINOR} = defined $2 ? $2 : '0';
  439. print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
  440. if ($config{GCCVER} < 3) {
  441. print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
  442. }
  443. }
  444. else {
  445. print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
  446. }
  447. }
  448. }
  449. print "\n";
  450. # Directory Settings..
  451. my $tmpbase = $config{BASE_DIR};
  452. dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
  453. if ($tmpbase ne $config{BASE_DIR}) {
  454. $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/etc"); # Configuration Dir
  455. $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
  456. $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
  457. $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
  458. $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
  459. }
  460. dir_check("are the configuration files", "CONFIG_DIR");
  461. dir_check("are the modules to be compiled to", "MODULE_DIR");
  462. dir_check("is the IRCd binary to be placed", "BINARY_DIR");
  463. dir_check("are variable data files to be located in", "DATA_DIR");
  464. dir_check("are the logs to be stored in", "LOG_DIR");
  465. dir_check("do you want the build to take place", "BUILD_DIR");
  466. my $chose_hiperf = 0;
  467. if ($has_kqueue) {
  468. yesno('USE_KQUEUE',"You are running a BSD operating system, and kqueue\nwas detected. Would you like to enable kqueue support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable kqueue?");
  469. print "\n";
  470. if ($config{USE_KQUEUE} eq "y") {
  471. $chose_hiperf = 1;
  472. }
  473. }
  474. if ($has_epoll) {
  475. yesno('USE_EPOLL',"You are running a Linux 2.6+ operating system, and epoll\nwas detected. Would you like to enable epoll support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable epoll?");
  476. print "\n";
  477. if ($config{USE_EPOLL} eq "y") {
  478. $chose_hiperf = 1;
  479. }
  480. }
  481. if ($has_ports) {
  482. yesno('USE_PORTS',"You are running Solaris 10.\nWould you like to enable I/O completion ports support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable support for I/O completion ports?");
  483. print "\n";
  484. if ($config{USE_PORTS} eq "y") {
  485. $chose_hiperf = 1;
  486. }
  487. }
  488. if (!$chose_hiperf) {
  489. yesno('USE_POLL', "Would you like to use poll?\n This is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable poll?");
  490. if ($config{USE_POLL} ne "y")
  491. {
  492. print "No high-performance socket engines are available, or you chose\n";
  493. print "not to enable one. Defaulting to select() engine.\n\n";
  494. }
  495. }
  496. $config{USE_FREEBSD_BASE_SSL} = "n";
  497. $config{USE_FREEBSD_PORTS_SSL} = "n";
  498. if ($config{HAS_OPENSSL_PORT} ne "")
  499. {
  500. $config{USE_FREEBSD_PORTS_SSL} = "y";
  501. print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
  502. print "version \e[1;32m".$config{HAS_OPENSSL_PORT}."\e[0m. Your base system OpenSSL is version \e[1;32m".$openssl_ver."\e[0m.\n\n";
  503. yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
  504. print "\n";
  505. $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
  506. if ($config{USE_FREEBSD_BASE_SSL} eq "n")
  507. {
  508. # update to port version
  509. $openssl_ver = $config{HAS_OPENSSL_PORT};
  510. }
  511. }
  512. else
  513. {
  514. $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
  515. }
  516. $config{USE_SSL} ||= "n";
  517. $config{MODUPDATE} ||= 'n';
  518. if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
  519. {
  520. print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
  521. print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
  522. yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
  523. if ($config{USE_SSL} eq "y")
  524. {
  525. if ($config{HAS_GNUTLS} eq "y")
  526. {
  527. yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
  528. if ($config{USE_GNUTLS} eq "y")
  529. {
  530. print "\nUsing GnuTLS SSL module.\n";
  531. }
  532. }
  533. if ($config{HAS_OPENSSL} eq "y")
  534. {
  535. yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
  536. if ($config{USE_OPENSSL} eq "y")
  537. {
  538. print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
  539. }
  540. }
  541. }
  542. }
  543. else
  544. {
  545. print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
  546. print "is in your path.\n\n";
  547. }
  548. yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
  549. print "\n";
  550. if ($config{MODUPDATE} eq "y") {
  551. print "Checking for upgrades to extra and third-party modules... ";
  552. system "./modulemanager upgrade";
  553. }
  554. }
  555. # We are on a POSIX system, we can enable POSIX extras without asking
  556. symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
  557. dumphash();
  558. if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
  559. {
  560. print "Sorry, but I couldn't detect GnuTLS. Make sure pkg-config is in your path.\n";
  561. exit(0);
  562. }
  563. if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
  564. {
  565. print "Sorry, but I couldn't detect OpenSSL. Make sure pkg-config and openssl are in your path.\n";
  566. exit(0);
  567. }
  568. our $failed = 0;
  569. $config{CERTGEN} ||= 'y';
  570. yesno('CERTGEN',"Would you like to generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
  571. if ($config{USE_GNUTLS} eq "y") {
  572. unless (-r "src/modules/m_ssl_gnutls.cpp") {
  573. print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
  574. symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
  575. }
  576. if ($interactive && $config{CERTGEN} eq 'y')
  577. {
  578. unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
  579. print "SSL certificates not found, generating.. \n\n
  580. *************************************************************
  581. * Generating the private key may take some time, once done, *
  582. * answer the questions which follow. If you are unsure, *
  583. * just hit enter! *
  584. *************************************************************\n\n";
  585. $failed = make_gnutls_cert();
  586. if ($failed) {
  587. print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
  588. } else {
  589. print "\nCertificate generation complete, copying to config directory... ";
  590. File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
  591. File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
  592. print "Done.\n\n";
  593. }
  594. }
  595. else {
  596. print "SSL certificates found, skipping.\n\n";
  597. }
  598. }
  599. else
  600. {
  601. print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
  602. }
  603. }
  604. if ($config{USE_OPENSSL} eq "y") {
  605. unless (-r "src/modules/m_ssl_openssl.cpp") {
  606. print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
  607. symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
  608. }
  609. $failed = 0;
  610. if ($interactive && $config{CERTGEN} eq 'y')
  611. {
  612. unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
  613. print "SSL certificates not found, generating.. \n\n
  614. *************************************************************
  615. * Generating the certificates may take some time, go grab a *
  616. * coffee or something. *
  617. *************************************************************\n\n";
  618. make_openssl_cert();
  619. print "\nCertificate generation complete, copying to config directory... ";
  620. File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
  621. File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
  622. File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
  623. print "Done.\n\n";
  624. } else {
  625. print "SSL certificates found, skipping.\n\n"
  626. }
  627. }
  628. else
  629. {
  630. print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
  631. }
  632. }
  633. if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
  634. print "Skipping SSL certificate generation as SSL support is not available.\n\n";
  635. }
  636. depcheck();
  637. writefiles(1);
  638. makecache();
  639. print "\n\n";
  640. print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
  641. if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
  642. print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
  643. print "modules in your config. This configure script has added those modules to the\n";
  644. print "build process. For more info, please refer to:\n";
  645. print "\e[1;32mhttps://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
  646. }
  647. print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
  648. if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
  649. print "\e[1;32mWARNING!\e[0m You are running OpenBSD but you are using the base gcc package\nrather than eg++. This compile will most likely fail, but I'm letting you\ngo ahead with it anyway, just in case I'm wrong :-)\n";
  650. }
  651. if ($config{GCCVER} < "3") {
  652. print <<FOO2;
  653. \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
  654. GCC 2.x series compilers only had partial (read as broken) C++ support, and
  655. your compile will most likely fail horribly! If you have any problems, do NOT
  656. report them to the bugtracker or forums without first upgrading your compiler
  657. to a newer 3.x or 4.x (or whatever is available currently) version.
  658. FOO2
  659. }
  660. if ($^O eq 'openbsd') {
  661. print <<__OPENBSD_WARNING__;
  662. \e[1;32mWARNING!\e[0m OpenBSD 6.5 changed Make to no longer look for BSDmakefile when
  663. searching for the makefile. If the version of OpenBSD you are using is 6.5 or
  664. newer then you will need to run '\e[1;32mmake -f BSDmakefile\e[0m' or '\e[1;32mgmake\e[0m' instead.
  665. __OPENBSD_WARNING__
  666. }
  667. ################################################################################
  668. # HELPER FUNCTIONS #
  669. ################################################################################
  670. sub getcache {
  671. # Retrieves the .config.cache file, and loads values into the main config hash.
  672. open(CACHE, ".config.cache") or return 0;
  673. while (<CACHE>) {
  674. chomp;
  675. # Ignore Blank lines, and comments..
  676. next if /^\s*$/;
  677. next if /^\s*#/;
  678. my ($key, $value) = split("=", $_, 2);
  679. $value =~ /^\"(.*)\"$/;
  680. # Do something with data here!
  681. $config{$key} = $1;
  682. }
  683. close(CACHE);
  684. return 1;
  685. }
  686. sub makecache {
  687. # Dump the contents of %config
  688. print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
  689. open(FILEHANDLE, ">.config.cache");
  690. foreach my $key (keys %config) {
  691. print FILEHANDLE "$key=\"$config{$key}\"\n";
  692. }
  693. close(FILEHANDLE);
  694. }
  695. sub dir_check {
  696. my ($desc, $hash_key) = @_;
  697. my $complete = 0;
  698. while (!$complete) {
  699. print "In what directory $desc?\n";
  700. print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
  701. chomp(my $var = <STDIN>);
  702. if ($var eq "") {
  703. $var = $config{$hash_key};
  704. }
  705. if ($var =~ /^\~\/(.+)$/) {
  706. # Convert it to a full path..
  707. $var = resolve_directory($ENV{HOME} . "/" . $1);
  708. }
  709. elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
  710. {
  711. # Assume relative Path was given.. fill in the rest.
  712. $var = $this . "/$var";
  713. }
  714. $var = resolve_directory($var);
  715. if (! -e $var) {
  716. print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
  717. chomp(my $tmp = <STDIN>);
  718. if (($tmp eq "") || ($tmp =~ /^y/i)) {
  719. # Attempt to Create the Dir..
  720. my $chk = eval {
  721. use File::Path ();
  722. File::Path::mkpath($var, 0, 0777);
  723. 1;
  724. };
  725. unless (defined($chk) && -d $var) {
  726. print "Unable to create directory. ($var)\n\n";
  727. # Restart Loop..
  728. next;
  729. }
  730. } else {
  731. # They said they don't want to create, and we can't install there.
  732. print "\n\n";
  733. next;
  734. }
  735. } else {
  736. if (!is_dir($var)) {
  737. # Target exists, but is not a directory.
  738. print "File $var exists, but is not a directory.\n\n";
  739. next;
  740. }
  741. }
  742. # Either Dir Exists, or was created fine.
  743. $config{$hash_key} = $var;
  744. $complete = 1;
  745. print "\n";
  746. }
  747. }
  748. our $SHARED = "";
  749. my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
  750. sub writefiles {
  751. my($writeheader) = @_;
  752. # First File.. inspircd_config.h
  753. chomp(my $incos = `uname -n -s -r`);
  754. chomp(my $version = `sh src/version.sh`);
  755. chomp(my $revision2 = getrevision());
  756. my $branch = "InspIRCd-0.0";
  757. if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
  758. {
  759. $branch = $1;
  760. }
  761. if ($writeheader == 1)
  762. {
  763. print "Writing \e[1;32minspircd_config.h\e[0m\n";
  764. open(FILEHANDLE, ">include/inspircd_config.h.tmp");
  765. print FILEHANDLE <<EOF;
  766. /* Auto generated by configure, do not modify! */
  767. #ifndef INSPIRCD_CONFIG_H
  768. #define INSPIRCD_CONFIG_H
  769. /* this is for windows support. */
  770. #define CoreExport /**/
  771. #define DllExport /**/
  772. #define CONFIG_PATH "$config{CONFIG_DIR}"
  773. #define DATA_PATH "$config{DATA_DIR}"
  774. #define LOG_PATH "$config{LOG_DIR}"
  775. #define MOD_PATH "$config{MODULE_DIR}"
  776. #define SOMAXCONN_S "$config{_SOMAXCONN}"
  777. #define ENTRYPOINT int main(int argc, char** argv)
  778. EOF
  779. print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
  780. if ($config{OSNAME} =~ /SunOS/i) {
  781. print FILEHANDLE "#define IS_SOLARIS\n";
  782. }
  783. if ($config{OSNAME} =~ /MINGW32/i) {
  784. print FILEHANDLE "#define IS_MINGW\n";
  785. }
  786. if ($config{GCCVER} >= 3) {
  787. print FILEHANDLE "#define GCC3\n";
  788. }
  789. if ($config{HAS_STRLCPY} eq "true") {
  790. print FILEHANDLE "#define HAS_STRLCPY\n";
  791. }
  792. if ($config{HAS_STDINT} eq "true") {
  793. print FILEHANDLE "#define HAS_STDINT\n";
  794. }
  795. if ($config{HAS_EVENTFD} eq 'true') {
  796. print FILEHANDLE "#define HAS_EVENTFD\n";
  797. }
  798. if ($config{OSNAME} !~ /DARWIN/i) {
  799. print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
  800. } else {
  801. print FILEHANDLE "#ifdef MAC_OS_X_VERSION_10_12\n";
  802. print FILEHANDLE "# define HAS_CLOCK_GETTIME\n";
  803. print FILEHANDLE "#endif\n";
  804. }
  805. my $use_hiperf = 0;
  806. if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
  807. print FILEHANDLE "#define USE_KQUEUE\n";
  808. $config{SOCKETENGINE} = "socketengine_kqueue";
  809. $use_hiperf = 1;
  810. }
  811. if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
  812. print FILEHANDLE "#define USE_EPOLL\n";
  813. $config{SOCKETENGINE} = "socketengine_epoll";
  814. $use_hiperf = 1;
  815. }
  816. if (($has_ports) && ($config{USE_PORTS} eq "y")) {
  817. print FILEHANDLE "#define USE_PORTS\n";
  818. $config{SOCKETENGINE} = "socketengine_ports";
  819. $use_hiperf = 1;
  820. }
  821. # user didn't choose either epoll or select for their OS.
  822. # default them to USE_SELECT (ewwy puke puke)
  823. if (!$use_hiperf) {
  824. print "no hi-perf, " . $config{USE_POLL};
  825. if ($config{USE_POLL} eq "y")
  826. {
  827. print FILEHANDLE "#define USE_POLL\n";
  828. $config{SOCKETENGINE} = "socketengine_poll";
  829. }
  830. else
  831. {
  832. print FILEHANDLE "#define USE_SELECT\n";
  833. $config{SOCKETENGINE} = "socketengine_select";
  834. }
  835. }
  836. print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
  837. close(FILEHANDLE);
  838. open(FILEHANDLE, ">include/inspircd_version.h.tmp");
  839. print FILEHANDLE <<EOF;
  840. #define BRANCH "$branch"
  841. #define VERSION "$version"
  842. #define REVISION "$revision2"
  843. #define SYSTEM "$incos"
  844. EOF
  845. close FILEHANDLE;
  846. for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
  847. my $diff = 0;
  848. open my $fh1, $file or $diff = 1;
  849. open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
  850. while (!$diff) {
  851. my $line1 = <$fh1>;
  852. my $line2 = <$fh2>;
  853. if (defined($line1) != defined($line2)) {
  854. $diff = 1;
  855. } elsif (!defined $line1) {
  856. last;
  857. } else {
  858. $diff = ($line1 ne $line2);
  859. }
  860. }
  861. if ($diff) {
  862. unlink $file;
  863. rename "$file.tmp", $file;
  864. } else {
  865. unlink "$file.tmp";
  866. }
  867. }
  868. }
  869. # Write all .in files.
  870. my $tmp = "";
  871. my $file = "";
  872. my $exe = "inspircd";
  873. # Do this once here, and cache it in the .*.inc files,
  874. # rather than attempting to read src/version.sh from
  875. # compiled code -- we might not have the source to hand.
  876. # Fix for bug#177 by Brain.
  877. chomp($version = `sh ./src/version.sh`);
  878. chomp(my $revision = getrevision());
  879. $version = "$version(r$revision)";
  880. # We can actually parse any file starting with . and ending with .inc,
  881. # but right now we only parse .inspircd.inc to form './inspircd'
  882. prepare_dynamic_makefile();
  883. my @dotfiles = qw(main.mk inspircd);
  884. push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
  885. # HACK: we need to know if we are on GCC6 to disable the omission of `this` null pointer checks.
  886. $config{GCC6} = `$config{CC} --version 2>/dev/null` =~ /gcc/i && $config{GCCVER} ge "6" ? "true" : "false";
  887. foreach my $file (@dotfiles) {
  888. open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
  889. $_ = join '', <FILEHANDLE>;
  890. close(FILEHANDLE);
  891. $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
  892. for my $var (qw(
  893. CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
  894. STARTSCRIPT DESTINATION SOCKETENGINE LOG_DIR GCC6
  895. )) {
  896. s/\@$var\@/$config{$var}/g;
  897. }
  898. s/\@EXECUTABLE\@/$exe/ if defined $exe;
  899. s/\@VERSION\@/$version/ if defined $version;
  900. if ($file eq 'main.mk') {
  901. print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
  902. my $mk_tmp = $_;
  903. s/\@IFDEF (\S+)/ifdef $1/g;
  904. s/\@IFNDEF (\S+)/ifndef $1/g;
  905. s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
  906. s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
  907. s/\@ELSE/else/g;
  908. s/\@ENDIF/endif/g;
  909. s/ *\@BSD_ONLY .*\n//g;
  910. s/\@GNU_ONLY //g;
  911. s/\@DO_EXPORT (.*)/export $1/g;
  912. open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
  913. print MKF $_;
  914. close MKF;
  915. print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
  916. $_ = $mk_tmp;
  917. s/\@IFDEF (\S+)/.if defined($1)/g;
  918. s/\@IFNDEF (\S+)/.if !defined($1)/g;
  919. s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
  920. s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
  921. s/\@ELSE/.else/g;
  922. s/\@ENDIF/.endif/g;
  923. s/\@BSD_ONLY //g;
  924. s/ *\@GNU_ONLY .*\n//g;
  925. $mk_tmp = $_;
  926. $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
  927. open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
  928. print MKF $mk_tmp;
  929. close MKF;
  930. } else {
  931. print "Writing \e[1;32m$file\e[0m ...\n";
  932. open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
  933. print FILEHANDLE $_;
  934. close(FILEHANDLE);
  935. }
  936. }
  937. chmod 0755, 'inspircd';
  938. }
  939. sub depcheck
  940. {
  941. getmodules();
  942. for my $mod (@modlist) {
  943. getcompilerflags("src/modules/m_$mod.cpp");
  944. getlinkerflags("src/modules/m_$mod.cpp");
  945. }
  946. }
  947. sub prepare_dynamic_makefile
  948. {
  949. my $i = 0;
  950. if (!$has_epoll)
  951. {
  952. $config{USE_EPOLL} = 0;
  953. }
  954. if (!$has_kqueue)
  955. {
  956. $config{USE_KQUEUE} = 0;
  957. }
  958. if (!$has_ports)
  959. {
  960. $config{USE_PORTS} = 0;
  961. }
  962. }
  963. # Routine to list out the extra/ modules that have been enabled.
  964. # Note: when getting any filenames out and comparing, it's important to lc it if the
  965. # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
  966. # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
  967. # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
  968. sub list_extras () {
  969. use File::Spec;
  970. # @_ not used
  971. my $srcdir = File::Spec->catdir("src", "modules");
  972. my $abs_srcdir = File::Spec->rel2abs($srcdir);
  973. local $_;
  974. my $dd;
  975. opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
  976. my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
  977. closedir $dd;
  978. undef $dd;
  979. opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
  980. my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
  981. closedir $dd;
  982. undef $dd;
  983. my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
  984. my %extras = ();
  985. EXTRA: for my $extra (@extras) {
  986. next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
  987. my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
  988. my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
  989. next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
  990. if (-l $abs_source) {
  991. # Symlink, is it in the right place?
  992. my $targ = readlink($abs_source);
  993. my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
  994. if ($abs_targ eq $abs_extra) {
  995. $extras{$extra} = "\e[32;1menabled\e[0m";
  996. } else {
  997. $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
  998. }
  999. } elsif (-e $abs_source) {
  1000. my ($devext, $inoext) = stat($abs_extra);
  1001. my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
  1002. if ($lnksrc > 1) {
  1003. if ($devsrc == $devext && $inosrc == $inoext) {
  1004. $extras{$extra} = "\e[32;1menabled\e[0m";
  1005. } else {
  1006. $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
  1007. }
  1008. } else {
  1009. open my $extfd, "<", $abs_extra;
  1010. open my $srcfd, "<", $abs_source;
  1011. local $/ = undef;
  1012. if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
  1013. $extras{$extra} = "\e[32;1menabled\e[0m";
  1014. } else {
  1015. $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
  1016. }
  1017. }
  1018. } else {
  1019. $extras{$extra} = "\e[33;1mdisabled\e[0m";
  1020. }
  1021. }
  1022. # Now let's add dependency info
  1023. for my $extra (keys(%extras)) {
  1024. next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
  1025. my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
  1026. my @deps = split / +/, getdependencies($abs_extra);
  1027. for my $dep (@deps) {
  1028. if (exists($extras{$dep})) {
  1029. my $ref = \$extras{$dep}; # Take reference.
  1030. if ($$ref !~ m/needed by/) {
  1031. # First dependency found.
  1032. if ($$ref =~ m/enabled/) {
  1033. $$ref .= " (needed by \e[32;1m$extra\e[0m";
  1034. } else {
  1035. $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
  1036. $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
  1037. }
  1038. } else {
  1039. if ($$ref =~ m/enabled/) {
  1040. $$ref .= ", \e[32;1m$extra\e[0m";
  1041. } else {
  1042. $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
  1043. }
  1044. }
  1045. }
  1046. }
  1047. }
  1048. for my $extra (sort {$a cmp $b} keys(%extras)) {
  1049. my $text = $extras{$extra};
  1050. if ($text =~ m/needed by/ && $text !~ m/enabled/) {
  1051. printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
  1052. } else {
  1053. printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
  1054. }
  1055. }
  1056. return keys(%extras) if wantarray; # Can be used by manage_extras.
  1057. }
  1058. sub enable_extras (@) {
  1059. my (@extras) = @_;
  1060. for my $extra (@extras) {
  1061. my $extrapath = "src/modules/extra/$extra";
  1062. if (!-e $extrapath) {
  1063. print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
  1064. next;
  1065. }
  1066. my $source = "src/modules/$extra";
  1067. if (-e $source) {
  1068. print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
  1069. next;
  1070. }
  1071. # Get dependencies, and add them to be processed.
  1072. my @deps = split / +/, getdependencies($extrapath);
  1073. for my $dep (@deps) {
  1074. next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
  1075. if (!-e "src/modules/$dep") {
  1076. if (-e "src/modules/extra/$dep") {
  1077. print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
  1078. push @extras, $dep;
  1079. } else {
  1080. print STDERR "\e[33;1mWARNING:\e[0m module \e[32;1m$extra\e[0m might be missing dependency \e[32;1m$dep\e[0m - YOU are responsible for satisfying it!\n";
  1081. }
  1082. }
  1083. }
  1084. print "Enabling $extra ... \n";
  1085. symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
  1086. }
  1087. }
  1088. sub disable_extras (@)
  1089. {
  1090. opendir my $dd, "src/modules/extra/";
  1091. my @files = readdir($dd);
  1092. closedir $dd;
  1093. my (@extras) = @_;
  1094. EXTRA: for my $extra (@extras) {
  1095. my $extrapath = "src/modules/extra/$extra";
  1096. my $source = "src/modules/$extra";
  1097. if (!-e $extrapath) {
  1098. print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
  1099. next;
  1100. }
  1101. if ((! -l $source) || readlink($source) ne "extra/$extra") {
  1102. print STDERR "Cannot disable \e[32;1m$extra\e[0m : Source is not a link or doesn't refer to the right file. Remove manually if this is in error.\n";
  1103. next;
  1104. }
  1105. # Check if anything needs this.
  1106. for my $file (@files) {
  1107. my @deps = split / +/, getdependencies("src/modules/extra/$file");
  1108. # File depends on this extra...
  1109. if (scalar(grep { $_ eq $extra } @deps) > 0) {
  1110. # And is both enabled and not about to be disabled.
  1111. if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
  1112. print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
  1113. next EXTRA;
  1114. }
  1115. }
  1116. }
  1117. # Now remove.
  1118. print "Disabling $extra ... \n";
  1119. unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";
  1120. }
  1121. }