Theju's tryst with life

Use the Windows key as Ctrl Key on Linux

The Ctrl key on the Samsung R517 laptop is placed awkwardly for comfortable use with Emacs. Off late due to the strain of hitting the Ctrl key often, I started to feel a mild tingling on my pinky. I was anxious if this was the first stage of the infamous Emacs pinky. So I started looking for ways of reducing the pain and I came across a beautiful article by Steve Yegge on Effective Emacs. If you wish to become a power Emacs user, then you ought to read it. This article came as a real blessing in disguise and I hope my post might be useful to some other soul.

The article actually recommends swapping the Caps Lock and the Ctrl key. But as a fairly frequent user of the Caps Lock key, I did not like the idea and hence decided to swap it with the 'vestigial' Windows key. This is fairly simple process on Linux. Here's how I went about it...

  1. Figure out the key code of the windows key. Linux comes with an X utility called 'xev'. After firing that utility, I pressed the windows key several times and noted down the key symbol and key code. In my case, they were "Super_L" and "133".
Keycode identification using xev
  1. Map the key using 'xmodmap'.
keysym Control_L = Super_L
keycode 37 = Control_L
remove mod4 = Super_L
add Control = Control_L Control_R Super_L

What the code above does is that it first assigns the left control to the windows key and deassigns the left control. But we want an additional control key instead of deassigning it. So we take the key code of the left control as mentioned in Step 1 and reassign it to the Control_L key symbol. We then, remove the Windows key from the modifier group called 'mod4'. The 8 modifier groups are Shift, Lock, Control, Mod1, Mod2, Mod3, Mod4 and Mod5. These modifier groups hold a collection of keys for a specific action. For example, by default the Caps Lock is part of the Lock modifier. Suppose, you add another key to this group, you can make it function like a Caps Lock. This is the basis for the last line, where I wish to use the Left Control, Right Control and Windows key as control keys.

  1. Add the above xmodmap file to your bashrc (or bashrc_profile depending on your distro)
source path/to/the/above/xmodmap/file

May the power of Emacs be with you!

Writing a keylogger in Linux is very easy!

I strongly believe that an employer shouldn't monitor an employee's usage of internet and computing resources at work. But when the employer has circumstantial evidence to prove that an employee is using computing resources to benefit a competitor, then it is a different matter altogether.

Recently, my cousin requested me to write a keylogger after he got a call from a regular customer who had received a bid from a competitor for a project whose quotes were only emailed to his company. After a little investigation, he learnt that some employees created a similar looking email address (just missing a period (.)) and were diverting order enquiries. My cousin wanted to get the password of this new email address and the names of all employees who were defrauding the company. His decision to migrate all the company machines to Linux nearly 6 months back played to my advantage!

I wrote a simple keylogger in C++ mainly because I wanted to learn C++ and it would perform better without loading the CPUs. Let me make it very clear, that I am comparing python against C++. I still love python!

In Linux, every device is a file. So even the keyboard can be accessed just like any ordinary file. I made use of the generic input drivers for X.org (evdev) to log the keystrokes into a file and another small utility to decode these keystrokes.

These utilities were cronned and sent the output by email.

No prizes to guess what happened to the employees and that email address!

The code is fairly simple and rudimentary. It is available at github. I plan to refine the code further based on requests. So if you require some help, please contact me.

PS: I would like to dedicate this code to my colleague at Citi and friend, Sunwoo Park. He taught and cleared doubts I had about C++ over IM!

Split a large CSV into smaller CSVs

At work, we sometimes have to deal with huge CSV files and it is difficult to open these files in memory because there is a limit of the buffer size.

So the best way would be to split the file into smaller chunks so that they can be easily read.

So here is the bash script that does the job (split_csv):

#!/bin/bash

num_lines=$1
num_digits=$2
input_file=$3
output_pattern=$4

split -d -l $num_lines -a $num_digits $input_file $output_pattern

i=0
while [ $i -lt $num_digits ]
do
  if [ $i -eq 0 ]
  then
    idx=0
  else
    idx="0$idx"
  fi
  i=$(( i+1 ))
done

first_file="$output_pattern$idx"

header=`head -1 $first_file`

for i in $( ls $output_pattern* )
do
  if [ "$i" != "$first_file" ]
  then
    echo $header | cat - $i > temp_file
    mv temp_file $i
    rm -rf temp_file
  fi
