<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dirty Motherfucking Blog</title>
	<atom:link href="http://www.dirty-motherfucker.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dirty-motherfucker.org/blog</link>
	<description>All kinds of shit</description>
	<lastBuildDate>Tue, 17 Aug 2010 18:19:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>ICH9R Raid Recovery</title>
		<link>http://www.dirty-motherfucker.org/blog/2010/08/17/ich9r-raid-recovery/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2010/08/17/ich9r-raid-recovery/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 18:19:53 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[administration]]></category>
		<category><![CDATA[ich9r]]></category>
		<category><![CDATA[raid]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=313</guid>
		<description><![CDATA[You know how everyone would tell you to not use RAID0 unless the data you store on it is worthless? And do you know how the same people would most likely tell you to never put your operating system on a RAID0 volume? Well, I ignored those people and did it anyway. And what did [...]]]></description>
			<content:encoded><![CDATA[<p>You know how everyone would tell you to not use RAID0 unless the data you store on it is worthless? And do you know how the same people would most likely tell you to never put your operating system on a RAID0 volume?</p>
<p>Well, I ignored those people and did it anyway. And what did I, shortly after, get in return? A failed RAID volume. Yay.</p>
<p>One day I simply shut off my computer for a little restructuring of my work area, and after I turned it on again, it told me it can&#8217;t boot, cause, well, yeah. In fact, it reported that one of the RAID disks was no longer a member of the array. So I rebooted multiple times, shut off the computer and power supply, booted back up. The volume remained failed.</p>
<p>So I booted into an Ubuntu Live CD and browsed the web for solutions. Cause I was certain no data could have actually been lost. The RAID controller was just stupid. The solutions I found were mostly along the lines of &#8220;re-create the volume and restore a backup&#8221;. Of course I had no backup.<br />
So I thought I would just back up the drives contents now and try to simply re-create the volume and write the data back.</p>
<p>Using dd, I did exactly that:</p>
<pre class="brush: plain;">
dd if=/dev/sda of=/media/backup/sda.dd bs=2MB
dd if=/dev/sdb of=/media/backup/sdb.dd bs=2MB
</pre>
<p>This took the whole night of course. So, the next day I rebooted to re-create the RAID volume. But I was very surprised to find that the RAID controller reported the volume to be in perfect health. And surely enough, seconds later my Windows was up and running again.<br />
I praised the gods, instantly made backups and went on with my life.</p>
<p>Until yesterday. When the same shit happened AGAIN. I was minding my own business, when suddenly my computer shut off (due to overheating I assume). When I started it back up again, it, again, reported the RAID volume as failed.<br />
Again, multiple reboots didn&#8217;t do anything. And, again, I went into a Live CD to back up the RAID member disks.<br />
And, AGAIN, today my volume comes up as healthy as ever.</p>
<p>I have no clue if there is any logic behind this or if this was just magic happening. I also have no idea if my actions actually had anything to do with this RAID recovery. But, sure as hell, when I come across a failed ICH9R RAID0 volume again, I&#8217;ll dd the disks and reboot the shit out of it.</p>
<p>And, also, I&#8217;ll be converting back to a non-RAID setup ASAP.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2010/08/17/ich9r-raid-recovery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passing SOAP faults from NuSoap to C#</title>
		<link>http://www.dirty-motherfucker.org/blog/2010/04/27/passing-soap-faults-from-nusoap-to-c/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2010/04/27/passing-soap-faults-from-nusoap-to-c/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 19:59:06 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[nusoap]]></category>
		<category><![CDATA[soap]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=308</guid>
		<description><![CDATA[I am currently implementing a SOAP interface for a PHP application I am working on. The built-in SOAP support in PHP didn&#8217;t really provide everything I needed (namely WSDL generation), so I went with NuSoap. After a lot of pain trying to get a WSDL out of it, that Visual Studio would consume, and correctly [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently implementing a SOAP interface for a PHP application I am working on. The built-in SOAP support in PHP didn&#8217;t really provide everything I needed (namely WSDL generation), so I went with NuSoap.<br />
After a lot of pain trying to get a WSDL out of it, that Visual Studio would consume, and correctly parse the SOAP messages I return, I came along the next big issue today.<br />
Whenever I tried to pass a fault from the server to my C# application, I would receive a nasty exception:</p>
<blockquote><p>Server returned an invalid SOAP Fault.  Please see InnerException for more details.</p></blockquote>
<p>Ok, so let&#8217;s look at that InnerException:</p>
<blockquote><p>Element &#8216;faultstring&#8217; with namespace name &#8221; was not found. Line 6, position 126.</p></blockquote>
<p>What? No &#8220;faultstring&#8221; element? Impossible!<br />
After double-checking my code for obvious errors and confirming with SoapUI that the &#8220;faultstring&#8221; element was indeed present, I started looking for the source of the issue. First I checked the nusoap_fault source, if there was anything weird in there that might confuse the CLR. But it seemed fine.</p>
<p>So I was sure the problem must be in the .Net libraries. I went on to decompile the binaries that are in use when making SOAP requests (namely System.ServiceModel). The actual issue was in System.ServiceModel.Channels.ReceivedFault.CreateFault11(). That function expects the elements of a SOAP fault&#8217;s body to be in a precise order! If the order is anything else than what it expects, it will throw the exception mentioned above.</p>
<p>I did not take the time to check whether this behavior is actually defined by the SOAP definition (although I highly doubt it). I just went on to extend the NuSoap classes to fix the issue. And here they are:</p>
<p>NuSoapServer.php:</p>
<pre class="brush: php;">
&lt;?php
  require_once( &quot;nusoap/nusoap.php&quot; );

  require_once( dirname( __FILE__ ) . &quot;/NuSoapFault.php&quot; );

  /**
  * Wraps a NuSoap server.
  * This class overrides the fault method of nusoap_server to use a customized version of nusoap_fault.
  */
  class NuSoapServer extends nusoap_server {
    /**
     * Specify a fault to be returned to the client.
     * This also acts as a flag to the server that a fault has occured.
     *
     * @param        string $faultcode
     * @param        string $faultstring
     * @param        string $faultactor
     * @param        string $faultdetail
     * @access   public
     */
    function fault( $faultcode, $faultstring, $faultactor='', $faultdetail='' ) {
      if( $faultdetail == &quot;&quot; &amp;&amp; $this-&gt;debug_flag ) {
        $faultdetail = $this-&gt;getDebug();
      }
      $this-&gt;fault = new NuSoapFault( $faultcode, $faultactor, $faultstring, $faultdetail );
      $this-&gt;fault-&gt;soap_defencoding = $this-&gt;soap_defencoding;
    }

  }
?&gt;
</pre>
<p>NuSoapFault.php:</p>
<pre class="brush: php;">
&lt;?php
  require_once( &quot;nusoap/nusoap.php&quot; );

  /**
  * Wraps a SOAP fault.
  * This class overrides nusoap_fault's serialize() method to fix the order in which it's members are serialized.
  * This is necessary to allow for communication with .Net clients.
  */
  class NuSoapFault extends nusoap_fault {
    /**
     * serialize a fault
     *
     * @return       string  The serialization of the fault instance.
     * @access   public
     */
    function serialize() {
      $ns_string = '';
      foreach( $this-&gt;namespaces as $k =&gt; $v ) {
        $ns_string .= &quot;\n  xmlns:$k=\&quot;$v\&quot;&quot;;
      }
      $return_msg =
        '&lt;?xml version=&quot;1.0&quot; encoding=&quot;' . $this-&gt;soap_defencoding . '&quot;?&gt;' .
        '&lt;SOAP-ENV:Envelope SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;' . $ns_string . &quot;&gt;\n&quot; .
          '&lt;SOAP-ENV:Body&gt;' .
            '&lt;SOAP-ENV:Fault&gt;' .
              $this-&gt;serialize_val( $this-&gt;faultcode,   'faultcode'   ) .
              $this-&gt;serialize_val( $this-&gt;faultstring, 'faultstring' ) .
              $this-&gt;serialize_val( $this-&gt;faultactor,  'faultactor'  ) .
              $this-&gt;serialize_val( $this-&gt;faultdetail, 'detail'      ) .
            '&lt;/SOAP-ENV:Fault&gt;' .
          '&lt;/SOAP-ENV:Body&gt;' .
        '&lt;/SOAP-ENV:Envelope&gt;';
      return $return_msg;
    }

  }
?&gt;
</pre>
<p>So now in my actual code I don&#8217;t use nusoap_server anymore, but my own NuSoapServer. And now everything works fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2010/04/27/passing-soap-faults-from-nusoap-to-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding build date/time/count to your C# project</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/12/21/adding-build-datetimecount-to-your-c-project/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/12/21/adding-build-datetimecount-to-your-c-project/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 12:57:42 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=302</guid>
		<description><![CDATA[This is pretty much a straight-forward conversion of http://www.dirty-motherfucker.org/blog/2009/04/24/build-count-of-vc-project-for-version-string/ I was quite pissed that there is no easy option to get something as simple as the build date into your C# project. So here is my pre-build script I use in my C# projects: @echo off SETLOCAL set TARGET_PATH=%~dp0 set IN_FILENAME=&#34;%TARGET_PATH%Version.txt&#34; set OUT_FILENAME=&#34;%TARGET_PATH%Version.cs&#34; set /p [...]]]></description>
			<content:encoded><![CDATA[<p>This is pretty much a straight-forward conversion of http://www.dirty-motherfucker.org/blog/2009/04/24/build-count-of-vc-project-for-version-string/<br />
I was quite pissed that there is no easy option to get something as simple as the build date into your C# project.<br />
So here is my pre-build script I use in my C# projects:</p>
<pre class="brush: plain;">
@echo off
SETLOCAL
set TARGET_PATH=%~dp0
set IN_FILENAME=&quot;%TARGET_PATH%Version.txt&quot;
set OUT_FILENAME=&quot;%TARGET_PATH%Version.cs&quot;
set /p BUILD= &lt; %IN_FILENAME%
set BUILD=%BUILD:~22%
if /I &quot;%BUILD%&quot; == &quot;&quot; set BUILD=0
set /a BUILD=%BUILD%+1
echo #define VERSION_BUILD %BUILD% &gt; %IN_FILENAME%
echo using System; &gt; %OUT_FILENAME%
echo namespace Angler { &gt;&gt; %OUT_FILENAME%
echo 	class Version { &gt;&gt; %OUT_FILENAME%
echo 		public const int BuildCount 	= %BUILD%; &gt;&gt; %OUT_FILENAME%
echo 		public const string BuildDate 	= &quot;%DATE%&quot;; &gt;&gt; %OUT_FILENAME%
echo 		public const string BuildTime 	= &quot;%TIME%&quot;; &gt;&gt; %OUT_FILENAME%
echo 	} &gt;&gt; %OUT_FILENAME%
echo } &gt;&gt; %OUT_FILENAME%
ENDLOCAL
</pre>
<p>I went the easy route with this by simply dropping the build count into an additional file.<br />
I wanted to avoid parsing the value out of the .cs file. But you&#8217;re welcome to improve on this :P</p>
<p>When you first run it, it will create the VersionInfo.txt file which will contain the initial build count (for you to adjust).<br />
I place the script in my project directory as &#8220;Increase build count.cmd&#8221; and add this as a pre-build event: &#8220;$(ProjectDir)Increase build count.cmd&#8221; (INCLUDING the quotes!)<br />
Now you simply add Version.cs to your project and use its members in your program.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/12/21/adding-build-datetimecount-to-your-c-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simulating TCP data from another device</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/12/03/simulating-tcp-data-from-another-device/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/12/03/simulating-tcp-data-from-another-device/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 22:11:22 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[administration]]></category>
		<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=293</guid>
		<description><![CDATA[This almost feels too simple to even mention it. But I guess it doesn&#8217;t hurt putting it our there. Someone might hit it in a desperate Google hunt. So this is the deal. You have a device on your network that controls another device by means of sending out simple TCP payloads. Now you want [...]]]></description>
			<content:encoded><![CDATA[<p>This almost feels too simple to even mention it. But I guess it doesn&#8217;t hurt putting it our there. Someone might hit it in a desperate Google hunt.<br />
So this is the deal. You have a device on your network that controls another device by means of sending out simple TCP payloads.<br />
Now you want to perform the same tasks with your program to get rid of the device. This is how you do it.</p>
<p>First, you wanna fire up your old friend <a href="http://www.wireshark.org/">Wireshark</a>. Now set up the device you want to emulate to send the data to the IP of your machine. Now you can start a Live Capture in Wireshark (Ctrl+E). Now you command your device to send the message by whatever means needed (like pressing the correct button on the device). Now stop the Live Capture in Wireshark (Ctrl+E) and add a filter to get the packet you need.</p>
<p>Let&#8217;s assume the devices IP address is 10.0.0.1 and your IP address is 10.0.0.2. Now the correct filter would be</p>
<pre class="brush: plain;">
ip.src == 10.0.0.1 &amp;&amp; ip.dst == 10.0.0.2
</pre>
<p>Now, hopefully you&#8217;ll see a single packet. In the center panel of Wireshark there should be a Data segment. This is what we want. Right-click it and select Copy -> Bytes (Hex Stream). You&#8217;ll get something like:</p>
<pre class="brush: plain;">
4e656574732c4b2c0100
</pre>
<p>(In case you&#8217;re interested, this is the payload when you press the first button on a <a href="http://neets.dk/products/control_system/307-0001/index.php">Neets Control EU Standard</a> device.)</p>
<p>Now let&#8217;s put this into code. The below example already has 2 payloads that would signal the target device to be turned on or off. For this 2 packets have been captured and can now be selected via the command line. The implementation is straight-forward.</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Neets_Control {
  class Program {

    private static byte[] WORKLOAD_ON   = new byte[] { 0x4e, 0x65, 0x65, 0x74, 0x73, 0x2c, 0x4b, 0x2c, 0x01, 0x00 };
    private static byte[] WORKLOAD_OFF  = new byte[] { 0x4e, 0x65, 0x65, 0x74, 0x73, 0x2c, 0x4b, 0x2c, 0x02, 0x00 };

    private static string TARGET_HOST   = &quot;10.11.110.11&quot;;
    private static int    TARGET_PORT   = 5009;

    static void Main( string[] args ) {

      TcpClient sender = new TcpClient( TARGET_HOST, TARGET_PORT );
      NetworkStream stream = sender.GetStream();
      if( args[ 0 ] == &quot;on&quot; ) {
        Console.WriteLine( &quot;Switching on&quot; );
        stream.Write( WORKLOAD_ON, 0, WORKLOAD_ON.Length );

      } else if( args[ 0 ] == &quot;off&quot; ) {
        Console.WriteLine( &quot;Switching off&quot; );
        stream.Write( WORKLOAD_OFF, 0, WORKLOAD_OFF.Length );

      } else {
        Console.WriteLine( &quot;Missing parameter (on/off).&quot; );
      }

      stream.Close();
      sender.Close();

    }
  }
}
</pre>
<p>So, yeah, I can now just refer back to my introduction. Possibly this wasn&#8217;t event worth mentioning ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/12/03/simulating-tcp-data-from-another-device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Run .bat file with a set of parameters</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/11/28/run-bat-file-with-a-set-of-parameters/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/11/28/run-bat-file-with-a-set-of-parameters/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 00:39:18 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[.bat]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[console]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=287</guid>
		<description><![CDATA[I am currently working on a project of larger scale than what I am usually working on. During this project I wrote several small tools which I personally feel are somewhat interesting. I&#8217;ll try to write up a few posts about some solutions I came up with to kinda special problems. This is the first [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently working on a project of larger scale than what I am usually working on. During this project I wrote several small tools which I personally feel are somewhat interesting.<br />
I&#8217;ll try to write up a few posts about some solutions I came up with to kinda special problems.<br />
This is the first one and I already feel the topic is not capturing the essence of what this tool does.</p>
<p>In this project we have a Windows domain of about 100 machines which are running our software are mainly used to display &#8220;stuff&#8221; (let&#8217;s not go into details).<br />
When I arrived on site where we deployed our product I found that some technicians where using .bat files to deploy files to machines in the domain. After deploying their files they would restart the machine remotely through Windows remote desktop feature. They would repeat that process for every machine in the domain manually until the desired group was up-to-date.<br />
Needless to say, for a programmer, this seemed unnecessarily cumbersome. This was when I wrote the first helpful tool.</p>
<p>The tool will read a .xml file which contains target IP addresses (or machine names if DNS is available) and will use them as a parameter to a supplied batch file. Alternatively it would use a list of targets supplied via the command line. Thus enabling you to run a .bat file for a large set of targets.<br />
Let&#8217;s have a look at the source:</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace BatchProcessor {
  class Program {

    private const   String      APPLICATION_NAME    = &quot;Batch Processor&quot;;
    private const   String      APPLICATION_VERSION = &quot;0.1&quot;;

    private static ConsoleColor defaultColor        = ConsoleColor.Gray;

    static void Main( string[] args ) {

      Console.WindowWidth = 160;
      Console.Title = String.Format( &quot;{0} {1}&quot;, APPLICATION_NAME, APPLICATION_VERSION );

      Console.ForegroundColor = ConsoleColor.Cyan;
      Console.WriteLine( String.Format( &quot;{0} {1}&quot;, APPLICATION_NAME, APPLICATION_VERSION ) );
      Console.ForegroundColor = ConsoleColor.DarkCyan;
      Console.WriteLine( &quot;CPP Studios Event GmbH 2009&quot; );
      Console.ForegroundColor = defaultColor;

      string        batchFile   = String.Empty;
      string        targetsFile = String.Empty;
      List&lt;string&gt;  targets     = new List&lt;string&gt;();

      if( args.Length &lt; 2 ) {
        errorExit( &quot;Incorrect number of arguments&quot; );
        return;
      }

      batchFile   = args[ 0 ];
      targetsFile = args[ 1 ];

      // Check if targetsFile is actually a file
      FileInfo targetsFileInfo = new FileInfo( targetsFile );
      if( !targetsFileInfo.Exists ) {
        for( int targetIndex = 1; targetIndex &lt; args.Length; ++targetIndex ) {
          targets.Add( args[ targetIndex ] );
        }

      } else {
        XmlDocument targetFile = new XmlDocument();
        try {
          Console.WriteLine( String.Format( &quot;Reading targets from {0}...&quot;, targetsFile ) );
          targetFile.Load( targetsFile );

          XmlNodeList targetNodes = targetFile.SelectNodes( &quot;/targets/target&quot; );
          foreach( XmlNode targetNode in targetNodes ) {
            targets.Add( targetNode.Attributes[ &quot;ip&quot; ].InnerText );
          }

        } catch( Exception ex ) {
          Console.ForegroundColor = ConsoleColor.Red;
          Console.WriteLine( &quot;Error while reading targets: &quot; + ex.Message );
          Console.ForegroundColor = defaultColor;
        }
      }
      Console.WriteLine( String.Format( &quot;Got {0} targets&quot;, targets.Count ) );

      foreach( String target in targets ) {
        string commandLine = String.Format( &quot;{0} {1}&quot;, batchFile, target );
        Console.ForegroundColor = ConsoleColor.DarkGreen;
        Console.WriteLine( String.Format( &quot;Executing '{0}'...&quot;, commandLine ) );
        Console.ForegroundColor = defaultColor;

        ProcessStartInfo  p     = new ProcessStartInfo( batchFile );
        Process           proc  = new Process();

        p.Arguments               = target;
        p.RedirectStandardOutput  = true;
        p.UseShellExecute         = false;
        proc.StartInfo            = p;

        proc.Start();
        StreamReader outputReader = proc.StandardOutput;

        proc.WaitForExit();
        Console.Write( outputReader.ReadToEnd() );

        Console.ForegroundColor = ConsoleColor.DarkGreen;
        Console.WriteLine( String.Format( &quot;Finished processing '{0}'.&quot;, commandLine ) );
        Console.ForegroundColor = defaultColor;
      }

      Console.ForegroundColor = ConsoleColor.Magenta;
      Console.WriteLine( &quot;Operation completed.&quot; );
      Console.ForegroundColor = defaultColor;

    }

    private static void errorExit( String errorMessage ) {
      Console.ForegroundColor = ConsoleColor.Red;
      Console.WriteLine( errorMessage );
      Console.ForegroundColor = defaultColor;
      Thread.Sleep( 5000 );
    }

  }
}
</pre>
<p>Pretty much a straight forward implementation of what I explained above.<br />
What amazed me most about the tool was the simplicity and how much can be achieved by the approach. Everyone who is capable of writing a .bat file could plug it right into the system and apply the command set to our pre-defined groups. I like to think that it turned out to be a very simple, yet versatile tool.</p>
<p>Another thing to notice is the console redirection used here. It&#8217;s pretty much what you will find if you google for &#8220;c# redirect console output&#8221; in a few seconds. Soon I noticed that it&#8217;s a very shitty way to redirect console output and leaves a lot to wish for. I will cover that topic in more detail in an upcoming post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/11/28/run-bat-file-with-a-set-of-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building PHP 5.3.0 on Ubuntu 8.04 Server</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/08/06/building-php-5-3-0-on-ubuntu-8-04-server/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/08/06/building-php-5-3-0-on-ubuntu-8-04-server/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 21:07:37 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[administration]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=274</guid>
		<description><![CDATA[When I wanted to build the latest PHP for a server I found several guides online. Sadly none of them worked right away. So after finally getting it all to work like I wanted to, I decided to quickly write up this guide. I start with a clean Ubuntu 8.04 install. So, first things first: [...]]]></description>
			<content:encoded><![CDATA[<p>When I wanted to build the latest PHP for a server I found several guides online. Sadly none of them worked right away.<br />
So after finally getting it all to work like I wanted to, I decided to quickly write up this guide.</p>
<p>I start with a clean Ubuntu 8.04 install. So, first things first:</p>
<pre class="brush: plain;">
sudo apt-get update
sudo apt-get dist-upgrade
sudo shutdown -r now
</pre>
<p>Now that we&#8217;re up-to-date, let&#8217;s begin:</p>
<pre class="brush: plain;">
sudo apt-get build-dep php5
sudo apt-get install libmcrypt-dev libc-client-dev checkinstall
</pre>
<p>Now we have all the crap to build PHP with. Let&#8217;s get PHP itself:</p>
<pre class="brush: plain;">
cd /tmp/
wget http://us3.php.net/get/php-5.3.0.tar.gz/from/this/mirror
tar xvzf php-5.3.0.tar.gz
cd php-5.3.0/
</pre>
<p>Now all that is left is to build PHP&#8230;</p>
<pre class="brush: plain;">
./configure --prefix=/usr --with-apxs2=/usr/bin/apxs2 --with-config-file-path=/etc/php5/apache2 --with-config-file-scan-dir=/etc/php5/apache2/conf.d --mandir=/usr/share/man --disable-debug --with-regex=php --disable-rpath --disable-static --with-pic --with-layout=GNU --with-pear=/usr/share/php --enable-calendar --enable-sysvsem --enable-sysvshm --enable-sysvmsg --enable-bcmath --with-bz2 --enable-ctype --with-db4 --without-gdbm --with-iconv --enable-exif --enable-ftp --with-gettext --enable-mbstring --with-pcre-regex=/usr --enable-shmop --enable-sockets --enable-wddx --with-libxml-dir=/usr --with-zlib --with-kerberos=/usr --with-openssl=/usr --enable-soap --enable-zip --with-exec-dir=/usr/lib/php5/libexec --without-mm --with-curl=shared,/usr --with-zlib-dir=/usr --with-gd=shared,/usr --enable-gd-native-ttf --with-gmp=shared,/usr --with-jpeg-dir=shared,/usr --with-xpm-dir=shared,/usr/X11R6 --with-png-dir=shared,/usr --with-freetype-dir=shared,/usr --with-t1lib=shared,/usr --with-ldap=shared,/usr --with-ldap-sasl=/usr --with-mhash=shared,/usr --with-mysql=shared,/usr --with-mysqli=/usr/bin/mysql_config --with-pspell=shared,/usr --with-unixODBC=shared,/usr --with-xsl=shared,/usr --with-snmp=shared,/usr --with-sqlite=shared,/usr --with-mssql=shared,/usr --with-tidy=shared,/usr --with-xmlrpc=shared --with-pgsql=shared,/usr --enable-gd-native-ttf --enable-dba=shared --with-openssl-dir=shared,/usr --enable-gd-jis-conv --enable-json --with-mcrypt=shared,/usr --enable-pcntl --with-pdo-mysql --with-pdo-odbc=unixODBC,/usr --with-pdo-pgsql=shared,/usr --with-pdo-sqlite --enable-xmlreader --with-tsrm-pthreads --with-imap --with-imap-ssl
</pre>
<p>I&#8217;m sure this doesn&#8217;t enable ALL features in PHP, but it works for me so far. If I&#8217;ll ever find I was missing something, I&#8217;ll be sure to update this post.</p>
<p>When building make sure to pass the correct number of CPUs to make with the -j parameter to safe some time.</p>
<pre class="brush: plain;">
make -j2
</pre>
<p>And now we wait&#8230;</p>
<p>Now we need to add these lines to our httpd.conf (which is empty in this case)</p>
<pre class="brush: plain;">
#LoadModule directive to aid module installations
#LoadModule dummy_module /usr/lib/apache2/modules/mod_dummy.so
</pre>
<p>Now we can build our .deb for PHP.</p>
<pre class="brush: plain;">
sudo checkinstall -D --install=no --fstrans=no --maintainer=your@email --reset-uids=yes --nodoc --pkgname=php5 --pkgversion=5.3 --pkgrelease=200908060830 --arch=amd64
</pre>
<p>And that&#8217;s it. Now you have a .deb which you can install on a different system or (as checkinstall told you) just put on this system with dpkg -i.</p>
<p>Have fun</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/08/06/building-php-5-3-0-on-ubuntu-8-04-server/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>gSteam &#8211; HLDS Frontend</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/06/09/gsteam-hlds-frontend/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/06/09/gsteam-hlds-frontend/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 21:24:49 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[administration]]></category>
		<category><![CDATA[hlds]]></category>
		<category><![CDATA[steam]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=271</guid>
		<description><![CDATA[This is a little introduction to the latest version of my steam and hlds frontend bash script. I will demonstrate it&#8217;s use by setting up a new Team Fortress 2 game server with it. This tutorial assumes an Ubuntu 8.04.2 x86 server system. I set up a VM for the sake of this tutorial. It [...]]]></description>
			<content:encoded><![CDATA[<p>This is a little introduction to the latest version of my steam and hlds frontend bash script.<br />
I will demonstrate it&#8217;s use by setting up a new Team Fortress 2 game server with it.<br />
This tutorial assumes an Ubuntu 8.04.2 x86 server system. I set up a VM for the sake of this tutorial.<br />
It has 2 CPUs, 512MB RAM and an 8GB harddrive. So if you want to do a dry run in a VM at first<br />
as well, this will do fine.<br />
Setting up the server OS is beyond the scope of this tutorial. I just assume you have a default<br />
install with an OpenSSH server and that you have fully updated your system after install.<br />
So, let&#8217;s get going.</p>
<p>The first thing we&#8217;ll need is the screen package.</p>
<pre class="brush: plain;">
sudo apt-get install screen
</pre>
<p>Now let&#8217;s create a user for steam and switch to it.</p>
<pre class="brush: plain;">
sudo adduser --disabled-login steam
sudo su - steam
</pre>
<p>Let&#8217;s download gSteam, my frontend, and set it executable for only steam.</p>
<pre class="brush: plain;">
wget http://www.dirty-motherfucker.org/steam/gSteam.sh
chmod 700 gSteam.sh
</pre>
<p>Now we can install the steam client.</p>
<pre class="brush: plain;">
./gSteam.sh install steam
</pre>
<p>As noted in my post regarding the L4D server, if the installation does not seem to properly start or<br />
hang, you can try to create a Steam.cfg file (in the homedir) with preferred content server ids.</p>
<p>http://www.dirty-motherfucker.org/blog/2008/12/26/running-a-source-dedicated-server-for-left-4-dead/</p>
<p>After you get the magic line &#8220;Steam Linux Client updated, please retry the command&#8221; you are ready to<br />
install some games. So let&#8217;s install Team Fortress 2.</p>
<pre class="brush: plain;">
./gSteam.sh install tf
</pre>
<p>The identifiers for the games can be obtained with:</p>
<pre class="brush: plain;">
./steam -command list
</pre>
<p>The &#8220;No installation record found at&#8230;&#8221; messages can be safely ignored.<br />
Now you will have to wait until the game is fully downloaded. This can take from &#8220;forever&#8221; to<br />
&#8220;until the fucking end of time&#8221; in some cases. The old Steam.cfg can help here as well, but<br />
I personally found that patience is the best tool.</p>
<p>Once the installation is completed a profile template for tf will be created. gSteam will try its<br />
best to determine some default parameters. You should edit it nevertheless to at least adjust<br />
the name of your server (and possibly the profile).</p>
<p>If everything worked fine you can now simply</p>
<pre class="brush: plain;">
./gSteam start tf2
</pre>
<p>and the thing should be running.</p>
<p>Installing other games is as simple as:</p>
<pre class="brush: plain;">
./gSteam install l4d_full
</pre>
<p>Let me just add that the script is far from fail-proof. Especially error-cases aren&#8217;t properly handled. But it saved me a lot of time so I thought I&#8217;d share it.<br />
Hope it helps someone else ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/06/09/gsteam-hlds-frontend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build count of VC++ project for version string</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/04/24/build-count-of-vc-project-for-version-string/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/04/24/build-count-of-vc-project-for-version-string/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 12:18:11 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=267</guid>
		<description><![CDATA[For ages now I wanted to write me something nice and neat to get build count (how often the project was built) to append it to my version string. And obviously I wanted it to automatically update. However I never really got around to it or cared that much that I actually wrote it. But [...]]]></description>
			<content:encoded><![CDATA[<p>For ages now I wanted to write me something nice and neat to get build count (how often the project was built) to append it to my version string. And obviously I wanted it to automatically update.<br />
However I never really got around to it or cared that much that I actually wrote it. But today is the day!<br />
And here is how it works:</p>
<pre class="brush: plain;">
@echo off
SETLOCAL
set TARGET_PATH=%~dp0
set FILENAME=&quot;%TARGET_PATH%build.h&quot;
set /p BUILD= &lt; %FILENAME%
set BUILD=%BUILD:~22%
if /I &quot;%BUILD%&quot; == &quot;&quot; set BUILD=0
set /a BUILD=%BUILD%+1
echo #define VERSION_BUILD %BUILD% &gt; %FILENAME%
echo #define VERSION_DATE L&quot;%DATE%&quot; &gt;&gt; %FILENAME%
echo #define VERSION_TIME L&quot;%TIME%&quot; &gt;&gt; %FILENAME%
ENDLOCAL
</pre>
<p>In case it&#8217;s not obvious what this batch file does. First we construct our target filename so that it is still valid even if VS calls the batch from another directory. Then we read in the first line of our build.h (the VERSION_BUILD #define), then we cut off the part before the build number, add 1 and write it back. I also add 2 #defines for date and time, cause, why not? I made date and time already wide strings but left the build count an integer. This makes it slightly easier to parse for the batch file ;)</p>
<p>So just throw the two files in a folder in your project and run the batch once so the build.h is created. Then open up your project properties and add the batch as a new Pre-Build Event. It makes most sense just to do it for Release builds. Now whenever you wanna reference the build count, just #include the build.h. Done.</p>
<p>I guess it would be desirable to solve this whole thing without macros. But at this time I lack the energy to make it more complex. Maybe in a few years&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/04/24/build-count-of-vc-project-for-version-string/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Complementary mIRC script for ZNC users</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/03/11/complementary-mirc-script-for-znc-users/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/03/11/complementary-mirc-script-for-znc-users/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 20:54:51 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[irc]]></category>
		<category><![CDATA[mirc]]></category>
		<category><![CDATA[znc]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=262</guid>
		<description><![CDATA[Download: ZNC mIRC Script A while ago I have ditched PsyBNC in favor of ZNC. And let me tell you, I am not missing that POS that is PsyBNC. So, so much for the software bashing. Back to topic. When using an IRC bouncer I prefer to have the recorded buffer played back to me [...]]]></description>
			<content:encoded><![CDATA[<p>Download: <a href="http://en.znc.in/wiki/Timestamps#mIRC">ZNC mIRC Script</a></p>
<p>A while ago I have ditched PsyBNC in favor of <a href="http://en.znc.in/wiki/ZNC">ZNC</a>. And let me tell you, I am not missing that POS that is PsyBNC. So, so much for the software bashing. Back to topic.</p>
<p>When using an IRC bouncer I prefer to have the recorded buffer played back to me when I re-connect. ZNC has several options for that. First of all there are the text buffers it will play back to you. Which is pretty standard. ZNC will play back the message as if the user said it and can either append or prepend the time when it happened. Sadly this does not look like the usual user text and is one of the problems this script targets.<br />
Then there is the <a href="http://en.znc.in/wiki/Buffextras">buffextras</a> module which will additionally play back generic IRC events as text. These will appear as if a user (*buffextras) sends text to the channel like with the generic buffer playback. The same problems as above here apply.<br />
You can go a little further though. You have the <a href="http://en.znc.in/wiki/Savebuff">savebuff</a> module which will play back IRC events in a certain format that can be parsed by a client-side script. This is the second problem this script targets.</p>
<p>The script will take all the buffer playback output from ZNC and format it as if it actually happened in the live session. You can grab the script from the <a href="http://en.znc.in/wiki/Timestamps#mIRC">ZNC wiki</a>.</p>
<p>So, what to take from this post? If you&#8217;re a PsyBNC user, switch to ZNC right now! If you&#8217;re a mIRC user and already use ZNC, great, grab the script. If you don&#8217;t use mIRC or don&#8217;t use IRC at all, well, I have just wasted your time :D</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/03/11/complementary-mirc-script-for-znc-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Output to the parent console in Windows application</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/03/10/output-the-parent-console-in-windows-application/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/03/10/output-the-parent-console-in-windows-application/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 00:27:42 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=248</guid>
		<description><![CDATA[So I looked into boost.program_options today to parse command line arguments for my Windows Forms application. Which basically works great. Except for the little part to output the &#8211;help output to the console. Now, obviously when you start your application through Explorer you won&#8217;t have a console. And that is fine. I was only interested [...]]]></description>
			<content:encoded><![CDATA[<p>So I looked into boost.program_options today to parse command line arguments for my Windows Forms application. Which basically works great. Except for the little part to output the &#8211;help output to the console. Now, obviously when you start your application through Explorer you won&#8217;t have a console. And that is fine. I was only interested in the case when you start the application through a console window. Additionally it would also have to work with Unicode of course :P<br />
So after looking around the web for a while I finally managed to put it all together. So here it is:</p>
<pre class="brush: cpp;">
BOOL consoleAttached = AttachConsole( ATTACH_PARENT_PROCESS );

boost::program_options::options_description desc( &quot;Allowed options&quot; );
desc.add_options()
	( &quot;help&quot;, &quot;Show this message&quot; )
	( &quot;width&quot;, &quot;Backbuffer width&quot; )
	( &quot;height&quot;, &quot;Backbuffer height&quot; )
	;

wstring commandLine = GetCommandLine();
int     argc = 0;
LPWSTR* argv = 0;
argv = CommandLineToArgvW( commandLine.c_str(), &amp;argc );

boost::program_options::variables_map vm;
boost::program_options::store( boost::program_options::parse_command_line( argc, argv, desc ), vm );
boost::program_options::notify( vm );

LocalFree( argv );

if( vm.count( &quot;help&quot; ) ) {
	if( consoleAttached ) {
		HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
		if( INVALID_HANDLE_VALUE == hStdOut ) {
			return 1;
		}
		DWORD dwCharsWritten;
		std::stringstream desc_strings;
		desc_strings &lt;&lt; desc;
		std::string desc_string = desc_strings.str();

		WriteConsoleA( hStdOut, desc_string.c_str(), desc_string.length(), &amp;dwCharsWritten, NULL );
		FreeConsole();
	}
	return 1;
}
</pre>
<p>Sadly after the application finishes the prompt doesn&#8217;t instantly return. Maybe I&#8217;ll look into that some day&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/03/10/output-the-parent-console-in-windows-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
