Multiplay Labs

from the MPUK.HQ

perl Makefile.PL errors with “Unable to find a perl 5″ on cygwin

without comments

When trying to build a new module on one of our machines which runs cygwin the basic command perl Makefile.pl failed with the error:

Unable to find a perl 5 (by these names: perl.exe perl.exe perl5.exe perl5.8.0.exe miniperl.exe, in these dirs: /usr/local/bin /usr/bin /bin /usr/X11R6/bin /usr/local/libexec/apache /usr/local/bin /usr/bin /bin /usr/X11R6/bin /cygdrive/c/WINDOWS/system32 /cygdrive/c/WINDOWS /cygdrive/c/WINDOWS/System32/Wbem /cygdrive/c/Program /bin /usr/bin)

After doing some digging this turned out to be a simple permissions issue on the perl.exe although perl scripts would happily run in perl -x /usr/bin/perl.exe was returning false.

The fix was a simple chmod a+x /usr/bin/perl.exe for anyone who comes across this issue.

Written by Steven Hartland

July 4th, 2009 at 1:29 pm

Posted in Hackery

Ruby URI.parse being strict results in URI::InvalidURIError

without comments

When using ruby’s URI.parse yesterday I was getting URI::InvalidURIError on what seemed to be a perfectly valid URI. After much digging in the source and reading the URI RFC 2396 and subsequent 3986, I discovered that the reason for this is that URI.parse applies this RFC strictly, so where a number of applications are quite happy to provide and use URI’s containing the “unwise” characters, URI.parse doesn’t accept them and throws a URI::InvalidError.

Fear not though there’s a really easy fix, just replace the direct call with:

myuri = URI.parse( URI.encode( uri_string ) )

This does however raise the question: Should parse implicitly call encode?

Written by Steven Hartland

July 2nd, 2009 at 8:36 am

Posted in Code

ruby very slow http downloads and high cpu usage

without comments

I’ve been doing some work to www.fileplay.net which required the dowload of files using ruby and during tests I was getting very slow download times coupled with very high cpu load from the ruby process.

The code in use was very simple:

require 'open-uri'
open( [http uri] )

I did some benchmarking and the download of a 157MB file from the local machine was taking over 20 seconds and using 100% where as wget for the same file only took 0.7 seconds.

Digging some more and profiling the code with RubyProf revealed that during the execution of the download over 11,000 threads where being created. This I tracked down to the net/protocol module and the Net::BufferIO::rbuf_fill method which is using a timeout block to wrap the @io.sysread(1024) call. This is clearly an extremely bad way to do this at it creates a new thread for every read call to monitor for timeout and was totally crippling the performance.

After playing with several changes to the core net/protocol.rb including:

  • Replacing timeout( @read_timeout ) { .. } with IO.select
  • Increasing the read requests to 1Mb
  • Garding against the use of a str.split!

I managed to get ruby to perform very similar to wget and download my test file in 0.8 seconds.

For those using ruby to do http requests of any significant size I would hence strongly suggest applying the patch I’ve uploaded to ruby bug tracker here: Ruby very slow http downloads bug

Written by Steven Hartland

June 27th, 2009 at 4:24 pm

Posted in Code, Hackery

Safari Exports Element Ids to Javascript Namespace

without comments

Well seems Safari is totally retarded and exports all html elements to the javascript namespace so if you have the something like the following it breaks:-

<div id="myDialog">my content</div>
<script type="text/javascript>
var myDialog;
if ( ! myDialog )
{
// Safari never gets here as myDialog = the HTMLElement defined above
myDialog = new MyDialog( .... );
...
}
// Safari now fails as the object was never created
// Instead myDialog is the div element
myDialog.myFunction();
</script>

This was experienced here in Safari 4 build 528.16 and reported by users in Safari 3 as well.

Written by Steven Hartland

May 28th, 2009 at 5:54 pm

Posted in Hackery

BF2cc Punkbuster directory option is borken

without comments

Been playing with BF2cc for inclusion in Clanforge v3 and I discovered today that BF2cc’s option to set the working path for Punkbuster is borken. When you use +pbPath it converts it to +pbpath before passing it to the server on the command line. The server however doesnt support +pbpath it requires +pbPath as its command line options are case sensitive, hense if fails.

The workaround for this bug is to put +pbPath <path> in GameExecArgs of config.xml instead of passing it on the command line to bf2ccd.

Written by Steven Hartland

March 15th, 2009 at 1:20 am

Posted in Hackery

ultrastats mysql database port fix

without comments

Just been playing more with ultrastats and went to set it up on our test db which runs on a none standard port. After fighting with it for 1/2 an hour it telling me access denied I looked at to code to find the nice port option it asks you for in the installer was totally and utterly ignored :(

Here’s the patch

--- ./install.php.orig	Tue Feb 24 21:19:24 2009
+++ ./install.php	Tue Feb 24 21:21:38 2009
@@ -240,5 +240,5 @@
 
 	// Now Check database connect
-	$link_id = mysql_connect( $_SESSION['DB_HOST'], $_SESSION['DB_USER'], $_SESSION['DB_PASS']);
+	$link_id = mysql_connect( "{$_SESSION['DB_HOST']}:{$_SESSION['DB_PORT']}", $_SESSION['DB_USER'], $_SESSION['DB_PASS']);
 	if (!$link_id) 
 		RevertOneStep( $content['INSTALL_STEP']-1, GetAndReplaceLangStr( $content['LN_INSTALL_ERRORCONNECTFAILED'], $_SESSION['DB_HOST']) . "<br>" . DB_ReturnSimpleErrorMsg() );
--- ./include/functions_db.php.orig	Tue Feb 24 21:24:00 2009
+++ ./include/functions_db.php	Tue Feb 24 21:24:48 2009
@@ -43,5 +43,5 @@
 
 	//TODO: Check variables first
-	$link_id = @mysql_connect($CFG['DBServer'],$CFG['User'],$CFG['Pass']);
+	$link_id = @mysql_connect("{$CFG['DBServer']}:{$CFG['Port']}",$CFG['User'],$CFG['Pass']);
 	if (!$link_id) 
 		DB_PrintError("Link-ID == false, connect to ".$CFG['DBServer']." failed", true);

Written by Steven Hartland

February 24th, 2009 at 10:41 pm

Posted in Hackery

Tagged with , , ,

ultrastats usernames with @ in them fix

without comments

The standard setup for ultrastats uses url parsing to create the DB entries for the monitored servers. This is far from optimum and when the username contains an ‘@’ falls down completely with their current code.

The fix for this is the following patch:

--- include/functions_common.php.orig	2009-02-23 17:33:29.000000000 +0000
+++ include/functions_common.php	2009-02-23 18:13:34.000000000 +0000
@@ -1135,10 +1135,9 @@
 	$ftpvalues['ftpfilename'] = "";
 
-	if ( strpos($ftpUrl, "@") !== false )
-	{	//Username and maybe password is given
-		$tmparray = explode("@", $ftpUrl);
-
+	$at_pos = strrpos( $ftpUrl, '@' );
+	if ( $at_pos !== false )
+	{	// Username and maybe password is given
 		// Set Username 
-		$ftpvalues['username'] = substr( $tmparray[0], 6 );
+		$ftpvalues['username'] = substr( $ftpUrl, 6, $at_pos - 6 );
 
 		// Check if Password is given
@@ -1149,13 +1148,16 @@
 			$ftpvalues['password'] = $tmparray2[1];
 		}
+		$server = substr( $ftpUrl, $at_pos + 1 );
 
 		// Get FTP Servername
-		$ftpvalues['ftpserver'] = substr( $tmparray[1], 0,  strpos($tmparray[1], "/") );
+		$first_slash = strpos( $server, '/' );
+		$last_slash = strrpos( $server, '/' );
+		$ftpvalues['ftpserver'] = substr( $server, 0,  $first_slash );
 
 		// Get FTP Path
-		$ftpvalues['ftppath'] = substr( $tmparray[1], strpos($tmparray[1], "/"), strrpos($tmparray[1], "/")-strpos($tmparray[1], "/")+1 );
+		$ftpvalues['ftppath'] = substr( $server, $first_slash, $last_slash - $first_slash + 1 );
 
 		// Get the Logfilename
-		$ftpvalues['ftpfilename'] = substr( $tmparray[1], strrpos($tmparray[1], "/")+1 );
+		$ftpvalues['ftpfilename'] = substr( $server, $last_slash + 1 );
 	}
 	else

Written by Steven Hartland

February 23rd, 2009 at 6:26 pm

Posted in Hackery

Tagged with , ,

Perl CGI.pm problems with query strings under Apache

without comments

Ever had a problem with query strings causing strange behaviour in apache when using the CGI module?
If you have the patch below might just save you some time and effort hunting down the problem.

--- CGI.pm.orig	Sat Mar  1 16:58:19 2008
+++ CGI.pm	Sat Mar  1 18:39:21 2008
@@ -2779,5 +2779,10 @@
    my $raw_script_name = $ENV{SCRIPT_NAME} || '';
    my $raw_path_info   = $ENV{PATH_INFO}   || '';
-   my $uri             = unescape($self->request_uri) || '';
+   my $uri             = $self->request_uri || '';
+
+   # ensure we dont get any query string as that can include escaped //
+   # e.g. a url parameter, which will break the apache bug fix
+   $uri =~ s/\?(.*)$//; 
+   $uri = unescape($uri);
 
    my $protected    = quotemeta($raw_path_info);

Written by Steven Hartland

February 21st, 2009 at 11:45 pm

Posted in Hackery

Tagged with , , ,

Running perl scripts from rc.d under FreeBSD

without comments

If you have even tried to run a perl script under FreeBSD’s startup system rc.d then you’ll have hit upon a little problem where it doesnt correctly recognise the running process on shutdown. There’s a simple fix for this just apply the patch below and you’ll be good to go.

--- /etc/rc.subr.orig	Mon Oct  8 18:31:34 2007
+++ /etc/rc.subr	Mon Oct  8 18:32:31 2007
@@ -271,5 +271,5 @@
 		_fp_args='_argv'
 		_fp_match='case "$_argv" in
-		    ${_interp}|"${_interp} "*|"${_interpbn}: ${_procname}"*)'
+		    ${_interp}|"${_interp} "*|"[${_interpbn}]"|"${_interpbn}: ${_procname}"*)'
 	else					# a normal daemon
 		_procnamebn=${_procname##*/}

Written by Steven Hartland

February 21st, 2009 at 11:40 pm

Posted in Hackery

Tagged with , , ,

Halflife patches break query protocol

without comments

Always on of those things you love to get you install an update and it breaks things. Anyway some of the recent updates to valves old none source games updated to use the new a2s query, all good but this implementation doesn’t properly support the handshake in the challenge response. More specifically the server never responds to the request for a challenge.

In order to fix this in qstat I’ve had to make it do a bogus request which makes the server send a challenge and hence allows the handshake to complete correctly.

Anyone who uses qstat should update to the latest version in svn.

Written by Steven Hartland

February 21st, 2009 at 11:36 pm

Posted in Hackery

Tagged with , , , ,