done

A simple usage would be:

split_csv 10000 3 input.csv test-

The usage is similar to that of the split utility.

Install Fedora from a USB disk without a DVD

Fedora has a release schedule of 6 months ie they release a new version every 6 months. 6 months is too short but there are a lot of new features that are packed into every release that it makes it very tempting to upgrade or re-install the new version.

Till recently I used to burn the ISO images that I downloaded from the torrents onto a DVD and install. After that the DVD was virtually useless. I tried using DVD-RWs but I felt that it was a waste of time especially when cheap high-capacity USB disks are easily available.

I searched around for a solution and found a promising post on the Fedora Forum.

I am writing it for my personal archival reasons but if you find it useful please send a thanks mail to the poster (sideways).

The solution works if you are using Fedora only but shouldn't be difficult to tailor for other distros.

First install the livecd-tools package that gives us the ability to create custom livecds from the images.

# yum install livecd-tools

Then you mount the Fedora ISO image that you downloaded onto a directory and copy the boot.iso to your USB disk. Remember to keep your USB disk in an unmounted state.

# mkdir /mnt/iso
# mount -o loop <path to>/Fedora-10-i386-DVD/Fedora-10-i386-DVD.iso /mnt/iso
# livecd-iso-to-disk /mnt/iso/images/boot.iso /dev/sdb1

Mark your USB disk as bootable.

# /sbin/parted /dev/sdb
(parted) toggle 1 boot
(parted) quit

Next mount your USB disk and copy the install.img file to your USB disk.

# mkdir /media/<usb disk>/images
# cp /mnt/iso/images/install.img  /media/<usb disk>/images/
# cp <path to>/Fedora-10-i386-DVD/Fedora-10-i386-DVD.iso /media/<usb disk>/

That's it...just boot off your USB disk (older motherboards might not support this feature). When you are asked for the location of the installation files point to Hard-disk and then to your USB disk.

Voila...you can easily install off the USB disk. No need to waste a DVD and you can do your bit for the environment by reducing garbage.

All credits go to Sideways for this fantastic method.

Handle ACPI events in Linux

Off late, I have been working totally in runlevel 3 to replicate the setup and feel at work. The only grudge I have with runlevel 3 is that there is no easy way to figure out the battery level of the laptop.

So I googled around and realized that ACPI was the answer to my question.

To figure out all the statistics that are related to ACPI, /proc/acpi is the place to head.

So to check the battery power level all one has to do is read the /proc/acpi/battery/BAT0/state file and it gives all the necessary statistics.

Later I realized that it would be wonderful if I was able to handle events like battery fully charged, battery level low, laptop lid closed etc. This too is handled by ACPI.

I dug around this topic deeper and could not come up with a decent solution. Some suggested looking around the ACPI kernel module. I tried this but could not get it to work.

Then I read about the acpid daemon that runs in userspace and listens to various ACPI events and runs user-defined scripts when a particular ACPI event is triggered. The man page for acpid is really helpful and gives all the required info on events and how to handle them.

Here is an example script that I use to trigger events when the battery is fully charged and when the battery level reaches the pre-defined alarm level.

In /etc/acpi/actions/

#!/bin/sh

# /etc/acpi/actions/battery.sh

PATH=/sbin:/bin:/usr/bin:/usr/local/bin

alarm_level=`cat /proc/acpi/battery/BAT0/alarm |awk '/^alarm/ { print $2 }'`
remaining_capacity=`cat /proc/acpi/battery/BAT0/state|awk '/^remaining/ { print $3 }'`
last_full_capacity=`cat /proc/acpi/battery/BAT0/info|awk '/^last/ { print $4 }'`

if [ $remaining_capacity -eq $alarm_level ]
then
  # Send an email
  # or play a tone or do whatever
  mplayer /home/theju/tones/battery_low.ogg
fi

if [ $remaining_capacity -eq $last_full_capacity ]
then
  mplayer /home/theju/fully_charged.ogg
fi

In /etc/acpi/events/battery.conf

event=battery/*
action=/etc/acpi/actions/battery.sh

For Thinkpad owners, there is a very good wiki article on Thinkwiki that also gives various other things you could do with ACPI.

The number of posts are 13. The number of pages are 3. Next