Feb 17

Two days. Two days of massive fighting with Apache and with .htaccess but I ended up winning this fight (and eventually the battle as well). I will give a simplified version of the problem, it’s enough to understand what was going on.

I was trying to create SEO URLs with the help of Apache’s mod_rewrite and .htaccess. Now consider the following URL:

http://www.example.org/article.php?id=2341

Not the most search engine optimised URL, right? What we would like to create from this looks like this:

http://www.example.org/article/2341/

Here’s a simple diagram how the mod_rewrite works:

Apache mod_rewrite

It’s pretty straigthforward. Firstly we need to create a .htaccess in the folder where we have the examples. If you run Apache server on your machine then create a folder under the www (/var/www under Linux) directory, and name it ’seo’.
To see the folder you will need to enter http://localhost/seo/ into your webbrowser.

Now create a .htaccess file in your seo folder and add the following to it:

1
2
3
RewriteEngine on
RewriteBase /seo
RewriteRule ^articles/([0-9]+)$ articles.php?id=$1

Create another file and name it articles.php and copy the following to it:

1
2
3
4
<?php
$iId = $_GET['id'];
echo 'You have selected article id #' . $iId;
?>

Before running this example don’t forget to enable the mod_rewrite option for Apache. To do this (or to check whether you have this module enabled) open your httpd.conf file and find the following line

1
LoadModule rewrite_module modules/mod_rewrite.so

If there is a #sign before it remove it (uncomment it). Don’t forget to restart your Apache server to enable your settings!

Now go to your browser and open the page http://localhost/seo/articles.php. You should see a screen which says “You have selected article id #”. Change the URL to http://localhost/seo/articles.php?id=2341
Now you should see exactly the same:

article.php with id

And now the moment of truth, enter http://localhost/seo/articles/2341 to your browser’s address bar (no trailing slash!). There are two kind of people now. The ones who see the same output as before, or the ones who see “You have selected article id #”. The ones who get an empty id should read on.

article correctly brining up the id

article not showing id

I did an exhaustive research on this topic, what could go wrong? For some strange reason, when Apache sees /articles/ it automatically loads articles.php. And this why the id is not displayed as only the articles.php gets invoked, without any parameter. I can tell you now that the error is not in .htacccess but in Apache’s configuration file, httpd.conf.

I run AppServ on my machine. I asked a friend of mine to run the previously mentioned scripts, he had no problems running it. I asked him to send over his httpd.conf file. Shockingly, there were differences in my version and in his (he runs WampServer). I simply copied the 2 relevant sections over and the RewriteRule started work like charm.

Open your httpd.conf file and find the following lines (yours might be sligthly different):

1
2
3
4
5
6
7
<Directory />
Options FollowSymLinks ExecCGI Indexes
AllowOverride None
Order deny,allow
Deny from all
Satisfy all
</Directory>

Rewrite this to:

1
2
3
4
5
6
7
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
allow from all
Satisfy all
</Directory>

Find this in your file (again, yours might be a bit different):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<Directory "C:/AppServ/www">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks MultiViews ExecCGI
 
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
AllowOverride All
 
#
# Controls who can get stuff from this server.
#
Order allow,deny
Allow from all
 
</Directory>

And rewrite it to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<Directory "C:/AppServ/www">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks
 
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
AllowOverride All
 
#
# Controls who can get stuff from this server.
#
Order Deny,Allow
Allow from all
Allow from 127.0.0.1
 
</Directory>

And yet again, don’t forget to restart your Apache server before testing the modifications! This solved the problem for me, I hope you find this solution useful.

Feb 13

News are spreading fast, Ryanair will suspend it’s booking service for 4 (that is four) days! Due to the new Office of Fair Trading rule, airlines are obliged to show their air taxes to customers.

For reasons unknown Ryanair will make these changes (even weeks later then the original deadline) while their booking system is offline. They won’t take any bookings online nor through their phone systems. As pointed out in the the article, they might have just as well place a link on their frontpage to easyJet.com.

Is it just another IT project failure? Might be so. It is clear that Ryanair didn’t plan this well and as Deri Jones (CEO of web application testing specialist SciVisum) says:

Ryanair are not stupid, so there must be some logic to this excessive downtime. It is possible that careful cost management - one of their trademarks - has resulted in under-delivery online, and they are simply paying the price for not having planned and executed better on this change

Feb 13

If people hear the word “database” they immediately think about large scale systems, server rooms, millions of rows of data, multiple tables and so on. The fact is, databases are somewhat like that.

Currently we are witnessing increasing demands for mobile computing (wireless, mobile). The rapid growth of mobile phones, PDAs, laptops means more people working on the road, more people working from home. Sooner or later, users would like to have any data, accessable at anytime and anywhere (especially mission-critical data). This is where mobile databases come into the picture. Bare in mind that businesses face a lot of problems trying to implement mobile databases which include: privacy, security and costs.

