Tag Archives: script

VBA – User Defined Type

As much as I do not like VBA, I do like the “User Defined Types” which, from a C/C++ programmer’s prospective, this is a lot like using structs.  And for data management, which is probably 90% of what VBA is used for, it makes a lot of since.  How do we define a User Defined Type?

Private Type dict
    a As Integer
    b As String
    c As String
    d As Integer
End Type

Once Defined, we need an initialization function to store the struct.

Private Function defineDict() As dict
    defineDict.a = 1
    defineDict.b = "two"
    defineDict.c = "three"
    defineDict.d = 4
End Function

At this point, we can use the same calling to to that ‘struct’ to change the variables as needed.

Sub testType()
    Dim t As dict       ' Set the variable
    t = defineDict      ' Initialize
    Debug.Print t.b     ' Prints >> "two"
    t.b = "no more"     ' Change a variable
    Debug.Print t.b     ' Prints >> "no more"
End Sub

Garmin Wardriver – Part 2

I’m very happy to say, this is a simple project, to get working in its most basic form.  Note, I said it’s most basic form so no hate mail on the fact that this is nothing more than a quick script!  There are plans to actually go deeper, make this open to more than my device, not use already existing programs, etc.  But for the basic concept and starter, I’ve made this program use gpsbabel to get the gps information and iwlist to get the network information.  I had started with pywifi but found this to be a problem because there was an overbound error.  This bug will be reported, it seems it has a problem with converting an integer to a float on a 64bit machine.

So with no futher ado, here is the script:

#!/usr/bin/env python
import os, re, time

# DEATH FUNCTION
def die(msg):
	print ' [*] ERROR: %s' % msg
	exit(1)

# ENSURE WE ARE ROOT
def checkroot():
	if os.getuid() != 0:
		die('Run this program as root.')
	return

# GET NETWORK INFO
def getessid(dev):
	nets = os.popen('iwlist %s scan' % dev).read()
	pat  = re.compile(r'ESSID:".*"')
	mess = re.findall(pat, nets)
	found= []
	for find in mess:
		found.append(find.split('"')[1].split('"')[0])
	return found

# GET GPS INFO
def getposition(dev):
	pos = os.popen('gpsbabel -i garmin,get_posn -f %s' % dev).read()
	pos = pos.splitlines()[1].split(' ')
	return [pos[1],pos[2]]

# RUN IT
def main():
	checkroot()
	found = getessid('eth1')
	pos   = getposition('/dev/ttyUSB0')
	for find in found:
		print 'ESSID: %s @ %s | %s' % (find,pos[0],pos[1])
	exit(0)

if __name__ == '__main__':
	main()

So what you see here is that I’m using os.popen() to call my programs to draw data.  Unfortunately, iwlist is painfully slow, to the point there’d be a five second delay on some slower machines between the call and having the data ready.  This is why I want to develop the application to not be dependent on other programs, but for the time being, this works as proof of concept in the data gathering stage.  It’s now just a matter of adjusting the code to run this constantly and load data to an overlay when entering and leaving an ESSID’s area.

Any comments for improvements?  Don’t forget, you can join this project any time on SourceForge!

PHP’s chunk_split() in python…

The other day I posted some code with PHP method for compressing XFDL files. I was unfamiliar with PHP’s chunk_split function, so I googled it and came up with this reference.  I then wrote the appropriate code in Python which is a quick script like this:

#!/usr/bin/env python

#string chunk_split ( string body [, int $chunklen = 76 [, string $end = "\r\n" ]] )
def chunk_split(body,chunklen=76,end="\r\n"):
	data = ""
	for i in range(0,len(body),chunklen):
		data += body[i:min(i+chunklen,len(body))] + end
	return data

You can see this code in action through this output:

zds@CF55 ~/Desktop
$ python
Python 2.5.2 (r252:60911, Dec  2 2008, 09:26:14)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from chunk import *
>>> test = """Hello, how are you today?  This is a test of my python interpreta
tion of the PHP function, chunk_split().  It should take this one line of writi
ng and split it by 76 characters and add a DOS compatible line end (e.g. \r\n)
by default.  I've done my best to have code as close as possible to the PHP fun
ction.  This was done in an attempt to work out a method of compression XFDL fi
les.  I've found this function to work but still need to figure out a way to ru
n a compatible gzip method to PHP's gzencode from Python."""
>>> chunk_split(test)
"Hello, how are you today?  This is a test of my python interpretation of the\r\
n PHP function, chunk_split().  It should take this one line of writing and s\r\
nplit it by 76 characters and add a DOS compatible line end (e.g. \r\n) by defa\
r\nult.  I've done my best to have code as close as possible to the PHP functio\
r\nn.  This was done in an attempt to work out a method of compression XFDL fil\
r\nes.  I've found this function to work but still need to figure out a way to \
r\nrun a compatible gzip method to PHP's gzencode from Python.\r\n"
>>>

It appears to work!  This still doesn’t fix my compression problems with the XFDL files though.  It would appear that gzencode does the correct compression, now I just need to find a way to do the same compression in Python.  The GZipFile methods do not output the same as gzenecode() in PHP.

XFDL Viewer Update…

As I dig through miles of XML, I realize I have not posted lately. I’ve been a bit busy meeting the May 15th deadline for my project. But here’s a quick update. First, don’t forget to view the update viewer. It’s not pretty, but it works to the point I’ve set it. I’ve changed from PHP to using Python CGI (a language I’m more comfortable with) and I’ve done what took two weeks in two days. Too bad this wasn’t thought of before!! Anyhow, I figured I’d pass along this bit of code from Neil Funk that shows a better method for decompression of an XFDL in Python:

#!/usr/bin/python
from base64 import *
import zlib

# OPEN FILES
inp = open('example.xfdl','rb').read()
out = open('example.xml,'wb')

# TAKE OUT THE MIME DATA
magic = inp.splitlines()[0]
data   = inp.split(magic)

# THE TRICKY PART -- Look to the python manual for explanation.
wbits = 15+32
newData = zlib.decompress(b64decode(data),wbits)

out.write(newData)
out.close()

And drumroll please, for Chris Hutton contributed this PHP code for recompressing an XFDL from XML.  I’m working to translate this to Python, but for the time being, an XML with an XFDL extension works.

// Export XML, gzip, and base64 encode. Append XFDL header information and output to user.
// XML is the raw data to be saved.
$newxml = $xml->asXML();
// chunk_split is new to me!
$output = chunk_split(base64_encode(gzencode($newxml)));
// Add the header!
$output = "application/vnd.xfdl;content-encoding=\"base64-gzip\"\n". $output;

header("Content-disposition: attachment; filename=\"{$filename}\"");
header("Content-type: application/vnd.xfdl");

echo $output;

So thank you all for your contributions!  I’ll try to keep this blog more up-to-date.

Python Curses – Custom Menu

Continuing on the same project as the previous post, I came to wanting to make a custom menu with curses in Python.  Realizing that there are functions to create menus in curses already, I wanted to build this fro m the bottom up.  The concept was to produce a menu that would highlight the selection change on the arrow keys or direct input, and then on a press of the Enter key the menu would return that selection.

Now, while writing this, you’ll see in my code that I took probable the least efficient way of building this menu, but it helps in making itself explanatory for the person learning curses.  As for the context of this coding, I built it as a function in my XFDL viewer, so there are 5 options in the menu.  I used win.keypad(0) to enable the use of the arrow keys but for some reason, the curses.KEY_UP was not being detected so the arrow key up and arrow key down are 259 and 258, respectively.  This does work though, I also have the menu catch numbers 1-5 and set the highlighted line accordingly.

def menu():
    curses.init_pair(1,curses.COLOR_RED, curses.COLOR_WHITE)
    screen.keypad(1)
    pos = 1
    x = None
    # I'm going to be lazy and save some typing here.
    h = curses.color_pair(1)
    n = curses.A_NORMAL
    while x != ord('\n'):
        # Gotta reset the screen from the root or lose the border, window, etc.
        screen.clear()
        screen.border(0)
        screen.addstr(2,2, "XFDL VIEWER", curses.A_STANDOUT)
        screen.addstr(4,2, "Please select an option...", curses.A_BOLD)
        # Detect what is highlighted by the 'pos' variable.
        if pos == 1:
            screen.addstr(5,4, "1 - XFDL -> XML",h)
        else:
            screen.addstr(5,4, "1 - XFDL -> XML",n)
        if pos == 2:
            screen.addstr(6,4, "2 - XML  -> XFDL",h)
        else:
            screen.addstr(6,4, "2 - XML  -> XFDL",n)
        if pos == 3:
            screen.addstr(7,4, "3 - Show XML",h)
        else:
            screen.addstr(7,4, "3 - Show XML",n)
        if pos == 4:
            screen.addstr(8,4, "4 - Exit",h)
        else:
            screen.addstr(8,4, "4 - Exit",n)
        if pos == 5:
            screen.addstr(9,4, "5 - DEBUG", h)
        else:
            screen.addstr(9,4, "5 - DEBUG", n)
        screen.refresh()
        x = screen.getch()
        # Is 'x' 1-5 or arrow up, arrow down?
        if x == ord('1'):
            pos = 1
        elif x == ord('2'):
            pos = 2
        elif x == ord('3'):
            pos = 3
        elif x == ord('4'):
            pos = 4
        elif x == ord('5'):
            pos = 5
        # It was a pain in the ass trying to get the arrows working.
        elif x == 258:
            if pos < 5:
                pos += 1
            else:
                pos = 1
        # Since the curses.KEY_* did not work, I used the raw return value.
        elif x == 259:
            if pos > 1:
                pos += -1
            else:
                pos = 5
        elif x != ord('\n'):
            curses.flash()
            # show_error() is my custom function for displaying a message:
            # show_error(str:message, int:line#, int:seconds_to_display)
            show_error('Invalid Key',11,1)

    return ord(str(pos))

I’ve highlighted the lines pertaining to my work around for the key pad.  This function will return the menu option and then that is processed for a reaction.  Reminder: the ‘screen’ object for my curses window is a global variable. I’m quite thrilled at the simplicity of this and the curses library, although I am disappointed in the lack of tutorials on the web deeper than typical ‘Hello World’ tutorials, but I hope these posts go to help others exploring this library!

Here’s a nice picture of the library in action:

Customize menu in action...
Be sure to comment on these tutorials and let me know if there is more detail needed or if they are helpful!!

XFDL in Linux :: Part 1

Earlier, I wrote about using PureEdge Viewer, which is Windows software from IBM on Linux through Wine. This got me thinking, do we need to use Windows software. A quick look at the file and through Google and it’s easy to see that an *.xfdl file is a gzipped, base64 encoded xml file. So this is part one of what I hope to be a tutorial into designing software on Linux using python to open, read and write xfdl files in the same way as PureEdge Viewer. It gets annoying, to say the least, to need to open Windows in VirtualBox, or an actual install to read and edit *.xfdl files. The barriers I see at this preliminary point is to convert the xml to a readable image and then to make that editable where possible.

So, in this first part, we will do the very basic converting an *.xfdl file to an *.xml file. The code should be self explanatory but if there are questions, post them through comments and I’ll do my best at getting an answer to you.

#!/usr/bin/python
""" IMPORTS """
from base64 import *
import gzip, os, sys

""" DEATH!!! """
# Standard way to die...
def die(msg=None):
    if msg == None:
        msg = "Unknown error."
    print " [*] ERROR - %s" % msg
    sys.exit(1)

""" CHECK FOR FILE """
# No file name, then we have nothing to do!
if len(sys.argv) < 2:
    die("Did not specifiy a file name.")

""" GET FILE """
# In a more advanced version, this will check the magic value of the file as well to
# ensure it is an *.xfdl file.
filename = sys.argv[1]
print "Using %s" % filename

""" OPEN FILE AND SPLIT """
# Nothing tough, grab the magic number (1st line) and then store the rest as a variable.
f = open(filename,'r').read()
magic = f.splitlines()[0]
print "magic: %s" % magic
data = f.split(magic)[1]
print "Got Data."
del f

""" BASE64 DECODE """
# First we decode the base64.
f = open('temp.gz','wb')
f.write(b64decode(data))
f.close()
print "Base64 Decoded."

""" GUNZIP DATA """
# Yes, I know this writing to a file and then deleting it is ugly but I have not found
# a way to gunzip from a data stream.
f = gzip.open('temp.gz','rb')
gunzip_data = f.read()
f.close()
os.remove('temp.gz')
print "Gunzipped Data."

""" SAVE XML FILE """
# As this gets more advanced, it should be able to stay as a data stream for editing.
filename = filename.split(".")[0] + ".xml"
f = open(filename,'wb')
f.write(gunzip_data)
f.close()
print "Saved to temporary file '%s'" % filename

Nothing too involved here, simply open the file, strip out the first line and the decode the rest from base64 and gunzip that data to get the xml inside.  In the next tutorial, we’ll look at the structure of that xml, once I actually understand it or find decent documentation on it!

Linux bash script for wifi.

When starting with Backtrack4, I compiled and installed the Broadcom wl driver for my laptop’s wifi. The unfortunate thing was that I got very frustrated because the default connection manager, wicd was getting confused when I would go to a network other than the one I initially connected to after boot-up. Shortly after that, Ubuntu 9.10 was experiencing the same difficulty after upgrading the kernel. So to work around using a network manager, I created a quick script to use.

In this script, you can see that you can pass a variable for your network name and key in the same format as you would normally. This was a fun script as it could easily be adapted as it’s own network manager, even with a little more work, you could have it in the tray, it’s own gui, etc. It’s nothing more than the commands typically used to connect on wifi but it just automated the process. I then went and created a child script for my most used networks, and after placing these in my bin, I actually have started to prefer this method.

Here’s the script:

#!/bin/bash

# die with honor
function usage() {
	echo "usage: ./connectWifi \"<essid>\" [key]"
	echo "       *key in ascii prefaces s:[key]"
	echo
	exit 1
}

# killed in disgrace
function die() {
	echo
	echo "   [*] ERROR: $1..."
	echo
	exit 1
}

# check for essid
if [[ $1 ]]; then
	# setup
	echo "Starting..."
	ifconfig eth1 down
	dhclient -r eth1 -q
	echo " -Previous connection dropped."
	ifconfig eth1 up
	iwconfig eth1 essid "$1"
	echo " -ESSID Set to $1."
	# check for key
	if [[ $2 ]]; then
		iwconfig eth1 key $2
		echo " -Key set to $2."
	fi
	# connect
	iwconfig eth1 mode Managed
	echo " -Connecting..."
	echo
	dhclient eth1
	# announce success
	if [[ $? -eq 0 ]]; then
		echo
		echo "Successfully connected to $1!"
		echo
		exit 0
	fi

else
	# no variables
	usage
fi

# declare failure
die "Failed to connect to $1."

This can serve as a good example of both the commands in connecting to wifi and an introduction to bash scripting. Please comment on the code and offer any suggestions you may have!