Archive for the 'Ruby' Category

HowTo: Use Multiple Addresses in Gmail Filters

August 25th, 2007 by peasleer

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

Non-blocking Networking in Ruby

November 14th, 2006 by peasleer

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