This really shouldn’t have taken me as long as it did to figure this out, but it was a big enough of an annoyance that I decided to share it.

How to convert a relative path to an absolute path in linux/unix/bash script:

#!/bin/bash
# Assume parameter passed in is an absolute path to a directory.
# For brevity, we won't do argument type or length checking.
echo "Absolute path: `cd $1; pwd`"


For those unaware, you don’t have to ‘cd -’ because the backticks perform command substitution and don’t modify the working directory of the script.

I like to think of snippets like this as an ingredient when cooking with technology. Individual ingredients may be good, but combining them with a recipe yields something far better :)

Gmail has incredible filtering, and I forward most of my older addresses to it to take advantage of its spam filtering capabilities before pulling the messages down to my box. Another cool feature is having the ability to tag messages based on some criteria, such as based on who sent a message. The only thing lacking is the user interface for creating these filters, because it doesn’t make readily obvious how to incorporate multiple addresses into one filter.

I’ve incorporated the knowledge gleamed from a google search on the topic into a Ruby script that takes multiple addresses in and returns a filter string that will work with gmail filters. I hope someone else finds it useful! (download)


#!/usr/bin/ruby -w
#
# Gmail supports filters, but the interface provided doesn't make it appear
# to support filtering multiple addresses at the same time. It does,
# and given multiple addresses, this script will return a filter string
# that matches multiple sources.
#
# Author: Robert Peaslee
#

if $*.length < 3
        p "Usage: filters.rb   ..."
        exit( 1 )
end

case $*[0]
        when "from"
                # Get rid of first element
                $*.shift

                string = "from:("
                $*.each { |addr|
                        string << "#{addr}) OR from:("
                }
                string.slice!( -8, string.length )
                p "Copy this into the filter:"
                p "#{string}"
                exit( 0 )
        when "to"
                # Get rid of first element
                $*.shift

                string = "to:("
                $*.each { |addr|
                        string << "#{addr}) OR to:("
                }
                string.slice!( -8, string.length )

                p "Copy this into the filter:"
                p "#{string}"
                exit( 0 )
        else
                p "Please supply either from or to as the first argument."
                exit( 1 )
end

The attendance database project I’ve recently written about requires the use of iButtons for verifying the physical presence of members at meetings. Having never worked with either the hardware other than as a user of it nor the software SDK in any capacity, it was a learning experience. One thing I quickly ran across when developing the software to locate a plugged-in adapter and read the iButton’s ID was the incredible amount of time it took to enumerate through the available ports just to find a connected adapter. The SDK provided examples on how to go about locating connected adapters, but to improve the speed at which it runs we can take advantage of what we know about the system and exploiting the code’s error conditions.

During installation of the 1-Wire drivers needed to communicate with iButton adapters, you have the option of selecting a default port to which the adapter will be connected. This information is stored as a property the SDK knows how to locate. The first step to increasing the speed of locating an adapter is to use this information – simply check the default port before searching all other ports on the machine. Odds are higher that the adapter is located on that port than any other port on the system, and by placing it as the first check before serially searching all other ports you increase your chances of getting on the first attempt.

The second enhancement requires a bit of background information. The example provided in the SDK shows you how to search all possible adapter types, then all possible ports for that adapter, and print them out. To be useful we would want instead of printing out the adapter and port names to attempt retrieving the device connected there. This would logically be done using the static getAdapter(String adapterName, String portName) method of the DSPortAdapter class. However, the time this method takes to return whether the adapter exists could be measured in seconds. To make this faster using our understanding of the system, we could skip over adapters we know we won’t be using (network adapters, parallel adapters, serial adapters, etc) and avoid scanning for them over all ports entirely. Reducing the size of the problem reduces the time it takes to come to a solution.

That is not all we can do, however. For some reason, if you try to retrieve an adapter using the getAdapter method and attempt to tell if it is successful by comparing the return object against null, it takes a long time. In comparison, the method throws an exception if it cannot locate the adapter much more quickly. Using this last bit of information, by putting a continue statement in your exception catching code you can just skip the attempt to open the obviously unavailable reader and enjoy a nice speed boost.

Here is some example code illustrating what I’ve talked about, excluding rolling over adapters we don’t care about. The speed of this is much faster than my first attempt, from taking around five minutes to locate an adapter to around 30 seconds. Base of code taken from the examples provided in the 1-Wire Java API. Sorry about the indenting, I gave up trying to figure out how to adjust the tabstop!


/**
 * Locate a reader to communicate with.
 *
 * @return boolean - true if adapter was found, false otherwise.
 */
