All Code Samples go here.

Disabling The hald-addon-storage Service On CentOS/RedHat

The haldHardware Access Layer Daemon – runs several processes in order to keep track of what hardware is installed on your system. This includes polling USB Drives and ‘hot-swap’ devices to check for changes along with a host of other tasks.

You might see it running on your system as follows:

1
2
3
4
2474 ?        S      0:00  \_ hald-runner
2481 ?        S      0:00      \_ hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
2487 ?        S      0:00      \_ hald-addon-keyboard: listening on /dev/input/event0
2495 ?        S     41:47      \_ hald-addon-storage: polling /dev/hdc

If your system is static and the devices do not change, you can actually disable this service using a policy entry.

Create a file in your policy directory, for example /etc/hal/fdi/policy/99-custom.fdi. Add the text:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>

<deviceinfo version="0.2">
    <device>
        <match key="storage.removable" bool="true">
            <remove key="info.addons" type="strlist">hald-addon-storage</remove>
        </match>
    </device>
</deviceinfo>

Save and reload the hald using /etc/init.d/haldaemon restart.

And you will find that service no longer is polling your hardware.

Of course to turn it back on, remove that policy entry and restart the haldaemon again, it will be back in service.

Solution Credit: Linuxforums User cn77

Experimenting with Pascal on Ubuntu

I’ve been busy lately on a number of projects, one of which is a programming class I am currently taking. The class itself is interesting, we are learning about the different types of programming languages. For our latest project, we were tasked with writing a simple program in Pascal. Pascal isn’t used too much any more since it lacks some of the features that most modern languages have, but it is good to know at least a little bit about it in case you ever run across some old Pascal programs in the wild.

The syntax for pascal is a bit verbose, that is the main complaint about it. There are a number of others, but that is beyond the scope of this howto.

Installing The Pascal Compiler on Ubuntu

Installing Pascal in modern Ubuntu is a cinch. The Free Pascal Compiler, or fpc, is all that you need to get started. It works great on 32-bit or 64-bit systems. Install with:

1
sudo apt-get install fpc

Any prerequisites will automatically download and install along with fpc.

Getting Started in Pascal

To test the compiler let’s start with a simple Hello World program. Open up hello.pas and enter:

1
2
3
4
5
6
7
program Hello;

begin

Writeln('Hello World');

end.

Compile with fpc hello.pas and run:

1
2
dave@cerberus:~/Pascal$ ./hello
Hello World

Selection Sort in Pascal

Now that we’ve verified it is running, I’m going to show you the code that I wrote for my program. Basically we were asked to Selection Sort two arrays of varying length. Apparently one of the (bad) features of Pascal originally was that you needed to declare the length of the array which made it a pain to work with them.

In this situation it is just two arrays so it isn’t too bad. Enter your array by creating two text files arrayA.txt and arrayB.txt. One number per line. The source code for sort.pas is:

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
61
62
63
64
65
66
67
68
69
70
71
72
73
program Sort;

var
        A: array[1..10] of Integer;
        B: array[1..20] of Integer;
        F: Text;
        i,j,k,l,m,temp: Integer;

begin
        {Read in array A}
        Assign(F, 'arrayA.txt');
        Reset(F);
        i:= 0;
        while not EOF(F) do begin
                Inc(i);
                Read(F, A[i]);
        end;

        {Read in array B}
        Assign(F, 'arrayB.txt');
        Reset(F);
        j:= 0;
        while not EOF(F) do begin
                Inc(j);
                Read(F, B[j]);
        end;
        i:=10;
        j:=20;

        {Print out the unsorted arrays}
        WriteLn('Unsorted Arrays:');
        WriteLn('Array A:');
        for k:=1 to i do
        Write(A[k], ' ');
        WriteLn();
        WriteLn('Array B:');
        for k:=1 to j do
        Write(B[k], ' ');
        WriteLn();
        WriteLn('=========================');
        WriteLn('Sorting Arrays...');
        WriteLn('=========================');

        {Selection Sort Array A}
        for l := 1 to i do
                for m := l + 1 to i do
                        if A[l] > A[m] then
                        begin
                                temp := A[l];
                                A[l] := A[m];
                                A[m] := temp;
                        end;
        {Selection Sort Array B}
        for l := 1 to j do
                for m := l + 1 to j do
                        if B[l] > B[m] then
                        begin
                                temp := B[l];
                                B[l] := B[m];
                                B[m] := temp;
                        end;

        {Print out the sorted arrays}
        WriteLn('Selection Sorted Arrays:');
        WriteLn('Array A: ');
        for k:=1 to i do
        Write(A[k], ' ');
        WriteLn();
        WriteLn('Array B: ');
        for k:=1 to j do
        Write(B[k], ' ');
        WriteLn();
end.

Compile and run (ok to ignore the compile-time errors)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dave@cerberus:~/Pascal$ fpc sort.pas
Free Pascal Compiler version 2.4.0-2 [2010/03/06] for x86_64
Copyright (c) 1993-2009 by Florian Klaempfl
Target OS: Linux for x86-64
Compiling sort.pas
Linking sort
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
73 lines compiled, 0.1 sec
dave@cerberus:~/Pascal$ ./sort
Unsorted Arrays:
Array A:
28 24 85 55 43 6 23 13 59 71
Array B:
13 37 36 53 24 83 27 42 62 71 9 92 1 41 6 3 88 77 65 67
=========================
Sorting Arrays...
=========================
Selection Sorted Arrays:
Array A:
6 13 23 24 28 43 55 59 71 85
Array B:
1 3 6 9 13 24 27 36 37 41 42 53 62 65 67 71 77 83 88 92
dave@cerberus:~/Pascal$

And there you have it. Compiling Pascal program on Ubuntu is an easy way to get your feet wet in programming. Pascal is a great beginner’s programming language, but if you want to learn more there are a number of great resources available for learning Pascal.

Adding Random Quotes to the Bash Login Screen

According to “official” system administrator rules and guidelines you shouldn’t be adding so-called vain scripts to the login prompt – only utilities that will add something useful to the system (for example, current system load, memory and disk usage, etc). However I have some systems that I frequently connect to and thought it would be neat to add a random quote script to my bash login. That being said, this should only be done on ‘non-production’ systems and adds a security vector so please be careful where you use this.

The goal of this is to add a little quote, at random, every time you log into your system. My thoughts were to do it not only as a little source of inspiration but also to add perspective to what I’m doing sitting in front of the computer all of the time.

Originally I was going to try to write the script solely in bash since it is so flexible (and just as a proof of concept) but dealing with RSS in bash isn’t exactly pretty and I just wanted to get this together as quick as possible. PHP makes parsing XML easy, there are a number of ways to accomplish it. I chose to use the ready-made script at rssphp.net to do this, if you are curious about how you can handle this yourself using SimpleXML check out this tutorial over at Pixel2Life. The end result of my solution is a bash script calling a php script to grab the quote.

The Code

First create a file named /etc/update-motd.d/10-quote. The name does not matter much – the number will decide what order the script is called in of all the scripts in /etc/update-motd.d. Do an ls on that directory to see what all is being called when you log in. Add the following lines to this file, assuming you are placing your scripts in /etc/scripts/:

1
2
3
4
#!/bin/sh
echo ""
/usr/bin/php /etc/scripts/getquote.php
echo ""

Download v1 of rssphp and extract it to the /etc/scripts/ directory. We will require that file in our php code.

Create the file /etc/scripts/getquote.php and add the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
require_once 'rss_php.php';    

        $rss = new rss_php;
        $rss->load('http://www.quotedb.com/quote/quote.php?action=random_quote_rss');
        $rssitems = $rss->getItems();

        if ($rssitems) {
                // print_r($rssitems);
                echo $rssitems[0]['description'].' :: '.$rssitems[0]['title']."\n";
        }
   
?>

I am using the RSS source from QuoteDB as the source of my quotes. Of all the places I checked (and I checked a lot) they seemed to have the most appropriate ones for this use. Feel free to use any source you wish – as long as the XML fields title/description hold the quote you will be able to use it. The RSS url was not obvious from the site and I had to do some digging to find it, in the end I am using http://www.quotedb.com/quote/quote.php?action=random_quote_rss.