A database that is portable and physically separate from the corporate databse server but is capable of communicating with that server from remote sites allowing the sharing of corporate data.

The components of the mobile database environment include:

  • corporate database server and DBMS that manages and stores the corporate data and provides corporate applications;
  • remote database and DBMS taht manages and stores the mobile data and provides movile applications;
  • mobile database platform that includes laptop, PDA, or other internet access devices;
  • two-way communication links between the corporate and mobile DBMS.

Depending on the requirements of the mobile applications, the user of the device might log on to the corporate database and work with data there or download the necessary data onto the device that he is using. In this case the data synchronisation will take place later.
The mobile database can either do short periodic connections to the corporate database (e.g. while downloading data) or have an ongoing direct communication.

The additional functionality required of the mobile DBMSs include:

  • communicate with the centralised database server through modes such as wireless or Internet access;
  • replicate data on the centralised database server and mobile device;
  • synchronise data on the centralised database server and mobile device;
  • capture data from various sources such as Internet;
  • manage data on the mobile device;
  • analyse data on a mobile device;
  • create customised mobile applications.

My opinion is that mobile databases will evolve as there is a higher and higher increase for mobile access. The only problem that I feel with this method is the privacy of the corporate data. Sending critical information and data about an organisation through databases might hold some risks.

[Ref: Thomas Connolly & Carolyn Begg: Database Systems: A practical approach to design, implementation and Management)

Feb 11

I always had this problem with my Firefox web-browser. Whenever I was running it for a long time, it suddenly hung and the only solution that brought it back to life was a pure and solid click on the “end process” button. Some weeks ago I really had enough of it and I thought I would run a search on this, hoping to find a solution. And luckily I did. This website explains how to fix the Firefox memory leak. Let me summarise the article:

  • Type about:config into your address bar in Firefox.
  • Create a new integer value (right click, new > integer). Name it as browser.cache.memory.capacity and give a low number for its value (Save it afterwards)
  • Search for the value browser.cache.disk.capacity and set its value to 15000 if you are using 1G of RAM.
  • Search for network.prefetch-next and set its value to false.

I think this should solve the memory leak, however on the website I have just recommended you can read about some more solutions as well. Happy hacking Firefox :)

Jan 29

Ever wanted to get rid of the address bar in your popup windows generated by JavaScript within IE7? Bad news, is that you can’t. IE7 will enforce the address bar to be shown and you simply can’t change it; It is a security feature.

We think the address bar is also important for users to see in pop-up windows. A missing address bar creates a chance for a fraudster to forge an address of their own. To help thwart that, IE7 will show the address bar on all internet windows to help users see where they are. IE7 will also help users avoid fraudulent sites if users choose to use the Phishing Filter to check a site for known phishing activity.

(http://blogs.msdn.com/ie/archive/2005/11/21/495507.aspx)

Jan 18

A new year means a start of a new semester, hence new stuff to learn. My modules for the upcoming semester are:

Jan 17

Please feel free to download my work for Concepts of AI assignment.

Concepts of AI - Wumpu's World (131)

How to play the game?

 First of all type in ‘start.’, this is what launches the game.

If you are ever lost during the gameplay, you can type in help or hint, which gives you all the commands.

 Basically all you have to do is to pick up the bow and arrow and proceed to “Issum Forest”. You are able to enter the forest with the knife or with the swords as well but you can’t fight the wumpu. It will fly away. To kill it, you have to use the bow and the arrow. There are two ways of completing the game. One is that you either kill the wumpu or you take the girl.

There is one secret area on the map. There is a temple in Vint Plains. That temple is not shown your map. There is a cave in Vint Plains and if you issue the correct command (look at or look hole) you will see that there is a temple called Hephaestus Temple. Then you are able to issue the command go to Hephaestus Temple. In there you will find a secret word which can be ‘said’ by the player. (Please be advised that using the “magic” word might not be the best solution :) ).

Be advised that you can pick up water and “eat” it. I did not have time to implement the “drink” command. There are many options for the player to pick up things, look at things. Whenever the player enters a particular area on the map, the items are listed.

To run this application you need to download SWI prolog.

Jan 11

New domain

start Comments Off

I have started to use this brand new domain. I had my own fun moving the WP database and files over, but it seems to be fine now. New articles will come, soon! :)

Dec 20

Further to an earlier post:

The X represents your current location on the map.
You are on the Lymedius Plains.
| ------------------------------------------------------- |
| Issum Forest      | Vint Plains   | Ledelen Mountains   |
| ------------------------------------------------------- |
| Viwude Cave       | Lauk Desert   | Torit Swamp         |
| ------------------------------------------------------- |
| Lymedius Plains X | Lersam Lake   | Kiml Mountains      |
| ------------------------------------------------------- |

More will follow soon with code snippets as well.