public boolean locateAdapter( ) {
	boolean found = false;
	while( !found ) {
		try {
			DSPortAdapter adapter = OneWireAccessProvider.getDefaultAdapter();
			System.out.println(”Adapter ” + adapter.getAdapterName() +
						” found on port ” + adapter.getPortName());
			this.adapter = adapter;
			this.port = adapter.getPortName();
			found = true;
		} catch(Exception e) {
			System.out.println(”Adapter not found on default port, trying all ” +
					“available to the system…”);
		}
		if( !found ) {
			DSPortAdapter adapter;
			String port;
			// get the adapters
			for (Enumeration adapter_enum = (Enumeration) OneWireAccessProvider.enumerateAllAdapters();
				adapter_enum.hasMoreElements(); )
			{
				adapter = ( DSPortAdapter ) adapter_enum.nextElement();
				System.out.println(”Trying adapter ” + adapter.getAdapterName() );
				// get the ports
				for (Enumeration port_enum = adapter.getPortNames();
					port_enum.hasMoreElements(); )
				{
					port = ( String ) port_enum.nextElement();
					System.out.println(”trying port ” + port );
					try {
						OneWireAccessProvider.getAdapter(adapter.getAdapterName(), port);
						this.adapter = adapter;
						this.port = port;
						found = true;
					} catch( OneWireException owe ) {
						// Just continue…
						continue;
					}
				}
				if( found ) {
					break;
				}
			}
		} 

		if( found ) {
			System.out.println(”Adapter found! Using ” + this.adapter.getAdapterName() +
					” on port ” + this.port );
		} else {
			// Wait 5 seconds before trying again
			try {
				Thread.sleep( 5000 );
			} catch (InterruptedException ie ) {}
		}
	} 

	return found;
}

My Time With Facebook

December 17, 2006

Being one of the millions of Facebook users, I was pretty happy to hear that they opened up a restricted API for those interested in developing applications that interact with it. I found myself with a few hours one weekend, and came up with a simple application using the API to check if you have any Facebook messages. Normally I wouldn’t post a task like this because it was rather trivial, but I decided to anyway because I did it in what I think is a cool way.

First, the actual code to check the messages is written in PHP and hosted on my web server. It will refresh every five seconds and check if you have new messages, displaying an icon to open a new browser window to check the messages. It can be seen here. Notice that I’m much better at writing code than designing interfaces ;) If you are interested, I’m using the official Facebook PHP5 client as a base for the web portion of the application. Full source is here.

The second part of the final application is a program written in C#. It is a small window that fits the dimensions of the used part of that page, using the maximize button to switch between the messages pane and the login pane when required. Internet Explorer is embedded in the application to do the rendering, but is stripped down in terms of navigation and context menu usage. It is still possible to navigate outside of the intended area, but this is a limitation on how Facebook designed it’s login page. The source of the application can be obtained here (zip format) and the executable itself can be obtained here (zip format). The source was built using Visual Studio 2005 – you should be able to build it without complication.

But enough of the program specifics.

Web applications are nice for developers. They develop the application in one place, and the changes are immediate to all users of the software. Feature and security updates are completely transparent, and best of all, the users don’t have to worry about them. Developer liability goes down because users aren’t running around with out of date and possibly insecure versions of their application, and users are happy because they always have the latest version of the software – a win-win situation. Even better, developers don’t have to concern themselves with deciding which operating systems or platforms to develop their primary application for because it is all online. This opens the application to a huge market of people. On the down side, web applications aren’t as accessible to as many people. Most people understand how to click an icon and use a program, it takes a higher level of acceptance to understand, for example, that their web browser could be used to replace Excel. The obvious solution to this problem is what is exemplified in the small application I’ve written to do an overall meaningless task. Embedding a browser in an application allows developers to have a binary executable that the masses are comfortable with that navigates solely to a web application that the developers prefer to maintain. With proper design, the web application can be made to always look good within the client executable, and following some rules of development will prevent people escaping to other sites from within the application. Everyone is happy.

I might expand on the idea later. There are other ways this would be useful, and some other ideas I’d like to tack to the list of supporting reasons for this concept. We’ll see :) It should also be noted that these thoughts originally came out of talking with the very intelligent Mike Manzano in my time working as his intern at Topia Technologies. See Mike, I *was* listening!

First, let me say that figuring out how to do Non-blocking IO in Ruby is a sparsely documented *pain in the ass.* Apparently non-blocking IO is only built into Ruby from version 1.8.4, and even then only through importing fcntl and fighting through making your socket object a non-blocking descriptor. New in 1.8.5 are non-blocking methods for common actions that will handle the descriptor handling for you, making things much nicer.

This all came about because I was writing a port knocking utility in Ruby because I got tired of studying for finals. If you want to see an example of a non-blocking socket connect, follow the code below. I’ll comment on it in a bit.

require 'socket'
include Socket::Constants

if $*.length   [port 2] ... [port N] \n"
    exit
end

