preload
Dec 26

Sometimes its nice to be able to  find out what IP address you are using to get to the Internet for things like setting up servers on the correct interface.  I use the following code to find this out:

#!/usr/bin/ruby

require 'open-uri'

def myINETaddr
  ip1 = open("http://ip.dnsexit.com/").read[1..20]
  ip2 = open("http://checkip.dyndns.org:8245/").read[/IP Address\: (.*)\<\/body/, 1]
  if ip1 != ip2
    throw "myINETaddr::UnableToRetrieve"
  end
  return ip1
end

if __FILE__ == $0
  puts myINETaddr
end

I have it check two outside services just to make sure they both agree…otherwise I have it throw an error. Of course, if you are behind a proxy server or NAT device, this method is just going to return the IP address of that device. If you just want the IP address of your default network interface, this code does the job just fine:

require 'socket'

def myIPaddr
   IPSocket.getaddress(Socket.gethostname)
end

if __FILE__ == $0
   puts myIPaddr
end
SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Dec 25

Merry Christmas!!
I love the ability that Ruby has to extend common value types and add my own personal methods.  One that I use alot is a simple ‘Hexdump’ method for the String class:

#!/usr/bin/ruby

class String

  def hexdump
    i = 1
    rr = ""
    while (self.length > 16*(i-1))
      a=self.slice(16*(i-1)..(16*i)-1)
      rr += sprintf("%06x: %4.4x %4.4x %4.4x %4.4x   %4.4x %4.4x %4.4x %4.4x ", (i-1)*16,  *a.unpack("n16"))
      rr += sprintf("|%s|\n", a.tr("^\040-\176","."))
      i += 1
    end
    return rr
  end

end

if __FILE__ == $0
   infile = File.new(ARGV[0], "r")
   ff = infile.read
   infile.close
   puts ff.hexdump
end
exit

The first part extends the String class, adding the ‘hexdump’ method. Calling this method on any string will return a dump of the string in hex. Its patterned after a very old BASIC program I used long ago. The bottom part of the code implements a file hexdump program:

 john@Orb:~/Dev/Ruby$ ./hexdump.rb /etc/rc.local
000000: 2321 2f62 696e 2f73   6820 2d65 0a23 0a23 |#!/bin/sh -e.#.#|
000010: 2072 632e 6c6f 6361   6c0a 230a 2320 5468 | rc.local.#.# Th|
000020: 6973 2073 6372 6970   7420 6973 2065 7865 |is script is exe|
000030: 6375 7465 6420 6174   2074 6865 2065 6e64 |cuted at the end|
000040: 206f 6620 6561 6368   206d 756c 7469 7573 | of each multius|
000050: 6572 2072 756e 6c65   7665 6c2e 0a23 204d |er runlevel..# M|
000060: 616b 6520 7375 7265   2074 6861 7420 7468 |ake sure that th|
000070: 6520 7363 7269 7074   2077 696c 6c20 2265 |e script will "e|
000080: 7869 7420 3022 206f   6e20 7375 6363 6573 |xit 0" on succes|
000090: 7320 6f72 2061 6e79   206f 7468 6572 0a23 |s or any other.#|
0000a0: 2076 616c 7565 206f   6e20 6572 726f 722e | value on error.|
0000b0: 0a23 0a23 2049 6e20   6f72 6465 7220 746f |.#.# In order to|
0000c0: 2065 6e61 626c 6520   6f72 2064 6973 6162 | enable or disab|
0000d0: 6c65 2074 6869 7320   7363 7269 7074 206a |le this script j|
0000e0: 7573 7420 6368 616e   6765 2074 6865 2065 |ust change the e|
0000f0: 7865 6375 7469 6f6e   0a23 2062 6974 732e |xecution.# bits.|
000100: 0a23 0a23 2042 7920   6465 6661 756c 7420 |.#.# By default |
000110: 7468 6973 2073 6372   6970 7420 646f 6573 |this script does|
000120: 206e 6f74 6869 6e67   2e0a 0a65 7869 7420 | nothing...exit |
000130: 300a 0000 0000 0000   0000 0000 0000 0000 |0.|
SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Dec 08

From time to time I need to create a utility that will work on one of my customer’s messaging systems to monitor something about it. Since Ruby isn’t on a lot of these systems (yet) I usually end up having to use Perl to create these utilities. Once nice thing about Perl is that there are lots and lots of packages out there that already do all sorts of functions. So after I have found the package that I need, I go out and see if its already on the messaging system. Since a standard Perl installation has any number of places where the package could be, I wrote this quick little Perl script to go parse through the @INC directories and print out all the package names it can find. The output can then be grep’d for the package in question quite easily.

Here’s the code:

#!/opt/perl/bin/perl
#
#  ShowLibs.pl  --  Print out all the packages in the @INC paths.
#     Useful if you want to see if a particular package is on your system or not.
#
#  John D. Allen, June 2009
#

use File::Find;

$cdir = "";
find(\&wanted, @INC);

sub wanted {
   if (/\.pm$/) {
      if ($cdir ne $File::Find::dir) {
         $cdir = $File::Find::dir;
         print "\n$cdir:\n";
      }

      open(PM, $File::Find::name);
      while(<PM>) {
         if (/^\s*package\s*(.*);/) {
            print "$1\n";
         }
      }
      close (PM);
   }
}

exit;
1;

You may need to change the first line, as my Perl home directory is not in a default location.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Dec 06

While running a simple enum of my Outlook inbox, I came across an error:

irb(main):005:0>require 'win32ole'
irb(main):006:0>ol = WIN32OLE.new('Outlook.Application')
irb(main):023:0>mapi = ol.GetNameSpace('MAPI')
irb(main):024:0>inbox = mapi.GetDefaultFolder(OutlookConst::OlFolderInbox)
irb(main):031:0>inbox.Items.each { |m| p.To }
ALLEN, JOHN
ALLEN, JOHN; xxxx
...
WIN32OLERuntimeError: unknown property or method `To'
    HRESULT error code:0x80020006
      Unknown name.
        from (irb):83:in `method_missing'
        from (irb):83
        from (irb):83:in `each'
        from (irb):83

Huh?? A message without a ‘To’ line? What gives? Poking around a bit more I get the item into an object to look at, and find out its an AppointmentItem, and not a normal email message. I’m thinking there is some property of the Item object that will tell me what kind of message it is. After some more digging around on the Internet, I find a reference to a MessageClass property. So if I modify my code a bit, I can list all the ‘To’ lines from all the messages I’m interested in looking at:

inbox.Items.each do |msg|
    puts "Unread:#{msg.To}" if msg.Unread && !msg.MessageClass[/Meeting/]
    puts "Meeting:#{msg.Subject}" if msg.MessageClass[/Meeting/]
end

The MessageClass properties of all the emails in my inbox are:
“IPM.Note” => Regular EMail
“IPM.Schedule.Meeting.Request” => Meeting Request
“IPM.Schedule.Meeting.Resp.Pos” => Meeting Accept
“IPM.Schedule.Meeting.Canceled” => Meeting Canceled
I’m sure there’s a Meeting Decline message class….I just don’t happen to have it right now.
“IPM.Note.Rules.OofTemplate.Microsoft” => Out of Office message.
I’m sure there are more types…I’ll add to this post as I find more.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with: