Feeds:
Posts
Comments

I have to admit I am a total DirectFB newbie and I had a hard time even compiling my first DirectFB program (the official DirectFB or tutorials on the Internet described procedures how to build DirectFB but not how to even compile the simplest demo program, forgive my poor google skill if somebody already posted the compiling instruction). Anyway I use the following command to compile successfully:

gcc -o simple simple.c `directfb-config --cflags` `directfb-config --libs`

OS: fresh installation of Gentoo 09132009
DirectFB version: 1.2.7
Source code of the demo program: http://www.directfb.org/docs/DirectFB_Tutorials/simple.html

Splash Screen with GTK+

The code:


#include <gtk/gtk.h>
static void destroy (GtkWidget*, gpointer);
static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);
int main (int argc,
          char *argv[])
{
  GtkWidget *window, *image;
  gtk_init (&argc, &argv);
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "A Splash Screen Demo");
  gtk_container_set_border_width (GTK_CONTAINER (window), 0);
  gtk_widget_set_size_request (window, 800, 480);
  gtk_window_set_decorated(GTK_WINDOW (window), FALSE);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

  /* Connect the main window to the destroy and delete-event signals. */
  g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (destroy), NULL);
  g_signal_connect (G_OBJECT (window), "delete_event",
                    G_CALLBACK (delete_event), NULL);

  image=gtk_image_new_from_file("wait.png");
  gtk_container_add(GTK_CONTAINER(window), image);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
}

/* Stop the GTK+ main loop function when the window is destroyed. */
static void
destroy (GtkWidget *window,
          gpointer data)
{
   gtk_main_quit ();
}
/* Return FALSE to destroy the widget. By returning TRUE, you can cancel
  * a delete-event. This can be used to confirm quitting the application. */
static gboolean delete_event (GtkWidget *window,
               GdkEvent *event,
               gpointer data)
{
    return FALSE;
}

And here’s the included “Please wait” image file in .png format:

The png file used by the splash screen demo program

The png file used by the splash screen demo program

To compile:


gcc -Wall -g demo.c -o splash `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`

Now test it:


./splash
# use Alt + F4 to close and exit.

Quite often we need to check the (effective) settings in a configuration file and the most common way is to use grep

grep -v ^# config_file

But this does not work well because
1) it does not filter out empty lines
2) it does not filter out lines start with space(s) or tab(s) and are followed by # or ; (openvpn uses both # and ; as comment characters)

As a solution to the solve the above limitations, I use the following egrep command quite often

egrep -v "^[[:cntrl:] ]*[#;]|^[[:cntrl:] ]*$ config_file

But the above command is a lot of typing therefore I add the following alias to my ~/.bashrc and it filters out all comment lines and empty lines [ including lines containing only space(s) and/or tab(s) ] nicely.

alias cf='egrep -v "^[[:cntrl:] ]*[#;]|^[[:cntrl:] ]*$"'

With this alias I just need to type the following to view my config files:

cf config_file

Reference:
Inspired by http://www.linuxjournal.com/content/tech-tip-view-config-files-without-comments, I also left a comment there (rc3) but that’s not the final version that I am using here.

Last week I helped one of our clients solve their web server being inserted with iframe problem, which started a few weeks back when they told me that their customers complained accessing to their product order status page resulting in some unexpected pop-up windows. As a result this client’s website is marked unsafe by anti-virus programs such as mcfee. My initial investication showed that accessing the problematic page results in an iframe line being inserted to the top of the page in the html source code:
<iframe src=”h t t p://w w w.h a c k i n g s.c n”></iframe>
(I intentionally add some spaces in the url as I don’t want you to accidentally hit that link going to the hacker’s site.)

A bit more detail about the setup of the webserver:
1) ASP.NET + IIS
2) runs behind a Linux firewall accessible through DNAT

My investigation continued and my accessing the same page from the firewall resulted in the same result — the hacking line being inserted. But when I accessed the page from any other workstation including the webserver itself, I didn’t see the line, which led to my wrong conclusion that there must be some virus in the webserver that is smart enough to tell where the traffic is from — when it’s from the gateway, the request is most likely made from the Internet; when it’s from the LAN, it stops inserting the line to fool the web administrator that the web server is fine. My conclusion is not coincident: I also used a Linux laptop to set up a temporary web server providing the exact same urls to replace the original webserver and the hacking line disappeared. I recommended the client to bring down the IIS webserver immediately and replace it with a Linux server. I thought the problem was solved.

A few days later, my client reported that the problem came back, with a Linux server being the web server. My hunting for the real cause of the problem went on and somehow arp cache poisoning got into my head. I heard it a lot before but never seen it in action. To get started I installed and run arpwatch on the firewall and before long I saw a lot of flip-flops scrolling up on the screen (mac addresses change back-and-forth) for a bunch of ip addresses in the client’s LAN. The client doesn’t use dhcp therefore there shouldn’t be flip-flops — At least that tells me that I was on the right direction to solve the problem. From the arpwatch log I saw something like this

...
Jul 29 13:21:18 linux-gw arpwatch: report: pausing (cdepth 3)
Jul 29 13:21:18 linux-gw arpwatch: flip flop 172.16.0.1 18:8b:41:72:b1 (0:13:20:3d:5e:53)
Jul 29 13:21:18 linux-gw arpwatch: report: pausing (cdepth 3)
Jul 29 13:21:18 linux-gw arpwatch: changed MAC address 172.16.0.199 0:50:da:7b:c6:60 (0:13:20:3d:5e:53)
...

I could see from the log entries that those flip flop lines share the same pattern — the mac address for a specific ip gets changed to the same mac address 0:13:20:3d:5e:53 then back to its original mac address. At that point I concluded whichever machine that has 0:13:20:3d:5e:53 as the mac address is the one that initializes arp poisoning attack. As the client didn’t have a ip to mac address mapping, the hunting for that machine took a bit while but luckily it was found on one of the workstations. I instructed the client to disconnect that workstation from the LAN and I conducted the test again, the hacking line was gone — either from the Internet or the gateway. What a relief! arpwatch continued to report a lot of flip-flops, but they are just for changing back to their original mac addresses from the poisoned mac address. When arpwatch stopped reporting flip-flops I generated an IP-Mac address map for the client so it will a piece of cake to ID which machine generates arp cache poisoning attack when problem like this happens again.

Direct Link
http://rc3.fileave.com/mkpass.py.txt

View Code (in colors)

To see the script in action, please visit my first Google App: http://genpswd.appspot.com/

Example Usage:


mkpass.py
generates 8-character password from all letters + all digits + all punctuation marks

mkpass.py -s 12
same as the above except the length is now 12

mkpass.py -t dlL
generates 8-character password from all letters + all digits

mkpass.py -t dlL -i _=\?
generates 8-character password from
all letters + all digits plus _ = ?
please note that the question mark needs to be escaped with backslash.
when running in shell.Other characters that need escaping are:
' " ` ! $

Simple bash reminder

Need to have a reminder while working on the computer? I have developed this simple but very useful script to remind me things that I would forget without a reminder.

#!/bin/bash
# Simple reminder shell script
usage() {
 echo -e "usage: `basename $0` [-t minutes] [-m message] [-b beeps]"
 echo -e "-t M\t\ttime scheduled to go off in minutes, default 1"
 echo -e "-m message\t\tMessage to show when alarm goes off, \
default to 'Something needs your attention'"
 echo -e "-b beeps\t\tNumber of beeps, default 5"
}

alarm() {
    sleep ${1}m
    echo -n ${2}
    bps=$3
    seq_beeps=$((bps*2))
    for i in `seq $seq_beeps`; do
        [ `expr $i % 2` == 0 ] && sleep 1 || echo -n -e \\a
    done
}

minutes=1
beeps=5
msg='Something needs your attention'
[ ! `whoami` == "root" ] && echo \
    "must be root to run this script" && exit 0
while getopts "t:m:b:h" flag
do
    case $flag in
        t)
            case $OPTARG in

                 [0-9] | [0-9][0-9] | [0-9][0-9][0-9] )
                minutes=$OPTARG;;

                *)
                echo "usage: minutes value must be in range 0 to 999"
                ;;
            esac
            ;;
        m)
            msg=$OPTARG;;
        b)
            case $OPTARG in
                 [0-9] | [0-9][0-9])
                    beeps=$OPTARG
                    ;;
                *)
                    echo 'usage: beeps value must be in range 0 to 99'
                    ;;
            esac
            ;;
        h|*)
            usage
            exit 0
            ;;
    esac
done
alarm $minutes "$msg" $beeps &

Example Usage:

alarm -t 5 -m "Check your coffee" -b 10
NOTE: You have to use sudo or become root to use this script.

This is a successor to my another post published a few days ago: http://ricochen.wordpress.com/2009/07/14/use-aleratec-roboracer-cddvd-duplicator-under-linux/

ALERATEC DVD CD ROBORACER LS DUPLEX BURN AUTO FLIP

#!/bin/bash
# script to control RoboRacer LS Duplex under linux

ADMIN=change_to@admin.email.address
DEBUG=1
DEV=`dmesg|awk '/pl2303.*ttyUSB/{print $NF;exit}'|tr -d ' '`
if [ -n "$DEV" ]; then
	DEV=/dev/$DEV
	if [ ! -c $DEV ]; then
		info="pl2303 port does not exist, make sure \
			RoboRacer LS Duplex is connected. If\
			so please reboot it and try again."
		rpr "Problem" "$info"
		exit 1
	fi
fi
# change the following device names if needed, if there
# are no other drives other than the Duplex's then most likely
# the names will be /dev/sr0 and /dev/sr1 
TOPDRIVE=/dev/sr1
BOTTOMDRIVE=/dev/sr2
SCRIPT=${0##*/}

rpr() {
	if [ -n "$ADMIN" ]; then
		echo -e "$2" | mail -s "`hostname -f` \
		RoboRacer: $1" $ADMIN
	fi
}
usage() {
	echo ">>Examples:"
	echo "$SCRIPT demo"
	echo "$SCRIPT load_topdrive"
	echo "$SCRIPT load_bottomdrive"
	echo "$SCRIPT eject_topdrive"
	echo "$SCRIPT retrieve_topdrive"
	echo "$SCRIPT eject_bottomdrive"
	echo "$SCRIPT retrieve_bottomdrive"
	echo "$SCRIPT remove_disc_topdrive"
	echo "$SCRIPT remove_disc_bottomdrive"
	echo "$SCRIPT top_hand_small"
	echo "$SCRIPT top_hand_big"
	echo "$SCRIPT top_hand_back"
	echo "$SCRIPT bottom_hand_small"
	echo "$SCRIPT bottom_hand_big"
	echo "$SCRIPT bottom_hand_back"
	echo "$SCRIPT top_tray_load_disc"
}

w() {
	echo -e "$1" >$DEV
}

ww() {
	case $1 in
		top_hand_small)	w !BNKRG95;;	#top handle turns a small angle
		top_hand_big)	w !BNKRB90;;	#top handle turns a big angle
		top_hand_back)	w !BNKRH96;;	#top handle turns back to origin
		bottom_hand_small)w !BNKPG93;;	#bottom handle turns small angle
		bottom_hand_big) w !BNKPB8E;;	#bottom handle turns a big angle
		bottom_hand_back) w !BNKPH94;;	#bottom handle turns back to origin
		top_tray_load_disc)	w !BNKDP90;;	#release one disc from the top disc loader
		1)	w !BNKLF8E;;
		2)	w !BNKFG89;;
		10)	w !BNKLG8F;;
		13)	w !BNKSTA3;;
		*)
			echo "unsupported parameter" && exit 0
			;;
	esac
	sleep 2
}

eject_topdrive() {
	[ -b $TOPDRIVE ] && /bin/eject $TOPDRIVE || echo "$TOPDRIVE does not exist"
}

retrieve_topdrive() {
	[ -b $TOPDRIVE ] && /bin/eject -t $TOPDRIVE || echo "$TOPDRIVE does not exist"
}

eject_bottomdrive() {
	[ -b $BOTTOMDRIVE ] && /bin/eject $BOTTOMDRIVE || echo "$BOTTOMDRIVE does not exist"
}

retrieve_bottomdrive() {
	[ -b $BOTTOMDRIVE ] && /bin/eject -t $BOTTOMDRIVE || echo "$BOTTOMDRIVE does not exist"
}

load_topdrive() {
	eject_topdrive
	ww top_hand_small
	ww top_hand_back
	ww top_tray_load_disc
	retrieve_topdrive
	[ $DEBUG -eq 1 ] && echo "Top drive $TOPDRIVE is loaded"
}

load_bottomdrive() {
	eject_bottomdrive && sleep 2
	ww bottom_hand_small
	ww bottom_hand_back
	ww top_hand_big
	eject_topdrive && sleep 2
	retrieve_bottomdrive
	ww top_hand_back
	retrieve_topdrive && sleep 2
	[ $DEBUG -eq 1 ] && echo "Bottom drive $BOTTOMDRIVE is loaded"
}
remove_disc_topdrive() {
	ww top_hand_back
	eject_topdrive && sleep 2
	ww top_hand_small
	ww top_hand_back
	retrieve_topdrive
	[ $DEBUG -eq 1 ] && echo "Disc removed from top drive $TOPDRIVE."
}
remove_disc_bottomdrive() {
	ww bottom_hand_back
	eject_bottomdrive && sleep 2
	ww bottom_hand_small
	ww bottom_hand_back
	retrieve_bottomdrive
	[ $DEBUG -eq 1 ] && echo "Disc removed from bottom drive $BOTTOMDRIVE."
}