for i in 1...$*.length
    s = Socket.new( AF_INET, SOCK_STREAM, 0 )
    sa = Socket.pack_sockaddr_in( $*[i], $*[0] )
    begin
    s.connect_nonblock( sa )
    rescue Errno::EINPROGRESS
    end
end

The first part of the code should be self-explanatory for anyone familiar with ruby. We just import the socket library, and include the constants from within so we don’t have to prepend Socket:: to all of our constants later. Following this immediately is an argument check – we want at least a hostname and one port to knock, but we can accept as many ports as the user can provide.

The second loop is the more interesting part. It starts off by creating a stream socket that expects a hostname or IP address as an endpoint. Then we create a socket address object containing the port ($*[i] = args[i]) and the hostname (contained in $*[0]). After the socket address has been created, we throw in the ‘begin’ statement so we can catch errors later on. Then comes the non-blocking connect call: the program execution will not wait for the socket to establish a connection before moving on, which is what we want when portknocking because no connection will be established when knocking. The rescue statement is so that we don’t get an error the next time the socket tries a connection. If we didn’t have it, ruby would complain that we already have a socket operation in progress and exit for us.

The script is simple, but this took a long time to figure out. I love ruby, but sometimes the documentation on niche areas of coding are a little weak. For other non-blocking IO procedures, look in the Ruby 1.8.5 core API: http://www.ruby-doc.org/stdlib

Gmail Address Filtering

September 24, 2006

Note: This post has been updated.

MIPS and .vimrc Fun, Part One

September 23, 2006

I’m in a course that requires us to write programs in MIPS assembly. I’m really enjoying the course, but even this early on I’m seeing repetition regardless of the lab or project. I believe my editor is here to make my life as a coder easier, so I’ve thrown together a couple functions for my .vimrc to handle some common tasks. The first is mapping numerical syscall values to constants so I don’t have to look at them while coding. The first version is for all syscalls, and the second is for syscalls I commonly use.

In your .vimrc:



" Makes constants for syscalls
command AllSyscalls call AllSyscallsAsConstants()
function AllSyscallsAsConstants()
    call append(line("."), "EXIT = 10")
    call append(line("."), "SBRK = 9")
    call append(line("."), "READ_STRING = 8")
    call append(line("."), "READ_DOUBLE = 7")
    call append(line("."), "READ_FLOAT = 6")
    call append(line("."), "READ_INT = 5")
    call append(line("."), "PRINT_STRING = 4")
    call append(line("."), "PRINT_DOUBLE = 3")
    call append(line("."), "PRINT_FLOAT = 2")
    call append(line("."), "PRINT_INT = 1")
endfunction

command CommonSyscalls call CommonSyscallsAsConstants()
function CommonSyscallsAsConstants()
    call append(line("."), "EXIT = 10")
    call append(line("."), "SBRK = 9")
    call append(line("."), "READ_STRING = 8")
    call append(line("."), "READ_INT = 5")
    call append(line("."), "PRINT_STRING = 4")
    call append(line("."), "PRINT_INT = 1")
endfunction


To use them, after saving your newly updated .vimrc, just type :AllSyscalls or :CommonSyscalls to have the constants created on the line your cursor is currently at. And despite how it looks, the function will create them in numerical ascending order.

Code2HTML

August 31, 2006

I always get frustrated when I post a new code snippet and have to change the to &lt and &gt. So to solve this, I wrote a ruby script that converts those characters (and a couple other common ones) from regular text to their appropriate HTML representation. The code is available here.

In an application I’m developing at work, we are working with temporary directories that house non-sensitive information. When working with these files in these directories, ruby would kindly report:

warning: Insecure world writable dir ..., mode 04077

This is is annoying, because the messages are filling our terminals with unnecessary content. Turning it off requires only a line near the top of the source file:

# Turn off ruby warnings
$VERBOSE = nil

Enjoy seeing only the messages you want.

Generic Process Keepalive

August 18, 2006

At work I was testing a server that would exit upon receiving a certain message. Having to restart the server every time I wanted to run another test got to be annoying, so I came up with this script to automate the process. It is written in ruby, and has been tested to work in MacOSX, Debian Linux, and MS Windows with Cygwin. There is no reason it wouldn’t work on other Unix-like systems, those are just the ones I tested.


#!/usr/bin/ruby
#
# This script will restart a process if it dies.
# Usage: ruby Proternal
#
# Written by Robert Peaslee
#

if $*.length   "
	exit( 1 )
end

$CMD_PATH = $*[0]
$CMD_PATTERN = $*[1]
$INTERVAL = $*[2].to_i

while true do
	processes = `ps | grep #{$CMD_PATTERN}`
	pcount = processes.length
	if pcount > 1
		p "Multiple processes found Exiting."
		exit( 1 )
	elsif pcount == 0
		`#{$CMD_PATH}`
	end
	sleep( $INTERVAL )
end

There is a direct link to the source file here.