07. May 2014 · Comments Off · Categories: Snippets

An update to my Python file comparison utility, now with bidirectional support. This is an alternative to using diff that provides, in my opinion, cleaner output. Also, unlike diff, because this is written in Python it should be able to run on just about any platform.

#!/usr/bin/python
# audit-tool.py 2.0 - A simple file comparison utility.
# Copyright 2014 13Cubed. All rights reserved. Written by: Richard Davis

import sys

def compareFiles(filename1, filename2, ignorecase, bidirectional):
  """
  Given two filenames and an ignorecase booelean, compares filename1
  against filename2 and returns list of the differences and a count of
  how many were found. If ignorecase is 1, the contents of both files
  are read in as lowercase so that case differences are ignored. If
  bidirectional is 1, filename1 is compared to filename2 and vice-versa.
  """
  results = []

  try:
    f1 = open(filename1, 'rU')
  except IOError:
    print 'Could not find the specified file:', filename1
    sys.exit(1)

  try:
    f2 = open(filename2, 'rU')
  except IOError:
    print 'Could not find the specified file:', filename2
    sys.exit(1)

  list1 = f1.readlines()
  list2 = f2.readlines()

  f2.close()
  f1.close()

  if ignorecase == 1:
    for i in range(0,len(list1)):
      list1[i] = list1[i].lower()
    for i in range(0,len(list2)):
      list2[i] = list2[i].lower()

  diffs = set(list1) - set(list2)

  if bidirectional == 1:
    reverseDiffs = set(list2) - set(list1)

  diffcount = 0

  results.append('\n' + filename1 + ' -> ' + filename2 + ':\n')

  for diff in diffs:
    results.append(diff)
    diffcount = diffcount + 1

  if bidirectional == 1:
    results.append('\n' + filename1 + ' <- ' + filename2 + ':\n')

    for diff in reverseDiffs:
      results.append(diff)
      diffcount = diffcount + 1

  return results, diffcount

def main():
  if (len(sys.argv) < 3) or (len(sys.argv) > 5):
    print 'usage: audit-tool.py filename1 filename2 [--ignorecase] [--bidirectional]'
    sys.exit(1)

  ignorecase = 0
  bidirectional = 0

  filename1 = sys.argv[1]
  filename2 = sys.argv[2]

  if len(sys.argv) == 4:
    option1 = sys.argv[3]
    if option1 == '--ignorecase':
      ignorecase = 1
    elif option1 == '--bidirectional':
      bidirectional = 1
    else:
      print 'unknown option: ' + option1
      sys.exit(1)

  elif len(sys.argv) == 5:
    option1 = sys.argv[3]
    option2 = sys.argv[4]

    if option1 == '--ignorecase':
      ignorecase = 1
    elif option1 == '--bidirectional':
      bidirectional = 1
    else:
      print 'unknown option: ' + option1
      sys.exit(1)

    if option2 == '--ignorecase':
      ignorecase = 1
    elif option2 == '--bidirectional':
      bidirectional = 1
    else:
      print 'unknown option: ' + option2
      sys.exit(1)

  (results, diffcount) = compareFiles(filename1, filename2, ignorecase, bidirectional)

  if diffcount:
    print '\n%d difference(s) found.' % (diffcount)
    for line in results:
      print line,
  else:
    print '\nNo differences -- files are identical.'

  print '\nCopyright (C) 2014 13Cubed. All rights reserved.'

if __name__ == '__main__':
  main()
18. February 2012 · Comments Off · Categories: Mac, Snippets

This is a quick-and-dirty way to write a simple locked-down web browser perfect for kiosks or other similar scenarios. This code opens a pre-defined URL in full-screen mode and works with Snow Leopard and Lion. Instead of the overhead of a full browser like Firefox, the compiled size of this code is around ~500k and is designed to serve a very simple function.

AppDelegate.h:

//  AppDelegate.h
//  QuickWeb
//
//  Please edit below to define URL, font and font size.

#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>

#define MY_URL          @"http://www.example.com"
#define FONT            @"Times"
#define FONTSIZE        16

@interface AppDelegate : NSObject <NSApplicationDelegate> {
    NSWindow *mainWindow;
}
@end

AppDelegate.m:

//  AppDelegate.m
//  QuickWeb
//
//  Please edit "AppDelegate.h" to define URL, font and font size.

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    int windowLevel;
    NSRect screenRect;
    // Capture the main display
    if (CGDisplayCapture( kCGDirectMainDisplay ) != kCGErrorSuccess) {
        NSLog( @"Couldn't capture the main display!" );
    }
    // Get the shielding window level
    windowLevel = CGShieldingWindowLevel();
    // Get the screen rect of our main display
    screenRect = [[NSScreen mainScreen] frame];
    // Put up a new window
    mainWindow = [[NSWindow alloc] initWithContentRect:screenRect
                                             styleMask:NSBorderlessWindowMask
                                               backing:NSBackingStoreBuffered
                                                 defer:NO screen:[NSScreen mainScreen]];
    [mainWindow setLevel:windowLevel];
    [mainWindow setBackgroundColor:[NSColor blackColor]];
    [mainWindow makeKeyAndOrderFront:nil];
    
    // Load content view
    NSString *urlAddress = MY_URL;
	NSURL *url = [NSURL URLWithString:urlAddress];
	NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    WebView *webView = [[WebView alloc] initWithFrame:screenRect];
    [[webView preferences] setStandardFontFamily:FONT];
    [[webView preferences] setDefaultFontSize:FONTSIZE];
    [[webView mainFrame] loadRequest:requestObj];
    [mainWindow setContentView:webView];
}

- (void)applicationWillTerminate:(NSNotification *)notification
{
    [mainWindow orderOut:self];
    
    // Release the display(s)
    if (CGDisplayRelease( kCGDirectMainDisplay ) != kCGErrorSuccess) {
        NSLog( @"Couldn't release the display(s)!" );
    }
}

- (BOOL)canBecomeKeyWindow
{
    return YES;
}

@end
19. January 2012 · Comments Off · Categories: Linux, Snippets

This template can be used to create a service script for Red Hat Enterprise Linux. It will enable you to use “service myservice start”, “service myservice stop”, or “service myservice status” to control a particular process. It also supports the familiar Red Hat “OK” or “FAILED” green and red status messages. Other options can be easily added by modifying the case statement below. This script also supports chkconfig, so you can set the service to start on boot by issuing the command “chkconfig myservice on”, or remove it from boot start with “chkconfig myservice off.” This script should be placed in /etc/init.d with the proper permissions.

#!/bin/bash
# Replace myservice with your service name. Insert commands where noted.
# chkconfig: - 99 00

# Source function library.
. /etc/rc.d/init.d/functions

case "$1" in
  start)
    echo -n "Starting myservice"
    if [ -f /var/run/myservice.pid ]
    then
      echo
      echo -n "myservice is already running!"
      echo
      exit 1
    fi
    # insert commands here ...
    if [ -f /var/run/myservice.pid ]
    then
      echo_success
      echo
    else
      echo_failure
      echo
    fi
    ;;

  stop)
    echo -n "Stopping myservice"
    if [ ! -f /var/run/myservice.pid ]
    then
      echo
      echo -n "myservice is not running!"
      echo
      exit 1
    fi
    # insert commands here ...
    echo_success
    echo
    ;;

  status)
    # insert commands here ...
    ;;

  *)
  echo "Usage: /sbin/service myservice {start|stop|status}"
  exit 1
esac

exit 0
07. July 2011 · Comments Off · Categories: Linux, Snippets

This is a very simple Bash script I wrote to monitor a remote address. The script sends a ping and if the ping returns a non-zero value (in other words, it failed) then an email is sent to a specified address and a flag is set to 1. Another email is sent only when the connection comes back up, at which time the flag is reset to 0.

Add this to crontab:
*/1 * * * * /usr/local/bin/checknet.sh > /dev/null
In this example the script runs every minute, and the output is redirected to /dev/null to suppress “Cron Daemon” emails.

Simply change the value of the target and email variables below and you’re ready to go.

#!/bin/bash

# If the file that holds the flag doesn't exist, create it with default of 0

if [ ! -f /usr/local/bin/checknet.tmp ]
then
  echo 0 > /usr/local/bin/checknet.tmp
fi

target=TARGET_GOES_HERE
email=EMAIL_GOES_HERE
flag=$(cat /usr/local/bin/checknet.tmp)
timestamp=$(date "+%d-%b-%Y %H:%M")

ping -c 1 ${target}

# If the ping fails ...

if [ $? -ne 0 ]
then
  if [ "$flag" -eq "0" ]
  then
    echo "Ping to $target failed!" | mail -s "Connection Down ($timestamp)" $email
    echo 1 > /usr/local/bin/checknet.tmp
  fi

# If the ping is successful ...

else
  if [ "$flag" -eq "1" ]
  then
    echo "Ping to $target successful!" | mail -s "Connection Up ($timestamp)" $email
    echo 0 > /usr/local/bin/checknet.tmp
  fi
fi
30. January 2011 · Comments Off · Categories: Snippets

Use RegEx (Regular Expressions) to search through files for specific text.

#!/usr/bin/python

import sys
import re

def ParseLog(filename, search_string):
  try:
    f = open(filename, 'rU')
  except IOError:
    print '\n*** I/O Error: Can\'t read file', filename, '***\n'
    return

  lines = f.readlines()
  for line in lines:
    result = re.search(search_string, line)
    if result:
      print line,

  f.close()

  return

def main():
  if len(sys.argv) < 2:
    print 'usage: ./checklog filename1 filename2 filename3 ...'
    sys.exit(0)

  args = sys.argv
  args.remove(sys.argv[0])

  search_string = raw_input('\nPlease enter RegEx search string: ')

  for arg in args:
    ParseLog(arg, search_string)

  print '\nCopyright (C) 2011 13Cubed. All rights reserved.'

if __name__ == '__main__':
  main()
30. January 2011 · Comments Off · Categories: Snippets

Convert IPv4 decimal (base 10) addresses to hex (base 16). Useful for 6to4 tunnel configs.

#!/usr/bin/python

import sys
import re

def DecToHex(dec_ip):
  dec_octets = str.split(dec_ip, '.')
  hex_octets = []

  if len(dec_octets) != 4:
    print 'usage: ./iptohex.py x.x.x.x'
    sys.exit(1)

  for dec_octet in dec_octets:
    if int(dec_octet) > 255:
      print 'usage: ./iptohex.py x.x.x.x'
      sys.exit(1)

    if int(dec_octet) < 16:
      hex_octets.append('0' + hex(int(dec_octet))[2:])
    else:
      hex_octets.append(hex(int(dec_octet))[2:])

  hex_octets.insert(2, ':')
  hex_ip = ''.join(hex_octets)
  return hex_ip

def main():
  if (len(sys.argv) != 2):
    print 'usage: ./iptohex.py x.x.x.x'
    sys.exit(1)

  dec_ip = sys.argv[1]

  invalid = re.search(r'[^0-9\.]', dec_ip)
  if invalid:
    print 'usage: ./iptohex.py x.x.x.x'
    sys.exit(1)

  hex_ip = DecToHex(dec_ip)

  print '\nIPv4 Hex Address:\t', hex_ip
  print '6to4 Tunnel Address:\t', '2002:' + hex_ip

  print '\nCopyright (C) 2011 13Cubed. All rights reserved.'

if __name__ == '__main__':
  main()
30. January 2011 · Comments Off · Categories: Snippets

A very simple one way file comparison utility written in Python.

#!/usr/bin/python
# audit-tool.py - A simple one way file comparison utility.
# Copyright 2011 13Cubed. All rights reserved. Written by: Richard Davis

import sys

def compareFiles(filename1, filename2, ignorecase):
  """
  Given two filenames and an ignorecase booelean, compares filename1
  against filename2 and returns list of the differences and a count of
  how many were found. If ignorecase is 1, the contents of both files
  are read in as lowercase so that case differences are ignored.
  """
  results = []

  try:
    f1 = open(filename1, 'rU')
  except IOError:
    print 'Could not find the specified file:', filename1
    sys.exit(1)

  try:
    f2 = open(filename2, 'rU')
  except IOError:
    print 'Could not find the specified file:', filename2
    sys.exit(1)

  list1 = f1.readlines()
  list2 = f2.readlines()

  f2.close()
  f1.close()
 
  if ignorecase == 1:
    for i in range(0,len(list1)):
      list1[i] = list1[i].lower()
    for i in range(0,len(list2)):
      list2[i] = list2[i].lower()

  diffs = set(list1) - set(list2)

  diffcount = 0

  for diff in diffs:
    results.append(diff)
    diffcount = diffcount + 1

  return results, diffcount

def main():
  if (len(sys.argv) < 3) or (len(sys.argv) > 4):
    print 'usage: ./audit.py filename1 filename2 [--ignorecase]'
    sys.exit(1)

  ignorecase = 0

  filename1 = sys.argv[1]
  filename2 = sys.argv[2]

  if len(sys.argv) == 4:
    option = sys.argv[3]
    if option == '--ignorecase':
      ignorecase = 1
    else:
      print 'unknown option: ' + option
      sys.exit(1)

  (results, diffcount) = compareFiles(filename1, filename2, ignorecase)

  if diffcount:
    print '\n%d difference(s) found:' % (diffcount)
    for line in results:
      print line,
  else:
    print '\nNo differences -- files are identical.'

  print '\nCopyright (C) 2011 13Cubed. All rights reserved.'

if __name__ == '__main__':
  main()