demo() {
	echo "executing $0 load_topdrive"
	load_topdrive
	echo "Simulating writing data to disc in top drive"
	sleep 5
	echo "executing $0 load_bottomdrive"
	echo "Loading disc from top drive to bottom drive"
	load_bottomdrive
	echo "Simulating labeling disc in bottom drive"
	sleep 5
	echo "executing $0 remove_disc_bottomdrive"
	echo "Removing disc from bottom drive"
	remove_disc_bottomdrive
	echo "Done."
}
if [ -c $DEV -a -b $TOPDRIVE -a -b $BOTTOMDRIVE ]; then
	case $1 in
		demo)
				demo;;
		load_topdrive)
				load_topdrive;;
		load_bottomdrive)
				load_bottomdrive;;
		eject_topdrive)
				eject_topdrive;;
		retrieve_topdrive)
				retrieve_topdrive;;
		eject_bottomdrive)
				eject_bottomdrive;;
		retrieve_bottomdrive)
				retrieve_bottomdrive;;
		remove_disc_bottomdrive)
				remove_disc_bottomdrive;;
		remove_disc_topdrive)
				remove_disc_topdrive;;
		top*|bottom*|1|2|10|13)
				ww $1;;
			*)
				usage;;
	esac
else
	[ $DEBUG -ne 1 ] && rpr "Problem" "Check dud burner's connection"
fi

The above script is the major part of a dvd email archiving application that I have developed recently. With the help of USB Sniffer (current version 1.8) I am able to get those magic control strings. What amazed me is that under Linux, this duplicator doubles as a true robotic dvd archiver — all processes, from generating iso files to light-scribing labels, run ompletely without user interference. The only thing needs to be done is to load empty discs (capacity: 100 discs) and collect them once a while. Basically I use the above script in this way:
1) Generate daily (encrypted) email archive
2) Generate weekly iso’s
3) When iso is ready, burn the iso file on the first tray on the Duplex
4) Use python Image Library to generate a .bmp file with the date-range of the archives as the label for the following step
5) Light-scribe the disc on the second tray with data side faced-up.
6) Disc removed from the second tray into the dvd holder.

This is the bash script that I wrote a while ago to control the Aleratec Roboracer CD/DVD Duplicator under Linux, which is not a supported platform by the manufacturer (standard features such as ejecting burning disks are supported, but not the loading part). Those control strings were obtained using USB sniffer [ http://benoit.papillault.free.fr/usbsnoop/doc.php.en ]. This script became an important part of an email backup application which archives daily emails and burns to the robotic duplicator without user interference.

#!/bin/bash
DEV=/dev/ttyUSB0
SR=`dmesg |awk -F ':' '/scsi3-mmc drive: 48x\/48x writer dvd-ram/{print $1}'`
DRIVE=/dev/$SR

w() {
    echo -e "$1" > $DEV
}

usage() {
    echo "`basename $0` -e    : eject the disc"
    echo "`basename $0` -l    : load the disc"
}

[ -c $DEV ] || echo "$DEV does not exist, please make sure\
 the duplicator is connected" && exit 1
case $# in
    1)
        case "$1" in
            "-e")
                eject $DRIVE
                sleep 1
                #turn handle a small angle
                w !BNKPG93
                sleep 1
                #turn handle back to origin
                w !BNKPH94
                sleep 1
                eject -t $DRIVE
                echo "disc ejected"
                ;;
            "-l")
                eject $DRIVE
                #turn handle a large angle
                w !BNKPB8E
                sleep 1
                #load disc
                w !BNKPH94
                sleep 2
                #turn handle back to origin
                w !BNKDP90
                sleep 2
                eject -t $DRIVE
                echo "disc loaded"
                ;;
            *)
                usage ;;
        esac
        ;;
    *)
        usage ;;
esac

Direct link to the script: http://rc3.fileave.com/robo.sh.
Aleratec Robo Racer

step 1.

mkdir /etc/portage
echo "www-servers/nginx **" >>/etc/portage/packages.keywords

step 2.