We also add the if statement to allow it to degrade nicely in case you have no network connectivity to the server. After a short period – a second or two – it will time out and let you log in.

The end result is a pretty quote in our motd:

1
2
3
4
5
6
Linux vps01.[redacted].com 2.6.18-2-pve #1 SMP Mon Feb 1 10:45:26 CET 2010 x86_64 GNU/Linux
Ubuntu 10.04.1 LTS

"The absence of alternatives clears the mind marvelously." :: Henry Kissinger

root@vps01:~#

It should be pretty strait forward; let me know if you run into any problems!

Find Out If A Twitter Username Exists Using PHP/JSON

I’ve been trying to grab a Twitter screenname that people continually register and do not use. Twitter eventually deletes it, but I suppose it is in high enough demand that someone else registers it right away (and then continues to never use it). Wrote up a quick and dirty php script to check the Twitter API to see if a screenname exists and if it doesn’t, shoot a short an email. I’ve been using changedetection to roughly do the same thing but it has fallen short on two counts: the first is that it reports follower count changes, and second it only runs once a day and this hasn’t been fast enough for me to grab my desired screen name.

You can set this script to run via cron at any desired interval, I’ve set it to run every 30 minutes for me. Test with sample information to make sure it works under your setup. I’m using the default mail() function, and I also included some json decoding in there so you could also use this script to play around with decoding a user’s information in PHP.

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
<?php
/* Copyright (c) 2010 Dave Drager
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */


/* README
 * This is a simple script to check a username on Twitter and send a short email
 * if it is not found. It's the simplest way I found to do this. Using the
 * sample code you could also modify it simply to do something with a
 * found username as well. Details are in the $json_output array. Enjoy
 */


// fill in these 2 variables below
$username = "someusername";
$notifyemail = "your_email@address";

// this is needed otherwise file_get_contents errors out
error_reporting(0);
$url="http://api.twitter.com/1/users/show.json?screen_name=".$username;
$json = file_get_contents($url,0,null,null);

if($http_response_header[0] == "HTTP/1.1 404 Not Found") {
        //echo "Screen name not taken!\n";
        $to      = $notifyemail;
        $subject = 'Screen name now available - '.$username;
        $message = 'The screen name '.$username.' is now available on Twitter.';
        $headers = 'From: '.$notifyemail . "\r\n";
        mail($to, $subject, $message, $headers, '-f '.$notifyemail);
}
else {
        // screen name exists - you can do something here if you want
        //$json_output = json_decode($json,true);
        //print_r($json_output);
}
?>

If you are running it from cron, add the sample entry:

1
0 * * * * /usr/bin/php /path/to/script.php

The above would run the script every hour on the hour.

Of course you can easily modify this sample code if you are looking to do any kind of similar checking in your web app. If you find this kind of script useful, please let me know!

Using Google Analytics Or Other Javascript With Smarty Template Engine

On a website I was working on recently I added the Google Analytics tracking code to the footer of a Smarty template, like this:

footer.tpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-XX']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>


</body>
</html>

However, since the javascript used by Google Analytics includes { and } tags, also used by the Smarty template engine, it tries to interpret this code and depending on your settings will either fail silently or or with an error such as this:

Smarty error: [in footer.tpl line 148]: syntax error: unrecognized tag 'var'

The fix is simple. Enclose your Google Analytics code, or other javascript code, with {literal} and {/literal}. The literal tag allows you to place code to be displayed, well, literally.

The final code will look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{literal}

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-XX']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

{/literal}

</body>
</html>

Your website should now run properly with the Google Analytics code in place.

A phpBB 3 iPhone Style Theme With Option to Disable

phpBB iPhone theme style

phpBB iPhone theme styleA forum that I am an adminstrator for has been clamoring for an iPhone theme (style) for a long time now. In the past, I hadn’t seen any usable iPhone template for phpBB3, until now.

The theme is hosted on Google code and is named phpbb-iphone-style. It is downloadable here and was last updated June 18th, as of today.

The theme works wonderfully on the iPhone. However, the issue that I ran into is automatically displaying it for mobile browsers, such as the iPhone, Android and other platforms.

