TTY Keystroke Injection using Perl

One of my current projects deals with a program that gathers input from a mag strip reader, which emulates a USB attached keyboard. As a result, the program needs to run inside an active shell on the machine. Know, I know there are other possible methods such as capturing the keyboard input by way of custom drivers for the device, but that’s a challenge for another day. I needed to occasionally shutdown the program and start it back up in the original tty session. Of course you cant simply stop and start it via restart script scheduled in cron because when it starts back up, the process will be headless and not capture any keystrokes sent to the active tty. What I needed is a way to send keystrokes to the active tty session.

My solution, TTY Keystroke Injection.

Here is a perl one liner to send one character. I found this online.

$ sudo perl -e '$TIOCSTI = 0x5412; $tty = "/dev/pts/3"; $char = "A"; open($fh, ">", $tty); ioctl($fh, $TIOCSTI, $char)'

The downside of the above command is it only sends a single character at a time (in the example, the A will get sent to /dev/pts/3). So… I wrote a simple perl script allowing me to conduct keystroke injection, passing in a full command, into a different session.

# tty keystroke injection
# version 1.2
# Richard

use Getopt::Long;
my $tty; # The tty session we are about to send keys to
my $command; # The command we are about to send to the target tty

GetOptions ("help|?" => sub{usage(0);}
	       ,"tty=s"  => \$tty
	       ,"cmd=s"  => \$command) or usage (1);

