<?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>ITworks &#187; Linux</title>
	<atom:link href="http://itworks.hu/tag/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://itworks.hu</link>
	<description>Random musings in IT</description>
	<lastBuildDate>Mon, 09 Jan 2012 08:01:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>New trends in Linux desktop UIs</title>
		<link>http://itworks.hu/2009/11/24/new-trends-in-linux-desktop-uis/</link>
		<comments>http://itworks.hu/2009/11/24/new-trends-in-linux-desktop-uis/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 21:14:25 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=89</guid>
		<description><![CDATA[As I see there is a solid movement to reform the user interfaces that are in use in our computers. After all the menu bars with a start menu are on the mainstream desktops since the win95/OS2 era. And the &#8230; <a href="http://itworks.hu/2009/11/24/new-trends-in-linux-desktop-uis/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-medium wp-image-90" title="win95Menu-Word" src="http://itworks.hu/wp-content/uploads/2009/11/win95Menu-Word-300x231.jpg" alt="win95Menu-Word" width="300" height="231" />As I see there is a solid movement to reform the user interfaces that are in use in our computers. After all the menu bars with a start menu are on the mainstream desktops since the win95/OS2 era. And the programs can be started using icons on the desktop and the start menu. For the ones who know what they are looking for there is also a command line. And there is a task bar to switch your running applications. But things ought to change with time, shouldn&#8217;t they?</p>
<p><span id="more-89"></span>On Linux (Ubuntu) first there was a movement to make things fancier than on Windows. Compiz made a huge visual improvement but has not really changed anything. Having your desktop on a cube and spinning it around is particularly fancy, but not really useful.</p>
<p>Taking the ideas from MacOS X a couple of dock style window navigators popped up. Avant Window Navigator, Cairo Dock or Docky theme of the gnome-do (more about that later) These are really nice looking, but have no added value compared to standard application switcher that I see.</p>
<p><img class="size-medium wp-image-91 alignleft" title="gnome-shell" src="http://itworks.hu/wp-content/uploads/2009/11/gnome-shell-300x187.png" alt="gnome-shell" width="300" height="187" />The path gnome 3.0 is taking is quite different, it completely replaces the taskbar, with a live miniature based desktop switcher. It is activated with a hot-spot for mouse/thouchpad users, or a hotkey (Super) for those who don&#8217;t want to leave the keyboard.  You can switch to running apps with a single click, if unsure which window you want to see, you can use the wheel to zoom on the window before changing.</p>
<p>Personally I like it, and I&#8217;ve been using it on my laptop for weeks now. Why not on my desktop? Well, there is a catch. It requires working 3d acceleration to use. This rules out quite a few cards, all legacy nvidia and ati cards have issues. Basically it&#8217;s only Intel I&#8217;ve heard it works properly. Unfortunately there are no plans to support legacy cards. So for those hardware one will have to switch to icewm or kde based desktops.</p>
<p>There is more to desktop software than switching, after all you must start your applications before switching them. Are there improvements in that over the start menu?</p>
<p>First there is the intelligent start menu you find in Linux SuSe and Mint. It&#8217;s a lot like XP, where the most frequently applications are remembered and the menu provides you with that on opening. This is a change compared to the classic start menu, and is quite helpful. Unless of course you don&#8217;t quite where you find the application you are looking for in the menu. What can help there?</p>
<p>Both the upcoming gnome-shell and the gnome-do add-on provide an excellent, find as you type style interface, this greatly helps you finding the application you might want to start. It is quite basic in gnome-shell yet, and is only useful for finding applications and preferences with names and descriptions containing the characters typed. Gnome-do however is more advanced, it can be extended with plugins, that search in your IM&#8217;s contact list, recent documents, etc. This greatly speeds up application startup. I heard there are plans to integrate the gnome-do capabilities in gnome-do and I really welcome the idea.</p>
<p>On the whole I see the usability of the gnome-shell is the best enhancement in the past few years, and I really hope those wrinkles I meet every day will soon be eliminated.</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2009/11/24/new-trends-in-linux-desktop-uis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating for a bot for MafiaWars</title>
		<link>http://itworks.hu/2009/08/12/creating-for-a-bot-for-maffiawars/</link>
		<comments>http://itworks.hu/2009/08/12/creating-for-a-bot-for-maffiawars/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:54:07 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[macro]]></category>

		<guid isPermaLink="false">http://itworks.hu/2009/08/12/creating-for-a-bot-for-maffiawars-2/</guid>
		<description><![CDATA[I started playing MafiaWars on my last job, where I had time to spare. As it has happened in the past with me playing on a mud, when the game got repetitive I start writing tools to speed things up.When &#8230; <a href="http://itworks.hu/2009/08/12/creating-for-a-bot-for-maffiawars/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I started playing <a href="http://apps.facebook.com/inthemafia/" target="_blank">MafiaWars</a> on my last job, where I had time to spare. As it has happened in the past with me playing on a mud, when the game got repetitive I start writing tools to speed things up.When I was on the mud I used macro-enabled clients, like <a href="http://tintin.sourceforge.net/" target="_blank">tintin++</a> to perform simple tasks for me. Since   <a href="http://apps.facebook.com/inthemafia/" target="_blank">MafiaWars</a> is a Web 2.0 application, one must emulate a web client, so things are a bit trickier than what one can achieve using a simple wget or shell-script based bot.<br />
<span id="more-41"></span><span style="font-weight: bold;"> Preparations </span></p>
<p>Digging through the Internet I couldn&#8217;t find a decent bot-base that I could use for my experiment. The only traces of bots I found were simple brainless fight bots implemented as <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacros.</a></p>
<p><span style="font-weight: bold;">First steps</span></p>
<p>As it seemed like a good idea at the time, I started by installing <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro plugin</a>, then saving a macro. My first goal was to allow for the bot to fight until it has stamina, then wait until some is regenerated.  I soon discovered that while there is a <code>LOOP</code> command, there is no conditional execution support in the <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro</a> language. Recognizing that not even a simple AI can be exclusively written in <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro</a>&#8216;s own language, I switched over to JavaScript based Macros.</p>
<p>The basic idea of the bot is to extract some data off the rendered screen, then perform some action, then start from the begining.</p>
<p><strong>Bot loop</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> terminated<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">// Check for termination here</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>terminated<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Do your logic here</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// I use throw(0) for forced termination when debugging, and I don't want alerts then</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Logging</strong></p>
<p>To make the bot&#8217;s work auditable, and to provide some help for debugging, I created a few simple logging functions.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> consoleWindow<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/**
 * Opens a console window
 *
 * @return the console window handle
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> openConsole<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #003366; font-weight: bold;">var</span> ww <span style="color: #339933;">=</span> Components.<span style="color: #660066;">classes</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;@mozilla.org/embedcomp/window-watcher;1&quot;</span><span style="color: #009900;">&#93;</span>
 .<span style="color: #660066;">getService</span><span style="color: #009900;">&#40;</span>Components.<span style="color: #660066;">interfaces</span>.<span style="color: #660066;">nsIWindowWatcher</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow <span style="color: #339933;">=</span> ww.<span style="color: #660066;">openWindow</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;DescriptiveWindowName&quot;</span><span style="color: #339933;">,</span>
 <span style="color: #3366CC;">&quot;width=600,height=300&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #660066;">title</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'MaffiaWars Console'</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;html&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;head&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;title&amp;gt;MaffiaWars Console&amp;lt;/title&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;/head&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;body&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;div id=&quot;status&quot; style=&quot;font-size:10px;width:100%;background-color:red&quot;&amp;gt;Starting up&amp;lt;/div&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;div id=&quot;log&quot; style=&quot;font-size:10px&quot;&amp;gt;&amp;lt;/div&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;/body&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 setConsoleStatus<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> setConsoleStatus<span style="color: #009900;">&#40;</span>content<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>consoleWindow<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 consoleWindow <span style="color: #339933;">=</span> openConsole<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 statusE <span style="color: #339933;">=</span> consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'status'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 statusE.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">nodeValue</span><span style="color: #339933;">=</span>content<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/**
 * Writes to the console window, if it exists, opens it if it doesn't
 *
 * @param content
 * @return
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> writeConsole<span style="color: #009900;">&#40;</span>content<span style="color: #339933;">,</span>color<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>consoleWindow<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 consoleWindow <span style="color: #339933;">=</span> openConsole<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 logE <span style="color: #339933;">=</span> consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'log'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #003366; font-weight: bold;">var</span> p <span style="color: #339933;">=</span> consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;p&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>color<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
 <span style="color: #003366; font-weight: bold;">var</span> styleA <span style="color: #339933;">=</span> document.<span style="color: #660066;">createAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'style'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 styleA.<span style="color: #660066;">nodeValue</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'background-color:'</span><span style="color: #339933;">+</span>color<span style="color: #339933;">;</span>
 p.<span style="color: #660066;">setAttributeNode</span><span style="color: #009900;">&#40;</span>styleA<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 p.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>consoleWindow.<span style="color: #660066;">document</span>.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span>d.<span style="color: #660066;">toDateString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; &quot;</span> <span style="color: #339933;">+</span> d.<span style="color: #660066;">toLocaleTimeString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;: &quot;</span>
 <span style="color: #339933;">+</span> content<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 logE.<span style="color: #660066;">insertBefore</span><span style="color: #009900;">&#40;</span>p<span style="color: #339933;">,</span>logE.<span style="color: #660066;">firstChild</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> isConsoleOpen <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
 <span style="color: #000066; font-weight: bold;">return</span> consoleWindow<span style="color: #339933;">!=</span><span style="color: #003366; font-weight: bold;">null</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #339933;">!</span>consoleWindow.<span style="color: #660066;">closed</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #006600; font-style: italic;">/**
 * Closes the console window
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> closeConsole<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isConsoleOpen<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 consoleWindow.<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 consoleWindow<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This implements a simple log window, where you can add new entries with the chosen background color. Since the code is for my own fun, several documentation comments are missing. The window contains two areas, the status area is used to display longer units of work, while the log area displays the logs in reverse order (newest first).</p>
<p>Using the log is pretty straightforward. To set the status you use setConsoleStatus(message) and to add  a new log entry you use the function writeConsole(content,color).The log window is not reused, and the log is not written to file, because I don&#8217;t need it.</p>
<p><strong>Business logic</strong></p>
<p>The business logic of the bot is very simple. It is based on how I actually play the game. The features are implemented in separate functions.</p>
<p>There are some global variables in the script, to store data for workflow based operations. For example the fully mastered job tiers are stored in such a global array.</p>
<p><strong>Completed features</strong></p>
<ul>
<li>Search for and fight opponents with mafias of the same size or smaller, when stamina is available<br />
The function searches the fight screen for the mafia of the smallest size, that is smaller than ours. If found it&#8217;s attacked, if there is no target, the function changes the city and checks the other location for targets.</li>
<li>Going to hospital in NY (I have more money there) when the health is critical</li>
<li>Keeping track of fight results<br />
This feature is not useful for determining opponents yet, as there is no way of identifying the opponents on the Fight screen.</li>
<li>Selling goods in Cuba, then depositing to bank<br />
Selling goods was easier, when all items started with &#8220;Sell&#8230;.&#8221; now there are the corrupt politicians, that are either collected or bought right in the middle. I didn&#8217;t see it introduced, so I thought there was something wrong with the logic&#8230;</li>
<li>Depositing to bank in NY</li>
<li>Doing jobs</li>
<li>Tiers are scanned sequentially to see if there is a job that is available. If the tier is fully mastered, it is stored and is avoided in later searches. The jobs, that are not mastered are checked against the specified requirements (sufficient energy and consumables are available) If there are more jobs that satisfy the requirements the one with most required energy is executed.</li>
<li>Using up energy-packs wisely to get level boosts.<br />
The function considers the amount of energy available, the amount of experience required for the next level, the 25% extra energy from the pack, and a rule-of-thumb multiplyer, to calculate the amount of XP per energy point.</li>
</ul>
<p><span style="font-weight: bold;">Planned features</span></p>
<ul>
<li>Repair and protect buildings in NY, before going to bank</li>
<li>Playing free lotto tickets</li>
<li>Using profile points to boost attack/defense</li>
<li>Identifying job pre-requisites in NY and mark those jobs available despite them  mastered</li>
</ul>
<p><span style="font-weight: bold;">Lessons learned</span></p>
<p><em><span style="font-weight: bold;">JavaScript issues<br />
</span></em></p>
<p>JavaScript has never been the language of my choice. My code probably features really poor practices, there were several things that drove me nuts though.</p>
<p>One of my biggest disappointment in JavaScript, is that it doesn&#8217;t support suspending execution in any way. One can&#8217;t write a simple <code>while(true){}</code> loop, and use a <code>sleep()</code> or <code>yield()</code> function to allow his computer do other things then running the bot. To overcome this issue on Linux I used the <a href="http://cpulimit.sourceforge.net/" target="_blank">cpulimit</a> utility, and ran the browser in a different process than my normal process. In fact I used firefox 3.0, then later firefox 3.6 to run the bot, while using firefox 3.5 as my normal browser. If I was to start again I would be using <a href="http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/" target="_blank">setInterval()</a> and create some kind of heartbeat based finite state machine.</p>
<p>JavaScript doesn&#8217;t allow for code inclusion, which was a surprise for me. I thought I could organize the code properly, into logging, utility and business logic modules. This comes from the browser based nature of JavaScript. Unfortunately modifying the parent document to include the other files is impossible, once you run your script from a plug-in. Maybe it can be worked around, but there is really no need for that on such a pet project.</p>
<p>The other JavaScript issue I had, is that the authors of <a href="http://apps.facebook.com/inthemafia/" target="_blank">MafiaWars</a> used window level variables to store some data, and use that data to dynamically create URL&#8217;s. Thus in order to access the data, that is to be stored in the link I would have to be able to access this data. Unfortunately, I just can&#8217;t. I&#8217;ve tried everything, and even though the variables are visible using <a href="http://getfirebug.com/" target="_blank">FireBug</a> they are inaccessible through the <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro plugin</a>.</p>
<p><em><strong>IMacro issues</strong></em></p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro</a> has issues with stopping running JavaScript macros. Once you close the iMacros tab it says it will terminate the running JavaScript macro, but in fact it&#8217;s only suspended. I had to implement in all the loops I used logic, to terminate the loop on certain conditions, like navigating the window away from FaceBook or closing the log window.</p>
<p>There is a strange feature of the <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro</a>, it seems that stopping the script either normally or through an exception takes almost 2 minutes for the browser to recover. I couldn&#8217;t yet find a reason for this, but it certainly causes problems.</p>
<p>While <a href="https://addons.mozilla.org/en-US/firefox/addon/3863" target="_blank">IMacro plugin</a> is certainly great for simple tasks, invoking it frequently from JavaScript kills it&#8217;s performance. After a while it got so bad, that my stamina was recharging faster, then it was spent! To overcome this issue I reimplemented the simple data extraction functions in JavaScript.</p>
<p>These changes have sped the execution up, and reduced the number of times the browser had to be forcefully restarted.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
 * Extracts the element matching the specified parameters
 *
 * @param tagName
 *            type of tag to look for
 * @param pos
 *            occurrence of the tag matching the search attributes
 * @param attributeTxt
 *            attributes to look for. The attributes are : separated key=value
 *            pairs, where the value is either a quoted string or a regular
 *            expression
 * @return the element matching the search attributes, or null if it's not found
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> extractElement<span style="color: #009900;">&#40;</span>tagName<span style="color: #339933;">,</span> pos<span style="color: #339933;">,</span> attributeTxt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> attributeA <span style="color: #339933;">=</span> attributeTxt.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> attributes <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>attributeA.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> attributeA<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'='</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>s.<span style="color: #660066;">length</span><span style="color: #339933;">!=</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Error extracting attributes from string '</span> <span style="color: #339933;">+</span> attributeTxt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		attributes<span style="color: #009900;">&#91;</span>s<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>s<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	elements <span style="color: #339933;">=</span> content.<span style="color: #660066;">document</span>.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span>tagName<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> curPos <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
	outer_loop<span style="color: #339933;">:</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> elementIx<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> elementIx<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> elementIx<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> curE <span style="color: #339933;">=</span> elements<span style="color: #009900;">&#91;</span>elementIx<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> attrIx <span style="color: #000066; font-weight: bold;">in</span> attributes<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'!curE.'</span><span style="color: #339933;">+</span>attrIx<span style="color: #339933;">+</span><span style="color: #3366CC;">' ||
				!(curE.'</span><span style="color: #339933;">+</span>attrIx<span style="color: #339933;">+</span><span style="color: #3366CC;">'.match('</span><span style="color: #339933;">+</span>attributes<span style="color: #009900;">&#91;</span>attrIx<span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'))'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">continue</span> outer_loop<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		curPos<span style="color: #339933;">++;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>curPos<span style="color: #339933;">==</span>pos<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">return</span> curE<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/**
 * Extracts the text content from the specified element
 *
 * @param tagName
 * @param pos
 * @param attributeTxt
 * @return text content of the element
 * @see extractElement(tagName, pos, attributeTxt)
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> extractText<span style="color: #009900;">&#40;</span>tagName<span style="color: #339933;">,</span> pos<span style="color: #339933;">,</span> attributeTxt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> curE <span style="color: #339933;">=</span> extractElement<span style="color: #009900;">&#40;</span>tagName<span style="color: #339933;">,</span> pos<span style="color: #339933;">,</span> attributeTxt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>curE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Cannot find '</span><span style="color: #339933;">+</span>tagName<span style="color: #339933;">+</span> <span style="color: #3366CC;">' on position '</span> <span style="color: #339933;">+</span> pos
			<span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>attributeTxt<span style="color: #339933;">?</span><span style="color: #3366CC;">' matching '</span><span style="color: #339933;">+</span>attributeTxt<span style="color: #339933;">:</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">return</span> curE.<span style="color: #660066;">textContent</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/**
 * Extracts the html content from the specified element
 *
 * @param tagName
 * @param pos
 * @param attributeTxt
 * @return html content of the element
 * @see extractElement(tagName, pos, attributeTxt)
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> extractHTML<span style="color: #009900;">&#40;</span>tagName<span style="color: #339933;">,</span> pos<span style="color: #339933;">,</span> attributeTxt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> curE <span style="color: #339933;">=</span> extractElement<span style="color: #009900;">&#40;</span>tagName<span style="color: #339933;">,</span> pos<span style="color: #339933;">,</span> attributeTxt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>curE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Cannot find '</span><span style="color: #339933;">+</span>tagName<span style="color: #339933;">+</span> <span style="color: #3366CC;">' on position '</span> <span style="color: #339933;">+</span> pos
			<span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>attributeTxt<span style="color: #339933;">?</span><span style="color: #3366CC;">' matching '</span><span style="color: #339933;">+</span>attributeTxt<span style="color: #339933;">:</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">return</span> curE.<span style="color: #660066;">innerHTML</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>The complete code</strong></p>
<p>Did I ever say I was to share it?</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2009/08/12/creating-for-a-bot-for-maffiawars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting VirtualBox on boot</title>
		<link>http://itworks.hu/2009/08/06/starting-virtualbox-on-boot/</link>
		<comments>http://itworks.hu/2009/08/06/starting-virtualbox-on-boot/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 14:13:50 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<category><![CDATA[virtualization]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=36</guid>
		<description><![CDATA[After setting up VirtalBox based virtualization on our server, I needed a way to have it automatically started and stopped whenever the host is restarted. Also it would be for the better if the system was not simply started and &#8230; <a href="http://itworks.hu/2009/08/06/starting-virtualbox-on-boot/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After setting up VirtalBox based virtualization on our server, I needed a way to have it automatically started and stopped whenever the host is restarted.</p>
<p>Also it would be for the better if the system was not simply started and stopped, but rather saved and restored when possible. I love scripting, but prefer the easy way, and since it&#8217;s a problem many have probably already tackled I sniffed around for a while.</p>
<p>There it was, new and shiny <a href="http://vboxtool.sourceforge.net/">tool</a> to make my day!</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2009/08/06/starting-virtualbox-on-boot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting DB2 instances on boot</title>
		<link>http://itworks.hu/2009/08/06/starting-db2-instances-on-boot/</link>
		<comments>http://itworks.hu/2009/08/06/starting-db2-instances-on-boot/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 08:32:27 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[DB2]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=34</guid>
		<description><![CDATA[After migrating our hosted application to a virtual server I realized, that as usual the system is a &#8220;maintenance free&#8221; Linux, meaning we set it up as it were and left it running for ages without touching it. On the &#8230; <a href="http://itworks.hu/2009/08/06/starting-db2-instances-on-boot/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After migrating our hosted application to a virtual server I realized, that as usual the system is a &#8220;maintenance free&#8221; Linux, meaning we set it up as it were and left it running for ages without touching it. On the occasion of power failure the applications were started manually.</p>
<p>As I don&#8217;t want to restart everything by hand, whenever our system is restarted I decided to iron these glitches out. OK, the system is only restarted about twice a year, but I tend to forget to restart things manually, so that&#8217;s the real reason.</p>
<p><span id="more-34"></span>The hosted application runs on a WebSphere Application Server Community Edtition 2.0 (meaning an IBM branded Apache Geronimo 2.0) which had an init script hacked together from an init script originally for Apache Tomcat. Talking about code reuse is one thing, doing it is another. It had a few quirks, like the JAVA_HOME setup, that were easily ironed.</p>
<p>The application stores it&#8217;s data in an IBM DB2 Universal Database 9.5, which performs beautifully by the way. It&#8217;s running on Debian, and was installed using the factory installer, which created the startup scripts as well. However the DB2 instances are not automatically started, and that&#8217;s a problem.</p>
<p>I was going to write a startup script which starts the db using the instance user, but it turned out it&#8217;s easier than that. DB2 instances can be auto started, only they are not created that way. Changing the flag is easy, as documented <a href="http://publib.boulder.ibm.com/infocenter/db2luw/v9//topic/com.ibm.db2.udb.admin.doc/doc/t0004919.htm?resultof=%22%64%62%32%69%61%75%74%6f%22%20">here</a>, you just have to issue the db2auto command for the instance.</p>
<p>The only thing left is to add some script to auto start the VirtualBox instance, and preferably stop it as well on shutdown.</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2009/08/06/starting-db2-instances-on-boot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating from physical to virtual server with pain and tears</title>
		<link>http://itworks.hu/2009/08/05/migrating-from-physical-to-virtual-server-with-pain-and-tears/</link>
		<comments>http://itworks.hu/2009/08/05/migrating-from-physical-to-virtual-server-with-pain-and-tears/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 13:45:39 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[annoyance]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[virtualization]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=28</guid>
		<description><![CDATA[We host the server for a legacy application in our office. Since it&#8217;s more like a favor than a real assignment we don&#8217;t care much about the server. However we had a few network issues lately, so we decided to &#8230; <a href="http://itworks.hu/2009/08/05/migrating-from-physical-to-virtual-server-with-pain-and-tears/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We host the server for a legacy application in our office. Since it&#8217;s more like a favor than a real assignment we don&#8217;t care much about the server. However we had a few network issues lately, so we decided to migrate it to a virtual server running on our hosted server. Also the machine produces lot&#8217;s of heat and noise, so we&#8217;d better had it switched off.</p>
<p>This seemed like such an easy task to do, what could be hard in creating a disk image with <a href="http://clonezilla.org/">CloneZilla</a>, copy it to a server, set up a virtual machine there with <a href="http://www.linux-kvm.org/">kvm</a>, restore the image and redirect all traffic to this computer instead of the one in our office. We estimated it could be done in two to three hours tops, and we get home around 7PM.</p>
<p><span id="more-28"></span>We missed a few points though. The machine had a faulty CD drive, so booting <a href="http://clonezilla.org/">CloneZilla</a> was not so easy. We went for the network boot option, but something just didn&#8217;t work out on the PXE boot. So we switched the CD drive to a working one, well at least it used to work a few years ago&#8230; But not anymore. So we decided to scrap the swap partition boot <a href="http://clonezilla.org/">CloneZilla</a> from there, and create our image. It worked! Almost. Except that <a href="http://clonezilla.org/">CloneZilla</a> didn&#8217;t quite identify the disk partition types, and didn&#8217;t see the RAID device at all. It turned out, that the utility somehow runs in user mode and starting the partimage utility with sudo is an acceptable workaround. We then had the disk image on a different server, where we tried to restore it into a 10GB virtual disk image. As it turns out, <a href="http://clonezilla.org/">CloneZilla</a> is unable to restore images that are bigger then the target partition even if there is less data in it.</p>
<p>So we went on a quest for a <a href="http://www.gnu.org/software/parted/">parted</a> that can shrink our 100GB partition to 10GB. Well, if there was one&#8230; As we had no intention of booting from the non-working CD we popped in a disk from our jukebox server with Ubuntu on it. No wonder it worked flawlessly, until I learned that a RAID 1 device with ext3 on it is not easy to shrink. So I decided to break the RAID block, remove the incompatible ext3 flags, and resize the first partition to 10GB. Then I used partimage to create the backup, it was created with about 300MB/min.</p>
<p>The backup was quickly copied over to the eagerly waiting server, that was to host the virtual machine. We fired up the VM with a 10GB disk image and <a href="http://clonezilla.org/">CloneZilla</a> iso mounted as a CD, and went out to restore the image to our partition. We didn&#8217;t even try to use the <a href="http://clonezilla.org/">CloneZilla</a> UI, except for mounting the host with sshfs to access our backup image. The setup was a breeze, except, that the restore speed was only about 50MB/min. No worries, it&#8217;s a small application after all, we don&#8217;t need a huge server for it anyway. It was also 1 AM already, so we didn&#8217;t pay much attention to detail anymore.</p>
<p>We redirected all the network traffic, to the new virtual interface and tested it while waiting for the restore to complete. During redirect, we fired a command, that killed the network adapter under us, so we were desperately trying to reach the hosting provider, to reboot our server. We went through all numbers listed on their homepage. Good thing they have a <a href="http://cam03.deninet.hu:8080/view/view.shtml">webcam</a> in their console room, so we could see the admin passing through on the way to our server, obviously not in a good mood! Suffice to say that was the most fun we had all evening!</p>
<p>After the restore was complete and some minor fixes (make the image bootable, install the grub loader, change the root device in the loader AND the fstab as well, change network configuration, to match the setup, AND the /etc/hosts AND /etc/resolv.conf, that are easily overlooked at 3 in the morning) we had the image booting up already. And oh boy, was it slow? Painfully so! The machine doesn&#8217;t support HW virtualization, and SW virtualization just doesn&#8217;t cut it.</p>
<p>So we grit our teeth and moved the whole bunch of stuff back to where it was, rebuilt the RAID array, and redirected everything where it was originally. Also we were not happy at all. We went home at 4 AM, when the streets are empty, and the bars were about to close.</p>
<p>I could not believe, that a P4 running at 3GHz should be so slow. So today I took the backup from yesterday, installed <a href="http://www.virtualbox.org/">VirtualBox</a>, and restored the image to a new virtual machine. It took about 2 hours altogether. I&#8217;m not saying that <a href="http://www.virtualbox.org/">VirtualBox</a> is in any way superior to <a href="http://www.linux-kvm.org/">kvm</a>, but I can show that in our case it&#8217;s ten times as fast. I&#8217;m sure we made mistakes in the deployment and there might be ways to reach this speed with <a href="http://www.linux-kvm.org/">kvm</a> as well.</p>
<p>No matter how much trouble we went through, it was sure an interesting night, we learned a lot about virtualization and image cloning, that might soon become handy.</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2009/08/05/migrating-from-physical-to-virtual-server-with-pain-and-tears/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>We&#8217;ve been hacked</title>
		<link>http://itworks.hu/2008/03/01/weve-been-hacked/</link>
		<comments>http://itworks.hu/2008/03/01/weve-been-hacked/#comments</comments>
		<pubDate>Sat, 01 Mar 2008 12:44:10 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[annoyance]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[rootkit]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=23</guid>
		<description><![CDATA[What could make one&#8217;s Saturday morning better, than a slight hangover? Well idling through a few mail folders, reading a few log messages and discovering that your server has been hacked for over three days is not the thing, for &#8230; <a href="http://itworks.hu/2008/03/01/weve-been-hacked/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What could make one&#8217;s Saturday morning better, than a slight hangover? Well idling through a few mail folders, reading a few log messages and discovering that your server has been hacked for over three days is not the thing, for sure.</p>
<p><span id="more-23"></span>Being a  bit on the paranoid side, I have a few tools up and running, that monitor my filesystems, for changes that were not made by me.</p>
<p>One such tool is <a href="http://www.nongnu.org/tiger/" target="_blank">tiger</a> which gave me lines like:</p>
<pre> # Checking listening processes
NEW: --WARN-- [lin003w] The process `bash' is listening on socket 7171 (TCP on every interface) is run by angel.
NEW: --WARN-- [lin003w] The process `oidentd' is listening on socket 113 (TCP on every interface) is run by oident.</pre>
<pre># Verifying system specific password checks...
NEW: --FAIL-- [lin005f] Installed file `/usr/bin/pstree' checksum differs from installed package 'psmisc'.
NEW: --WARN-- [lin001w] File `/lib/libproc.a' does not belong to any package.
NEW: --WARN-- [lin001w] File `/lib/libproc.so.2.0.6' does not belong to any package.
NEW: --WARN-- [lin001w] File `/lib/lidps1.so' does not belong to any package.
NEW: --WARN-- [lin001w] File `/sbin/ttyload' does not belong to any package.
NEW: --WARN-- [lin001w] File `/sbin/ttymon' does not belong to any package.
NEW: --WARN-- [lin001w] File `/usr/sbin/ttyload' does not belong to any package.</pre>
<pre># Checking listening processes
NEW: --WARN-- [lin003w] The process `bd' is listening on socket 60001 (TCP on every interface) is run by sdb.</pre>
<p>This I just ignored, being absent minded at times, I tend to forget when I install new binaries. Altough I clearly remembered, that I haven&#8217;t touched the server for quite a time.</p>
<p>But there were other reports as well, from <a href="http://www.rootkit.nl/">RKHunter</a> that some files were changed on the file system and a new user was added. It turned out, that a day later the guy activated himself, and installed SH4 and SH5 rootkits on the system.</p>
<p>RKHunter and Tiger reported the changes. A few commands were changed, to hide some processes and files.  The rootkit is a bit screwed up, as the top command doesn&#8217;t work at all.</p>
<p>Since I also keep regular backups of the system I wanted to quickly remove the backdoors, I tried to overwrite the changed files on the system. The changed commands had a few  attributes set, so they were read only. To overwrite them with the original files first I had to chattr them.</p>
<p>Unfortunately these rootkits tend to restore themselves from  the demons they spawn, which I couldn&#8217;t find until the files were restored. Since I had all the information from the security programs it was quite easy to write a script to erase the rootkits and restore the original files.</p>
<pre>SRC="/path-to-archive"

for i in /bin/ls /bin/netstat /bin/ps /usr/bin/find /usr/bin/md5sum /usr/bin/pstree /usr/bin/top /sbin/ifconfig; do
    echo $i
    chattr -sia $i
    rm $i
    cp ${SRC}/$i $i
done

chattr -sia /lib/lidps1.so /etc/sh.conf /dev/srd0  /dev/shm/bd /dev/shm/nou
rm /lib/lidps1.so /etc/sh.conf /dev/srd0  /dev/shm/bd /dev/shm/nou

chattr -sia -R /lib/libsh.so /usr/lib/libsh /dev/.raw
rm -r /lib/libsh.so /usr/lib/libsh /dev/.raw

rm /sbin/ttyload /sbin/ttymon /usr/sbin/ttyload</pre>
<p>When this was ran, I was able to find and kill the processes from the backdoors. There were strange processes named bash, ttymon, /usr/sbin/httpd, /usr/sbin/apache/log and suchlike, I didn&#8217;t recognize.  After killing the processes, I&#8217;ve re ran the script, to make sure there were no application hooks that  recreated the files. Then I went through the entire proc table again with a fine comb.</p>
<h1>Post-mortem</h1>
<p>It turned out, that the hacker came in through the mldonkey server, that I used to download some torrents. It was ran in a chrooted environment to start with, but this didn&#8217;t seem to matter. So much for chroot. The attacker first used a kernel exploit to gain root priviledges. Then he created an account named &#8220;angel&#8221;and uploaded and installed the rootkits. He also uploaded what seemed to me like an IRC bot, and spread it liberally around the machine. (I found about 5 copies, but I didn&#8217;t count)</p>
<p>The kernel vulnerability  existed, because even though the new patched kernel was already installed, the system was not restarted to use it. After the reboot the kernel exploit is hopefully gone, but the mldonkey server remains vulnerable. Mldonkey is disabled on the server for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2008/03/01/weve-been-hacked/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Linux on Compaq Contura Aero 4/25</title>
		<link>http://itworks.hu/2008/02/13/linux-on-compaq-contura-aero-425/</link>
		<comments>http://itworks.hu/2008/02/13/linux-on-compaq-contura-aero-425/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 07:52:51 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[compaq contura aero]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=22</guid>
		<description><![CDATA[My dad found this puppy on the street. Someone decided to get rid of it, and put it out for grabs. Since it&#8217;s a nice compact looking machine we decided to give it a spin. Originally the computer ran DOS, &#8230; <a href="http://itworks.hu/2008/02/13/linux-on-compaq-contura-aero-425/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My dad found this puppy on the street. Someone decided to get rid of it, and put it out for grabs. Since it&#8217;s a nice compact looking machine we decided to give it a spin.</p>
<p>Originally the computer ran DOS, and judging from the software I found on it, it was used by someone visually challenged, for reading out text through the speaker.</p>
<p>Looking at the configuration I found that even though originally it is supposed to contain 4 to 8 Megs of RAM, and 84 to 250Mb HDD. It&#8217;s expanded to the last limits possible for the computer. I have 20Mb RAM with a blasting 1,3Gb HDD! Unfortunately the board only has a 486 SLC, running on a staggering 25Mhz, a 4 bit grayscale VGA adapter and a grayscale LCD with 640&#215;480 resolution.</p>
<p align="center"><strong>I HAD TO put Linux on this, no matter how slow it is to start with!</strong></p>
<p align="center"><span id="more-22"></span></p>
<p>There are some issues concerning this install. To start with it doesn&#8217;t have any kind of optical disk, network adapter of any kind, USB was unknown to mankind at the time of manufacturing, as well as the memory cards of any kind. I only had the following options:</p>
<ul>
<li>Use the PCMCIA floppy that came with the puppy</li>
<li>Use a serial cable and transfer the images using something like LapLink</li>
<li>Use a parallel cable as above</li>
</ul>
<p>So I decided to take the non-trivial alternative. I tore the laptop apart, along with my father&#8217;s other laptop. I removed the hard disk and put it in the other laptop. I&#8217;ve installed a clean install of Debian testing (just to make sure all the latest hardware drivers will be installed, if I happen to upgrade to P4 <img src='http://itworks.hu/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> ), and put the disk back in the Aero. No luck. It haven&#8217;t got past the init phase, but did show some promise. So I decided against using a mainstream distrib.</p>
<p>The next attempt was to use a distribution aimed for this kind of beasts, the DSL (Damn Small Linux) This according to ancient scrolls scattered around the net, did run on similar machines. DSL is a tiny distribution, based heavily on busybox, and other tiny tools. The entire ISO image is only 50Mb.  I&#8217;ve installed it on the disk and gave it a spin in the Aero.  This is where things start to go wrong&#8230;</p>
<p>The Aero lacks coprocessor (in SLC, S stands for single, meaning that it has a 16 bit bus, LC means less coprocessor) This was natural in those times, you didn&#8217;t want too much float arithmetics, there no one heard of MP3 then, and JPEG was literally nowhere to be seen. This probably halved the energy consumption of the notebook, so I can&#8217;t blame them too much for excluding them. I however can blame the DSL guys for excluding the virtual coprocessor support from their kernel image. Come on, it&#8217;s not a single disk distrib any more, what harm would that extra few kilobytes bring to the kernel? Anyways if you are not planning to really support pre-486 computers, why build the image for 386 architecture? The 386-es did only have external coprocessors. Sometimes these things make me wonder&#8230;</p>
<p>This really crippled my style, instead of having the Aero up and running in two hours it took me almost a day to get it running. Not being able to hunt down any pre-built kernel for this, I&#8217;ve decided to roll my own. Fortunately all the kernel sources, and the configuration they used to build their kernel was available. Except for some patches you need to compile the kernel using current tools, and of course the madwifi drivers. After a couple of unsuccessful attempts, since I haven&#8217;t tried to build a kernel for over 5 years, I managed to get one running. Well if not running, at least up to the point, where it tried to mount the root fs, where I met the obnoxious error message:</p>
<pre>EXT2-fs: hda1: couldn't mount because of unsupported optional features (4).</pre>
<p>Going through most of the forums I&#8217;ve seen this in, I could not figure out what the heck this is supposed to mean. I knew I used ext3, why does it want to mount it as ext2? And since it&#8217;s backward compatible, why can&#8217;t it? A quick check on the other laptop revealed it can&#8217;t boot either. So I rebooted from the LiveCD, having a hunch. After booting I issued fsck /dev/hda1, and yes this was it! The volume reached maximum mount count and it seems I lack some kernel feature (or maybe something else, I should need to look in the automatic fsck in more depth) and the system check could not be performed.</p>
<p>I plugged the disk back in the Aero and it booted up, started the X so I checked the /proc/cpuinfo.</p>
<p align="center"><strong>OMG! 28.2 bogomips!</strong></p>
<p align="left">More on my adventures with this later.  <img src='http://itworks.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2008/02/13/linux-on-compaq-contura-aero-425/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>DB2 Express-C 9.5 on Debian</title>
		<link>http://itworks.hu/2007/11/13/db2-express-c-95-on-debian/</link>
		<comments>http://itworks.hu/2007/11/13/db2-express-c-95-on-debian/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 19:23:23 +0000</pubDate>
		<dc:creator>csak</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[DB2]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[X11]]></category>

		<guid isPermaLink="false">http://itworks.hu/?p=21</guid>
		<description><![CDATA[For our current pet project we&#8217;ve decided to use DB2 Express-C as a database back-end. The choice is made, so our junior developers could practice their art on databases that resemble enterprise databases more than MySQL or Postgres. (We have &#8230; <a href="http://itworks.hu/2007/11/13/db2-express-c-95-on-debian/">Read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For our current pet project we&#8217;ve decided to use DB2 Express-C as a database back-end. The choice is made, so our junior developers could practice their art on databases that resemble enterprise databases more than MySQL or Postgres. (We have already ruled out SAPDB/MaxDB on previous occasions.)</p>
<p><span id="more-21"></span><br />
First off the system I&#8217;m trying to install the server is remotely located, and doesn&#8217;t have any kind of X on it. This rules out all kind of graphical installs, but I never was fond of those anyway.</p>
<p>The system is running a Debian testing, with pretty strict firewall rules.</p>
<p>The install went easy, but with a few glitches. First off I&#8217;ve downloaded the installer from <a href="http://www-306.ibm.com/software/data/db2/express/download.html" target="_blank">IBM</a>. This required my PartnerWorld password, so I guess it&#8217;s not as easy to get as it seems. Then I&#8217;ve unpacked the installer and went on to install as root (this is usual for most installs, but almost mandatory for IBM products) This turned out to be a mistake later, as Express-C is different from other enterprise DB2-s. It&#8217;s preferred to be installed as a DB user, unless you want to run several instances on a given machine (not common for a single-shot pet-project).</p>
<p>The install went on fine with the console mode, and as a nice feature, even the text-mode installer shows a time estimate for each step.</p>
<p>After installing the application several times,  I went to read some documentation, as I couldn&#8217;t find any of the tools I was used to on DB2 EE 8.2. The IBM Infocenter is always a good idea to look up such informations, see the one I looked at <a href="http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp" target="_blank">here</a>.</p>
<p>Unfortunately all manuals described the startup  as a simple process, all starting with the usual loading of DB2 profile, and then starting up the db with the db2start command. Unfortunately it always threw an error message, which <a href="http://www.thescripts.com/forum/thread569412.html">turned out</a> to be a problem with the default shared memory size. The simple solution is to add the lines:<br />
<code><br />
kernel.msgmni = 1024<br />
kernel.shmmax = 268435456<br />
</code></p>
<p>to the /etc/sysctl.conf file and then applying the changes with the</p>
<p><code>sysctl -p</code></p>
<p>command.</p>
<p>The db then started up fine, but as it turned out I should not be running the non-root installation, as that only permits local &#8220;APP&#8221; level connections.</p>
<p>So I&#8217;ve created the system users dasadm, db2inst for later use.</p>
<p><code>mkdir /data/db2<br />
adduser --system dasadm --home /data/db2/dasadm<br />
touch </code><code>/data/db2/dasadm/.profile<br />
chown dasadm.nogroup </code><code>/data/db2/dasadm/.profile</code><br />
<code>adduser --system db2inst --home /data/db2/db2inst<br />
</code><code>touch </code><code>/data/db2/</code><code>db2inst</code><code>/.profile<br />
chown </code><code>db2inst</code><code>.nogroup </code><code>/data/db2/</code><code>db2inst</code><code>/.profile</code></p>
<p>Then the entire DB was reinstalled using the root user.</p>
<h4>Creating an admin server</h4>
<p>The admin server is used to monitor, and manage your DB2 instances on a system. To create and start service, issue the commands:</p>
<p><code>chsh dasadm -s/bin/sh<br />
DB2_HOME/instance/dascrt dasadm<br />
</code></p>
<p>There seems to be some error on the current version of DB2, the admin server keeps sending messages like:<br />
<code>The state of instance 'dasadm' gcf module '/opt/ibm/db2/V9.5/das/lib/libdb2dasgcf.so.1' is OPERABLE (OFFLINE).</code><br />
I could not yet locate the actual reason, but to disable this message it&#8217;s great to turn the db2fmd off. That can be achieved by commenting out the respectable lines in the inittab, and then reloading the inittab with:</p>
<p><code>init q</code></p>
<p>I&#8217;ll keep this off until I find some way to work around the current problem.</p>
<h4>Creating a db instance</h4>
<p>The DB2 instance was created and started using the following commands, as root:<br />
<code>DB2_HOME/instance/db2icrt -u db2inst db2inst<br />
</code><code>DB2_HOME/instance/db2istrt -u db2inst db2inst</code><code><br />
</code></p>
<p><code></code>command. When using the command one must make sure the provided ID actually <strong>HAS A SHELL</strong>! Of course it took me quite a while to find that out.</p>
<h4>Getting the  Control Center to work</h4>
<p>First off I thought it would be a good idea to just forward the DB2CC X11 output to my computer.</p>
<p>To get X forwarding on the server I tried doing what I read <a href="http://forums.vpslink.com/archive/index.php/t-1627.html" target="_blank">here</a>. After installing the xauth package I was able to forward my favorite X application (xteddy) through to my desktop. There still seems to be a problem, that the window content is not forwarded, even thought the bear shaped window appears. However when I switch over to another user (root and then to db2inst) it simply fails to forward the X. It turned out that the  xauth must be copied over to the user that is to be authorized using a command like:<br />
<code><br />
xauth -f /home/MYUSER/.Xauthority extract /root/.Xauthority :0<br />
</code></p>
<p>I could not however use this, to extract the xauth from my user directly to the db2inst user.</p>
<p>Cutting the crap, I&#8217;ve got fed up with the xauth, so I just thrown in a shell for the db2inst user, and authorized my user to log-in remotely. Then X11 forwarding worked straight away, and I was able to forward the db2cc without any problem. It&#8217;s quite slow, but what the heck?</p>
<p>The speed problem can be helped a bit by adding a -C (compress) parameter to the ssh. It speeds the connection up almost to the level of running it on the local network through my ADSL connection.</p>
<p><strong>Summarizing</strong></p>
<p>After wasting hours on trying to set things up I got some problem starting up the administrator instance, being unable to trace it down to the root of the problem, I uninstalled the entire installation, wiped the install directory and started up the install in graphical mode as root with copying the X authorization as described above.</p>
<p>The installer was running for about 5 minutes, and created and configured the  basic DB instance.</p>
]]></content:encoded>
			<wfw:commentRss>http://itworks.hu/2007/11/13/db2-express-c-95-on-debian/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