Dec 20

Before continue reading please note that this article doesn’t intend to call upon you to create nasty applications. If you use this code it should be for your own fun or for learning purposes.

After doing some research on disabling keys or key combinations I found out that there are several ways of achieving the before mentioned key combos. CTRL-ALT-DEL combo is part of the SAS (Secure Attention Sequence) thus the solution to disable this is to write your own gina.dll (Graphical Identification and Authentication).

Don’t worry, I’m not looking into that as for now, I’m going to show you the work around. We will use C#’s Registry editing possibilities to set/change the group policy for the CTRL-ALT-DEL key sequence. Let’s see what we are about to do without programming anything. Open Start Menu > Run and enter gpedig.msc. Navigate to: User Configuration > Administrative Templates > System > CTRL+ALT+DELETE Options.This is the place where you normally set the behaviour of the key combo. Select Remove Task Manager > Double-click the Remove Task Manager option.

If you change it’s value, the following registry entry gets created/modified: Software\Microsoft\Windows\CurrentVersion\Policies\System and the value of DisableTaskMgr gets set to 1.

Now, the task is set. Let’s get down to business and start coding:

Important thing, don’t miss out this line:

using Microsoft.Win32;

And now the method I have created looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void KillCtrlAltDelete()
        {
            RegistryKey regkey;
            string keyValueInt = "1";
            string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
 
            try
            {
                regkey = Registry.CurrentUser.CreateSubKey(subKey);
                regkey.SetValue("DisableTaskMgr", keyValueInt);
                regkey.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

If you run the method and try to press CTRL-ALT-DEL the following screen should come up:

CTRL ALT DEL

So the CTRL-ALT-DEL combo has been taken care of, let’s see the rest. You might have found this a bit difficult, so here’s an easy one. How to disable ALT+F4. 5 lines of code alltogether:

1
2
3
4
5
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            base.OnClosing(e);
        }

Okay. As for the rest I was reading many many articles, and they gave a lot of help. I can’t name one, as I was looking into at least 15 which all held some useful peace of information. I will give you the the source of the method called hooks. The code snippet uses the LowLevelKeyboardProc which is:

The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was “injected”. However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.

Again, dont forget:

using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Diagnostics;

Here’s the rest what you need:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[DllImport("user32", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, int hMod, int dwThreadId);
        [DllImport("user32", EntryPoint = "UnhookWindowsHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int UnhookWindowsHookEx(int hHook);
        public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
        [DllImport("user32", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
        public const int WH_KEYBOARD_LL = 13;
 
        /*code needed to disable start menu*/
        [DllImport("user32.dll")]
        private static extern int FindWindow(string className, string windowText);
        [DllImport("user32.dll")]
        private static extern int ShowWindow(int hwnd, int command);
 
        private const int SW_HIDE = 0;
        private const int SW_SHOW = 1;
public struct KBDLLHOOKSTRUCT
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        public static int intLLKey;
 
        public int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
        {
            bool blnEat = false;
 
            switch (wParam)
            {
                case 256:
                case 257:
                case 260:
                case 261:
                    //Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key,
                    blnEat = ((lParam.vkCode == 9) &amp;&amp; (lParam.flags == 32)) | ((lParam.vkCode == 27) &amp;&amp; (lParam.flags == 32)) | ((lParam.vkCode == 27) &amp;&amp; (lParam.flags == 0)) | ((lParam.vkCode == 91) &amp;&amp; (lParam.flags == 1)) | ((lParam.vkCode == 92) &amp;&amp; (lParam.flags == 1)) | ((lParam.vkCode == 73) &amp;&amp; (lParam.flags == 0));
                    break;
            }
 
            if (blnEat == true)
            {
                return 1;
            }
            else
            {
                return CallNextHookEx(0, nCode, wParam, ref lParam);
            }
        }
public void KillStartMenu()
        {
            int hwnd = FindWindow("Shell_TrayWnd", "");
            ShowWindow(hwnd, SW_HIDE);
        }
private void Form1_Load(object sender, EventArgs e)
        {
            intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
        }

Quite obviously you can programmatically reset these values. Here’s the code to re-enable everything:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void ShowStartMenu()
        {
            int hwnd = FindWindow("Shell_TrayWnd", "");
            ShowWindow(hwnd, SW_SHOW);
        }
public static void EnableCTRLALTDEL()
        {
            try
            {
                string subKey = "Software\Microsoft\Windows\CurrentVersion\Policies\System";
                RegistryKey rk = Registry.CurrentUser;
                RegistryKey sk1 = rk.OpenSubKey(subKey);
                if (sk1 != null)
                    rk.DeleteSubKeyTree(subKey);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnhookWindowsHookEx(intLLKey);
        }

I hope you enjoyed my article and that you found some useful bits. I tried to collect all the information I managed to find during my research on this topic.