if($tty eq ''){
	print 'ERROR: You must specify a target tty session' . "\n";
if($command eq ''){
	print 'ERROR: You must specify a command' . "\n";
# Questions on how to get the correct value for $TIOCSTI
# is discussed here :
my $TIOCSTI = 0x5412;
# Open a connection to the TTY
open(TTY,">$tty") or die "ERROR: Cannot open $tty\n";
# Split the command into single characters
my @command = split("",$command . "\n");
# Sleep a second to make sure the key gets sent
# Loop the arry and send the key to the target TTY
foreach $arr(@command){
print "Command: $command\nSent to $tty\n";

sub usage{
  my $err = shift and select STDERR;
  print < -cmd 
    -tty   -> The dev path to the targeted tty session
                                  To get a list of active tty session you can use the "w" command
                                  or use the command "tty" to see what your current tty session is
    -cmd      -> This is the command to pass to the target tty session
  exit $err;

To execute the program simply pass the target tty device and the command you want to execute.

$ sudo perl ./ -tty /dev/pts/2 -cmd 'ls -al'

Arduino Powered Mum

Living in Texas, you can’t escape the craziness around the Homecoming Mum tradition. The tradition started in the 1960′s with boys giving their homecoming dates chrysanthemums lightly decorated with ribbons. However, as with all things in Texas, the bigger the better. Our son is a freshman now and it’s our turn to partake in the Mum tradition. Being a maker, I wanted to do a little more than simply combine silk flowers and ribbon. I wanted to make the Mum shine. Shine… Arduino and RGB LEDS! Challenge accepted.

Information on how to build this Mum can be found here:

Squeaky Steel Case Jersey Chair… Fixed!

Our offices recently underwent a major renovation. Part of the change was the arrival of new Steel Case Jersey chairs for our work areas.

Steel Case Jersey Chair

The chairs themselves are adjustable in several areas and quite comfortable. However, by the time the newness wore off the squeaking started. The slightest movement such as leaning back or forward caused an ear piercing squeak to emit from the underside of the chair. As time progressed, you could hear squeaking throughout the entire floor. At times it was quite comical; however, most of the time it simply annoying.

The fix:

To stop the squeak find yourself a bit of lubricant such as WD-40 or white grease. Flip the chair over on its right side and look for the Seat Angle adjusting lever.

Steel Case Jersey Underside

The lever goes into the underbelly of the chair. The squeak is coming from where that lever is riding up and down on the underbody frame. You can see in the photo below how the paint has worn away and now its bare metal rubbing on metal.

Apply the lubricant on that spot and your done!

Don’t have any lubricant handy, for a temporary fix, use a post-it note and wrap it around the lever like this.

Other ideas to create an anti squeak buffer are velcro, felt feet, or masking tape.

Now we can work in peace and quiet!

Building a Word Clock

I was recently asked if I could build a Word Clock. Of course, not wanting to back down from a challenge (and a bit of research) I said “yes”. One of the objectives of this build, aside from producing a quality product for our client was to document the build and share with the community.

After a bit work, I present to you, the Javelin Word Clock.

Check out this video a co-worker put together. I think he did a great job.
Want one? You too can build this same clock by following my Instructables documentation here:
Let me know what you think.

PostgreSQL parsing paths

I’ve been working on a project dealing with file paths inside our PostgreSQL databases and came across a situation where I wanted to parse out the file name from a path. As with everything code related, there are several ways to accomplish the task at hand.

Here are the three easiest methods I’ve came up with.

SELECT '/path/to/my/file.txt' AS str_path
  ,REGEXP_REPLACE('/path/to/my/file.txt', '^[^*?"<>|:]*/','')

And now for a breakdown of each method.

REGEXP_REPLACE('/path/to/my/file.txt', '^[^*?"<>|:]*/','')

The first method is the most simple method (and fastest). It uses regex to find and replace everything but the last element in a path with empty space (‘’).


The second method finds the last element (the reverse of the first method). The function REGEXP_MATCHES returns a PostgreSQL array so we use the ARRAY_TO_STRING function to convert the array to a string.


This third method is probably overkill but it may be useful if you can’t seem to get a regex expressions to work. The method uses REGEX_SPLIT_TO_ARRAY to split the string into an array. Then using the ARRAY_UPPER function we find out how many elements are in the array. This value is then passed to the SPLIT_PART function , telling it which element we want returned.

Keep in mind that with each of the methods above you can always replace the delimiter with your own search criteria to come up with fun and exciting ways to pull out that gem of information from a string!

Create Online KVM Backups

Running eCommerce sites, downtime is considered a bad deal… at the same time, not having backups is even worse. Here is a simple script that I’ve put together to execute an online backup (not a snapshot) of a Virtual Machine managed by KVM without having to shut down the VM.

Create a new file.


And copy and paste the following code.


function backup_snapshot {
  if [ `qemu-img info $filename.qcow2 | grep  --count "file format: qcow2"` -eq 1 ] then
    echo "Backing up $filename"
    # create the snapshot
    if [ $debug -eq 1 ] then
      echo "Creating snapshot"
    qemu-img snapshot -c $date $filename.qcow2
    #copy the snapshot out
    if [ $debug -eq 1 ] then
      echo "Converting snapshot to standalone qcow2 file"
    qemu-img convert -c -f qcow2 -O qcow2 $filename.qcow2 $filename-$date.qcow2
    #delete the old snapshot
    if [ $debug -eq 1 ] then
      echo "Deleting snapshot"
    qemu-img snapshot -d $date $filename.qcow2
    echo "Snapshot backups only support qcow2 files"
date=`date +%d%m%Y`
filename=`echo $1 | sed s/.qcow2//`
backup_snapshot $date $filename

Exit vi, saving the script.

Now make your script executable.

$chmod +x

To run the script pass it the name of your VM.

$./ /path/to/your/vm/hostname.qcow2

From my experiance, the performance impact to the VM is fairly minimal.

Hope this helps.

Raspberry Pi Slideshow

Wanting to do something productive with my Raspberry Pi, I decided to at least get it showing me new art each day. As it turns out… its a little more challenging than I had originally expected. The main reason was resources on the Pi. Many image viewers, both command line and x windows based like to do some crazy things that tend to blow up the memory consumption on my Raspberry. As a result, the kernel will, in turn, enjoy killing the offending process. The following is how I overcame the challenges.

The Equipment:
Raspberry Pi running Raspbian “wheezy” on a 4GB SD Card
HDMI Monitor
An Internet connection

The Overview:
The idea is to get updated images from Deviantart nightly and display them via slide show over the course of the day.

The Steps:
With a fresh install of Raspbian I booted up the Pi. The initial wizard gives you a few options, here is what I did.
1. Expand the root partition to fill the SD Card
2. Changed the keyboard to the US layout
3. Changed the timezone to reflect where I live
4. Changed the boot into desktop to yes (meaning it will start the desktop after boot).
5. As a matter of security, I also updated the password for the pi user.

Reboot the Pi and you should find yourself looking at the desktop once you log in.

Add Auto Login:
You can skip this part if you don’t want to auto login, it wont affect the outcome unless you reboot your machine.
Making this as automated as possible, we need to set up the Pi to auto login the pi user. Here’s how we do that.

Edit /etc/inittab using vi. Of course vi is just my preferred text editor, feel free to use your own favorite. I’ve heard quite a few people like nano.

sudo vi /etc/inittab

Scroll down till you see the following line:

1:2345:respawn:/sbin/getty --noclear 38400 tty1

Comment it out by adding a pound sign (#) in front of it. Insert a new line and add the following.

1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

Your file should now look something like this:

#1:2345:respawn:/sbin/getty --noclear 38400 tty1
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

NOTE: If your using a user different than ‘pi’ you will want to change the user, pi, to your user.

Close and save the file.

Go ahead and reboot your Pi just to make sure your changes have properly taken affect.

sudo shutdown -r now

Update and Install pqiv
Once the machine comes back up, it should automatically boot you into LXDE (the default desktop environment). Go ahead and open a terminal window and update the apt-get repository.

sudo apt-get update

Normally we would issue a simple apt-get install pqiv to install pqiv; however, due to issues with version in the raspbian repository we will need to download, fix, compile, and install pqiv manually. Don’t forget to remove pqiv if you’ve already installed it at some point.

sudo apt-get remove pqiv

Install git and the dependency gtk2 library for pqiv.

sudo apt-get install git libgtk2.0-dev

We have what we need to build the application, now we need to download the source.

git clone -b 0.12

Now that you’ve downloaded the pqiv source, you will notice a new directory in your home directory called pqiv. Go into this directory and run ./configure to validate all preconditions are met and create a platform specific make file.

cd pqiv

Now we need to fix the source code by replacing the gchar option; with gint option; in the main() function in the pqiv.c file. The line we are looking for is around 2233.

/*gchar option;*/
gint option;

Save and exit vi. Now you’ve fixed the bug, we will run make and install the application.

sudo make all install

You now have the fixed version of pqiv running on your Pi.

Get the slide show images:
Now we need to create the process to download the images from Deviant art. To do this, first create a directory in your home directory. Open a terminal session and type in the following commands.

mkdir images
mkdir scripts
cd scripts

Now we need to create the script to get the images from DeviantArt. Create a new file in the scripts directory.

vi ~/scripts/

Inside the script copy and paste the following code.

NOTE: Updated wget line to adapt to the change in RSS format from Deviantart.


cd /home/pi/images

rm *.jpg *.png

# go get the files
#landscape files
wget -q -O- "" | grep -o '<media:content url="[^"]*' | grep -o '[^"]*$' | xargs wget -c


for f in $FILES
    file -b $f
    echo "Checking file number $count"
    count=$(($count + $one))
    if [ "$(file $f|grep JPEG)" ]; then
      mv ${f} $RANDOM.jpg
    elif [ "$(file $f|grep PNG)" ]; then
      mv ${f} $RANDOM.png
    elif [ "$(file $f|grep ASCII)" ]; then
      echo ”Skip Script file”
      echo "unknown file type $f"
Once you've added the script, save your file and make it executable.
chmod +x ~/scripts/

Just to be sure your script is working execute it via the command line.

cd ~/scripts

So… whats this script do you might ask? For starters, using wget, it reaches out and pulls down images from DeviantArt via their RSS feeds. Using grep and sed we save the resulting downloaded file to the images directory. The second part of the script looks at all the files downloaded (some of them end up not being images) and gives them random file names. These random file names are what make the slide show seem a little more “random”.

But we want this pull to be a automated. To do this we add the script to cron. To edit cron:

crontab -e

And then add the following line at the end of the file.

00 01 * * * /home/pi/scripts/ > /home/pi/get_images.log 2>&1

The line above kicks off your script every night at 1:00 am and outputs both output and error to a log file in the home directory of pi. (this is really only to help with troubleshooting if needed).

Slide show Image Swapping
Next we need to create a set of scripts to refresh the slide show file and make sure the slide show continues to run.

First up is a really simple script to continually refresh the slide show image. Create a new script file in your scripts directory.

cd ~/scripts

Copy and paste this script into your new file.


cd /home/pi/images
while true;
  do for i in *;
    do cp $i /home/pi/slideshow.jpg;
      echo $i;
      sleep 30;

Save your file and make it executable.

chmod +x

Here is a quick outline of what the above script does.

It first changes its current directory to the images directory. Once there, it goes into an infinite loop. Once inside the loop it gets a list of files from your images directory. It then copies the first file to your home directory calling the file slideshow.jpg. The script then waits 30 seconds and then copies the second file, overwriting the existing slideshow.jpg with this new one. The script will do this for each file until it goes through all of them. Then it starts from the begging and does it all over again. At 1:00 am the get_images script will download a new set of images and because the update_slideshow_image get a new file list each time it loops, these new files will get added to the list to be displayed. This may not make much sense now, but it will after in a moment.

Using pqiv to display images:
Now we need to create the script to display the images.

cd ~/scripts

Copy and past this script into your new file.


# Lets start and restart the slideshow if needed
until /usr/bin/pqiv -i -f -s -w /home/pi/slideshow.jpg; do
  echo "Slideshow crashed with exit code $?. Restarting..." >&2
  sleep 2

Save your script and make it executable.

chmod +x

This script is really quite simple. Most of the actual slide show work is done by pqiv. This script’s only duty is to kick off pqiv. If the program crashes the script will echo the reason it crashed and then wait a few seconds before restarting the slide show. Why do I do this you might ask? Memory resources on a Raspberry Pi are limited and image viewing software isn’t all that great at being memory friendly, especially when trying to load larger files, scale them, and then display them. Do that over a hundred times and you will quickly get killed by the kernel.

As a side note, I tried several other image viewing programs like fbi, fim, and feh. While they worked, they each had some small issues and more importantly, they were not fond of refreshing the image when the underlying file changed.

Autostart the slide show:
To have our slide show kick off automaticly once the Pi reboots. To do this we need to add two .desktop files to autostart. One file will run our update_slideshow_image script that the other will run the start_slideshow script.

Here is how you create the first file.

cd /etc/xdg/autostart
sudo vi slideshow_image_changer.desktop

Inside this file add the following.

[Desktop Entry]
Name=Slideshow Image Changer
Comment=Slideshow Image Changer

Save this file and create the second file.

sudo vi slideshow_start.desktop

Add the following to this new desktop file.

[Desktop Entry]
Name=Slideshow Image Changer
Comment=Slideshow Image Changer

Save and close this file.

Prevent the Raspberry from going to sleep:
We are almost done… one thing that drove me nuts for a little while was how the Raspberry would occasionally turn off the monitor. I couldn’t really narrow down what I did to fix the issue. I updated the following config settings and they seem to work as expected.

Update the kbd config file.

sudo vi /etc/kbd/config

Scroll down till you see the BLANK_TIME setting and change it to 0.

# screen blanking timeout. monitor remains on, but the screen is cleared to
# range: 0-60 min (0==never) kernels I've looked at default to 10 minutes.
# (see linux/drivers/char/console.c)

Scroll down a little more till you see the POWERDOWN_TIME setting and change it to 0

# Powerdown time. The console will go to DPMS Off mode POWERDOWN_TIME
# minutes _after_ blanking. (POWERDOWN_TIME + BLANK_TIME after the last input)

Save and close the config file.

Next I ended updating the lightdm.conf file.

sudo vi /etc/lightdm/lightdm.conf

Scroll down till you see the [SeatDefault] section and add a line towards the end of it.

xserver-command=X -s 0 dpms

My screen no longer goes blank and I have the pleasure of having a dynamic slide show all day.

Reboot your Raspberry Pi. Provided everything goes as planned, your slide show should start shortly after booting into the LXDE desktop… congratulations!

Using Perl to communicate with Single Line LED Sign



I recently inherited a single line LED sign made by SuperViewVision, Model Number SVV-ML-80X7-RG, and my first thought was “Great! I can stream cool stuff to the sign like tweets”. To my dismay the sign came with windows only software and little documentation. On top of that there was no easy method to programmaticly update the display. Each change to the message had to be done manually. I search for several days looking for protocol documentation. In the product description there is a blurb about protocol documentation available upon request. So, I attempted to communicate with the vendor asking for documentation. The vendor’s response was less than helpful. Evidently they sell the sign but allow resellers to re-flash the sign with their own protocols so they wanted to know the date I bought the sign and who I bought it from. This was information  I wasn’t privy to due to my method of acquiring the sign. After searching I started to get the feeling the sign was really old or its simply not used as often as other signs using some of the more main stream LED sign protocols because I couldn’t find anything!

The stage was set, the challenge clear. I was going to map out the protocol for the sign and use a perl script to communicate with it.

To understand how the sign communicated I used a windows serial port sniffer and started logging commands sent to the sign. As it turns out the protocol is a two (or more) step process. A wakeup signal followed by the command(s). Something like this:

PORT_WRITE -> ~128~
PORT_WRITE -> f01A\Y1\Z4\a\sHello World\r\r\r

To help you out, I’ve built a small perl script to help. Click here to download the perl script. I suggest renaming it from .txt to .pl If your running on a linux machine (like me) you will have to make the script executable before trying to run it.

Here is the usage syntax.

usage: perl --port=/dev/ttyS0 --signid='~128~' --info 'info message' --alert 'alert message' --update 'update message' --setDTM
       --port   '/dev/ttyS0'     Define the port the sign is connected to. Defaults to /dev/ttyS0
       --signid '~128~'          Define the sign ID. Defaults to ~128~
       --info   'info message'   Post the string using the default format (bright green default size)
       --alert  'alert message'  Post the string using the alert format (flashing ALERT and scrolling in bright red)
       --update 'update message' Post string using the update format (flashing UPDATE and scrolling in bright yellow)
       --showDTM                 Will add the current date time to the message displayed
       --setDTM                  Updates the sign with the current date and time

The --info, --alert, and --update are all pre configured displays but you can pass any kind of slash command to send any combination of cool things. Here is an example of passing both an --alert and --info with some embedded embellishments.

perl --port=/dev/ttyS0 --signid='~128~' --info 'Conns db1:\c12\h db2:\c12\h \rC\Y1\h\sServers:\c48\h Up:\c39\h Down:\b2\h \rC\Y1\h\scan you can a can as canners can a can' --alert '\djavtableau\b is NOT responding to ping!'

Now that I had a simple command line interface I built a script (not documented here) to pull my environment health and statistics every few minutes and update the sign.

Something else about the script, I havn’t tested it on a windows machine but I bet if you update the USE statement to point to the Win32::SerialPort module it should work.

That’s about it… each of the modes and other effects are further documented inside the perl file.

[FIXED] Android DNS not working with WIFI

So I finally upgraded my wireless access point from a G device to a new shiny N device. The Cisco Linksys E1200 to be specific. When I did this change I had several of my Android based devices unable to brows or pull up any type of internet based services (news, stocks, facebook, oh my!). After several attempts to tweak my wireless settings, at one point I event completely turned off security to no avail. I then noticed that I was able to pull up websites via IP but not domain name. Ah ha! DNS. So evidently DNS via wifi is a semi known issue with routers that are not configured to allow some sort of open DNS and Fully Qualified Domain Names (FQDN). To be honest I only vaguely understood what the problem was… only to the point were I knew that my router simply wasn’t going to work regardless what I did to it (besides replace it with a new one).

That left the Android devices to be tweaked. Despite the router passing the DNS servers to the device as part of the IP settings when a connection is established it wont use DNS servers (again related to the FQDN and some other Router magic). So what I ended up doing ultimately is downloading and installing Set DNS. However what do you do if you cant even open Google Play (Marketplace) if you cant resolve anything? Here are the steps that I took to get to the point of being able to connect and brows.

Its worth noting that you must have Super User (su) rights on the devices (in other words you must have root access).

Method 1

Update the /system/etc/resolve.conf

If you already have resolv.conf you simply need to add your favorite DNS servers via command line like this..

# su
# mount -o remount, rw /system
# echo "nameserver" >> /system/etc/resolv.conf
# echo "nameserver" >> /system/etc/resolv.conf

If there is not a resolv.conf in your /system/etc then you need to create one.

# su
# mount -o remount, rw /system
# echo "nameserver" > /system/etc/resolv.conf
# echo "nameserver" > /system/etc/resolv.conf

Now you need to set the permissions on the resolve.conf to rw-r-r-

# chmod 4755 /system/etc/resolv.conf

Reboot your phone and try to connect to your favorite wifi access point and brows the web.

Method 2

Update the /system/build.prop

Before you can update the build.prop file you will have to make the filesystem writable. Just like in method 1 fire up a command line interface and remount the /system filesystem.

# su
# mount -o remount, rw /system

Using your favorite text editor edit the file.

# vi /system/build.prop

Once you are inside the file editing it, here is the section I added at the bottom of the file.

# Added by Richard
# Google DNS Tweak

Save the file and reboot your device. Once its up try to pull up your favorite site via the browser or check out the Google Play store. If your updates took place properly you might even see an increase in performance.

Its working? Great! Now go download Set DNS. It makes updating DNS settings so much easier.

My Codeing Standards

In computer programming, a naming convention is a set of rules for choosing the character sequence to be used for identifiers which denote variables, types and functions etc. in source code and documentation.

Reasons for using a naming convention

•to reduce the effort needed to read and understand source code
•to enhance source code appearance (for example, by disallowing overly long names or abbreviations)

Here are some of the benefits obtained by adopting a common naming convention:

•to provide additional information (i.e., metadata) about the use to which an identifier is put
•to help formalize expectations and promote consistency within a development team
•to enable the use of automated refactoring or search and replace tools with minimal potential for error
•to enhance clarity in cases of potential ambiguity
•to enhance the aesthetic and professional appearance of work product (for example, by disallowing overly long names, comical or “cute” names, or abbreviations)
•to help avoid “naming collisions” that might occur when the work product of different organizations is combined
•to provide meaningful data to be used in project handovers which require submission of program source code and all relevant documentation and to provide better understanding in case of code reuse after a long interval of time

Business value
Although largely hidden from the view of most business users, well-chosen identifiers make it significantly easier for subsequent generations of analysts and developers to understand what the system is doing and how to fix or extend the source code for new business needs.

For example, although the following:
a = b * c;
is syntactically correct, it is entirely opaque as to intent or meaning. Contrast this with:
dblWeeklyPay = dblHoursWorked * dblPayRate;
which implies the intent and meaning of the source code, at least to those familiar with the underlying context of the application.

Commented code helps future generations of developers easily understand what sections of code are supposed to be doing. Using comment blocks native to the language make note of the major function of the following few lines as well as outline expected input and output (if applicable). Believe it or not commenting your code will help you too.
# # This program will check the current Q for any old items # checkActiveQ # Function that will look up items in the Active Q sub checkActiveQ{ # Code here … }

Variables should be prefixed to indicate their data type. Optionally, especially for large programs, the prefix can be extended to indicate the scope of the variable. The body of a variable or procedure name should use mixed case (CamelCase) and should be as long as necessary to describe its purpose. In addition, function names should begin with a verb, such as initNameArray or closeDialog.

For frequently used or long terms, standard abbreviations are recommended to help keep name lengths reasonable. In general, variable names greater than 16 are considered too long.

When using abbreviations, make sure they are consistent throughout the entire application. Randomly switching between cnt and Count within a project will lead to unnecessary confusion.

Variable Data Types

Use the following prefixes to indicate a variable’s data type.

Data type Prefix Example
Boolean bln blnFound
Byte byt bytRasterData
Collection object col colWidgets
Currency cur curRevenue
Date (Time) dtm dtmStart
Double dbl dblTolerance
Error err errOrderNum
Integer int intQuantity
Long lng lngDistance
Object obj objCurrent
Single sng sngAverage
String str strFName
Variant var varCheckSum

Using CamelCase
Indicate word boundaries using medial capitalization (also called “CamelCase” and many other names), thus rendering “two words” as either “twoWords” or “TwoWords”.



Indentation rules (most coding standards impose) really contradict
rules of good writing,
the way people perceive information,
and the grammar rules.
Making things (that group naturally, but not syntactically) inside
parenthesis also contradicts how texts are usually typed.
If (you try to type text that way)
you’ll face misunderstanding even (if programmers read you)
your text will be easy to read,
and your writing will be productive

If you have questions or comments let me know by posting a comment.