emerge nginx

step 3.

mkdir -p /var/www/localhost/htdocs
echo "<h1>Hey it works</h1>" >>/var/www/localhost/htdocs/index.html

index.html is created for testing.

step 3.

vi /etc/nginx/nginx.conf

comment out the first line in server block (or change 127.0.0.1 to the ip you want httpd listens on), without this step nginx will only listens on 127.0.0.1

	server {
		#listen		127.0.0.1;
		server_name	localhost;

		access_log	/var/log/nginx/localhost.access_log main;
		error_log	/var/log/nginx/localhost.error_log info;

		root /var/www/localhost/htdocs;
	}

step 5.

mkdir /usr/logs
touch logs/nginx.lock.accept

[ without this step nginx will fail to start ]

step 7.

/etc/init.d/nginx start

step 8.
To verify nginx is running

pgrep nginx

It should report 2 pid numbers; run

netstat -na|grep :80

to test if the port binding is correct, you should see something similar to

tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN

I was following the instruction from http://www.gentoo.org/doc/en/handbook/handbook-arm.xml?part=1&chap=7 trying to put Gentoo onto my sheevaplug. Everything seems to be functioning except I couldn’t get the login prompt to appear through the usb-serial port, but I was able to ssh to the box though. The complete booting message reads

Press I to enter interactive boot mode

* Mounting proc at /proc ...                                             [ ok ]
* Mounting sysfs at /sys ...                                             [ ok ]
* Mounting /dev ...                                                      [ ok ]
* Starting udevd ...                                                     [ ok ]
* Populating /dev with existing devices through uevents ...              [ ok ]
* Waiting for uevents to be processed ...                                [ ok ]
* Mounting devpts at /dev/pts ...                                        [ ok ]
* Remounting root filesystem read-only ...                               [ ok ]
* Checking root filesystem .../dev/sda1: clean, 194291/1197168 files, 504877/4s
[ ok ]
* Remounting root filesystem read/write ...                              [ ok ]
* Checking all filesystems ...                                           [ ok ]
* Mounting local filesystems ...                                         [ ok ]
* Mounting USB device filesystem (usbfs) ...                             [ ok ]
* Activating (possible) swap ...                                         [ ok ]
* Your TIMEZONE in /etc/conf.d/clock is still set to Factory!
* Setting system clock using the hardware clock [UTC] ...                [ ok ]
* Configuring kernel parameters ...Unknown HZ value! (80) Assume 100.
[ ok ]
* Updating environment ...                                               [ ok ]
* Cleaning /var/lock, /var/run ...Unknown HZ value! (79) Assume 100.
[ ok ]
* Wiping /tmp directory ...                                              [ ok ]
* Device initiated services: udev-postmount
* Setting hostname to sheevaplug ...                                      [ ok ]
* Loading key mappings ...                                               [ ok ]
* Setting terminal encoding to UTF-8 ...                                 [ ok ]
* Setting user font ...                                                  [ ok ]
* Starting lo
*   Bringing up lo
*     127.0.0.1/8
[ ok ]
*   Adding routes
*     127.0.0.0/8 ...                                                    [ ok ]
* Starting eth0
*   Bringing up eth0
*     192.168.1.59/24
[ ok ]
*   Adding routes
*     default via 192.168.1.1 ...                                         [ ok ]
* Initializing random number generator ...                               [ ok ]
Unknown HZ value! (85) Assume 100.
INIT: Entering runlevel: 3
* Starting syslog-ng ...                                                 [ ok ]
* Mounting network filesystems ...                                       [ ok ]
* Starting sshd ...                                                      [ ok ]
* Starting vixie-cron ...                                                [ ok ]
* Starting local ...                                                     [ ok ]
Unknown HZ value! (86) Assume 100.

[ System is ready at this point, but the login prompt just can't show up; I am able to ssh to the box though. ]

I haven’t found any solution (tried re-installing procps as suggested by some posts but it didn’t help) yet to this problem. I also tried the vinilla-sources-2.6.30.1 kernel, but the problem remains the same. Maybe it’s time to file a bug report with Gentoo.

Edit [ July 6th, 2009 ]:
Today I solved half of the problem, the reason why I couldn’t get a login prompt through the serial port is line #39 in /etc/inittab

s0:12345:respawn:/sbin/agetty 9600 ttyS0 vt100

After change that line to

s0:12345:respawn:/sbin/agetty 115200 ttyS0 vt100

I finally had the login prompt appear as it should.

Older Posts »