Fortunately there is a modification you can make to the phpbb code which is effectively a theme switcher for mobile browsers. The how to is located within the download file for the theme above.

What if a user wants to turn off the mobile style?

I modified the code to allow a user to set an option on their profile to permentently disable the theme when logged in on a mobile browser.

First, install the style as described above. As part of the switcher, you need to find out the theme ID. You can do so, after installing the style, by hovering over the ‘Detail’ tab in the ACP (Administrator Control Panel) and looking for the ‘id’ variable. In the example below it is ‘6’.

Once the theme is installed, move over to the “Users and Groups” tab, and then the “Custom Profile Fields” area. At the bottom of this page there is a box to add a new profile field. Type ‘disable_mobile’ as the name, and Boolean (Yes/No) as the type and click add.

For the options, I selected:

  • Publicly display profile field: No
  • Display in user control panel: Checked
  • Display on registration screen: Unchecked
  • Display on viewtopic screen: Unchecked
  • Required field: Unchecked
  • Hide profile field: Unchecked
  • Field name/title presented to the user: Disable Mobile Browser
  • Field description: When viewing on a mobile device (iPhone, Android, etc), clicking ‘yes’ will disable the mobile browser.
  • Entries: First option: Yes, Second option: No

On the second screen select the following items:

  • Field type: Radio Buttons
  • Default value: no

Save your custom profile field.

It will end up looking like this in the profile control panel of the end user:

phpbb iphone style disabler

Now the fun part, adding the code to your install to select which mobile browser to use automatically.

Back up, then open install dir/includes/session.php

Around line 1468 in the function setup

1468
1469
1470
1471
1472
        /**
        * Setup basic user-specific items (style, language, ...)
        */
        function setup($lang_set = false, $style = false)
        {

Replace

1
global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;

with

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
global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache, $user;


//-----Begin phone detection & redirection code-----

                $user->get_profile_fields( $user->data['user_id'] );
                $user_fields = $user->profile_fields;

                // if (!($user_fields['pf_disable_mobile'] == 1)) {  
                // Thanks to Chris Dembek for this code fix
                if (isset($user_fields['pf_disable_mobile']) && !($user_fields['pf_disable_mobile'] == 1))

                        //id of the iphone/mobile theme - SELECT THIS FROM YOUR STYLES
                        $mobilestyleid = 6;

                        //Fetch the users browser
                        $user_browser = strtolower($this->browser);

                        //List of mobile user-agent keywords
                        $browsers_array = array('240x320', '320x240','blackberry', 'iemobile', 'minimobile', 'mobile', 'opera mini', 'pda', 'phone', 'pocket', 'psp', 'symbian', 't-shark', 'wireless');

                        //Check for the user-agent in the list of mobile user-agents
                        foreach ($browsers_array as $ua_match) {
                                if (strpos($user_browser, $ua_match) !== false) {  //a match
                                        $style = $mobilestyleid;
                                        $this->data['is_mobile'] = true;
                                        break;
                                }
                        }

                }

                //-----End phone detection/redirection code-----

Make sure to replace $mobilestyleid = 6 with your style id number!

Save your file. Test out the modifications on your phone, you should be presented with the mobile version on reload (make sure to purge any cache if you don’t see it right away).

Finally go into your profile and select the ‘disable mobile browser’ option and make sure it reverts back to your regular default theme.

Let me know if you have any problems implementing this but it has worked great for this phpbb forum!

Another Bash One Liner To Delete Old Directories

We received a tip from blog readers Christian and Michael for alternatives to the command to delete all directories older than a certain period of time. These both work in bash and can be used in scripts to clean up old backup directories or any situation where you need to delete old directories from the command line.

From Christian:

find /home/backup/ -maxdepth 1 -type d -mtime +7 -exec rm -r {} \;

From Michael:

find /home/backup/ -maxdepth 1 -type d -mtime +7 -exec echo “Removing Directory => {}” \; -exec rm -rf “{}” \;

The first one works quietly, while the second one will display what is being deleted. These are probably faster than putting it into a for loop, so feel free to use whatever works best in your particular situation!