SMS

Notes on SMS (short text messages to/from cell phones):


  • Limit of 160 bytes includes subject AND body
  • Send via the Web
    • http://www.google.com/sendtophone
  • Send via email
    • Cellular One: 10-digit-cell-number@mobile.celloneusa.com
    • Comcast: 10-digit-cell-number@comcastpcs.textmsg.com
    • Sprint: 10-digit-cell-number@messaging.sprintpcs.com
    • T-Mobile: 10-digit-cell-number@tmomail.net
    • Verizon: 10-digit-cell-number@vtext.com
  • AT&T/Cingular Information:
    • SMS: 10digitmobilenumber@txt.att.net
    • MMS (multimedia): 10digitmobilenumber@mms.att.net
    • BlackBerry: username@att.blackberry.net

Set Up SSH Service on Windows

Tested on Windows XP Pro SP2 on a Windows Domain network. The following instructions assume that you want to install to "C:\Program Files\OpenSSH" and that you want your SSH server to run under the user-ID "sshd" and that you'll create a home directory for sshd named C:\OpenSSH-server.  You'll need to edit where appropriate if you make other choices.

  1. Install OpenSSH for Windows from http://sshwindows.sourceforge.net/ into C:\Program Files\OpenSSH (or other directory of your choosing).  I refer to this directory as [install-dir] throughout this document.
  2. Run the attached batch file from a command prompt.
  3. Edit [install-dir]\etc\sshd_config and set UsePrivilegeSeparation to yes
  4. Right click on C:\OpenSSH-server, select the Security tab, and grant sshd (or whatever you named the account)  and grant these permissions to the folder and subtree.
    1. Read
    2. Read & Execute
    3. List Folder Contents
    4. Full Control
    5. Also make the sshd account the Owner of the folder and subtree.
  5. Open the Services applet (from Control Panel/Administrative Tools) and change the OpenSSH service to use the sshd account.
  6. Stop and start the OpenSSH service.

At this point you've got password login.  There is more work to be done to enable PKI-based login.

 

GnuCash from Quicken

I'm going to try GnuCash.  I know from previous experience that I'll receive a bunch of the following error messages when importing my Quicken QIF file.

  • The file contains an unknown Action 'Cash'. Some transactions may be discarded.

It appears to me that Quicken and ETrade use action=Cash for Interest Income, instead of posting the transaction as a transfer from Interest Income to the ETrade account in Quicken.  I could manually edit these transactions to reflect the double-entry accounting norm, but I'm going to try a different route.  I figure that Quickbooks ought to be able to import Quicken better than anyone else.  Once I get my Quicken data into a double-entry bookkeeping system (i.e. Quickbooks) then perhaps it will import better into GnuCash.

  1. Download Quickbooks 2008 Simple Start from http://quickbooks.intuit.com/product/about_quickbooks/trials.jhtml
  2. Run the setup and install to C:\Kevin\Quickbooks
  3. Run Quickbooks for the first time:
    1. Select Sole Proprietorship
    2. Save the new, empty QB file to C:\kevin\Sample Company.QBW
    3. Otherwise, take the defaults
  4. Oops! QB Simple Start can't import Quicken data.  "Use Quickbooks Pro" is the suggested answer.
  5. Oddly enough, you can't download Quickbooks Pro 2008 from Quickbooks.Intuit.com, but you can from http://www.quicken.com.au/BusinessFinance/QuickBooksPro/trial.aspx
  6. When you download it (QuickBooks Pro Professional Business 2007-08 Trial), they'll give you a trial-unlock code.  Write it down. They'll give it to you as 99999999999999999, but you'll have to break it into 12345-12345-12345-123456.
  7. It will insist on rebooting.  Go ahead.
  8. Start QB and select "Convert from Quicken."
  9. Oops, that won't work.  It just tells you that it can't.  Create a new company, of type "General Business" with "Individual Income Tax Return."
  10. Save the empty file as C:\kevin\Sample Company.QBW
  11. Ahhh, but Quickbooks (this version) cannot import QIF, but IIF.  Download QIF to IIF converter from http://www.bigredconsulting.com/downloadpages/DownloadQIFNow.htm
  12. Run the install.
  13. Start Excel 2003; select Tools/Add-ins, and enable QIF to IIF importer.
  14. Oops. It isn't free.
  15. A little bit more reading has left me suspecting that Quicken to Quickbooks may be a low-fidelity translation.  I have read that QB won't import investment accounts.  Back to square one.


  1. Let's try it with Windows GnuCash, V2.2.1.
  2. Oops! When I start it, I run into the bug documented at http://wiki.gnucash.org/wiki/Windows#GConf.2FORBit_COMM_FAILURE
  3. Debugging the start-up failure (I'm running Win2K SP4 in a VM with 256MB RAM allocated):
    1. It happens with straight 2.2.1
    2. I extracted the binary files for ORBit 2.13.3 from ftp://ftp.gnome.org/pub/gnome/binaries/win32/ORBit2 and overwrote the ones in my gnucash directory. It works.
    3. 2.14.9 does not work.
    4. 2.14.0 does work.
    5. 2.14.2 does not work.
    6. I went back and re-tested 2.14.0 and 2.14.2 and confirmed that 2.14.0 does work and 2.14.2 does not work. Note that in between tests I deleted iof from C:\tmp\gconfd-kevin\lock
    7. So I'll try building 2.14.0 and test my build, followed by building 2.14.2 and testing my build, and then I'll migrate one to the other, a line at a time until I find the issue. 
    8. ... but I can't get it to build with the Cygwin mingw.  I'll try the stand-alone mingw from mingw.org.
  4. I eventually got it to build correctly.  I helped locate the bug.  Tor has a patch to 2.14.10 that fixes the problem.

After fixing the GnuCash start-up problem, it is time to work on importing my accounts.


  1. When I import transactions from an investment account, some of them have Action = 'Cash' (i.e. NCash\n records).  I get lots of error messages: "The file contains an unknown Action 'Cash'. Some transactions may be discarded."  Simply replacing all "\nNCash\n" with "\n" seems to fix the problem.  In other words, the NCash records can simply be deleted, because the N records are optional in Investment accounts.
  2. Ditto for ContribX and for WithdrwX.

Politics

"Politics is really just the art of getting people to agree on what they're going to do." (Unknown origin)

Learning Scala

Here are my notes on learning Scala:

 

  •  Not a lot of tool support yet.  JEdit syntax highlighting works OK, as do some other editors. Eclipse plugin provides more capability, but it is slow.
  • Environment variables:
    • SCALA_HOME=/path/to/scala/dir
    • PATH (add $SCALA_HOME/bin)


Notes on the language proper:

Hello World:

object HelloWorld {
  def main(args: Array[String]) {
       println("Hello, world!")
    }
}

object defines a singleton class instance.  Every program has a function named main inside a singleton object.

def defines a function or an expression without evaluating it; it does not evaluate its RHS.

Val defines a constant; it evaluates its RHS.

Formal parameter definition should always include a type. (Array[String] for the main function.)

Function calls are call-by-value by default.  Formal parameters with ": =>" instead of just ":" are call-by-name.

Every statement returns a value.

"return val" is the same as "val" at the end of a function.

Semicolons may be used as statement terminators.

Function definitions look like this:

def funcname(parm: ParmType):FuncType = {
  statements;
}

You can omit the surrounding {} if the function body is a single statement.

You can omit FuncType if it is obvious to the compiler.

Conditions (e.g. in an if-statement) must be surrounded by parenthesis, as in C and Java.

You can nest functions (in order to scope the names).

Tail-recusion is optimized for "directly tail-recursive" calls.  e.g. This gets optimized:

    def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)

... but this does not (due to the need to multiply AFTER the recursion returns).

    def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n 1)

Named functions can be passed by name too ("First-class functions"), as can anonymous functions.

Here is an anonymous function in use:

def blarfle(a: Int, b: Int): Int = sum((x: Int) => x * x, a, b)

The function header is "(x: Int)", so it is a function that takes a single, integer parameter. The body of the function is "x * x".

Sometimes you can get away with omitting the type (if the compiler can figure it out), as in:

def blarfle(a: Int, b: Int): Int = sum((x) => x * x, a, b)

And, whenever your argument list is just "(x)" it can be rewritten as "x" giving:

def blarfle(a: Int, b: Int): Int = sum(x => x * x, a, b)

Sometimes you'll run into a function that looks like this:

def sum(f: Int => Int): (Int, Int) => Int = {
  def sumF(a: Int, b: Int): Int =
  if (a > b) 0 else f(a) + sumF(a + 1, b)
  sumF
}

This says that 'sum' is a function that take a function (the argument 'f') that takes an Int parameter and returns an Int result;], and the function 'sum' returns a function of type "(Int, Int)=> Int)". In other words, 'sum' is a function factory that takes one function as its argument, and it generates a function that takes two Ints (and returns an Int).

One way to use sumF would be to do something like:

  def g = sum((x) => x * x)
  g(1,3)

... which calls 'sum' to generate a function that sums squares, naming the new function 'g', and then calls 'g' with 1 and 3 as parameters.

Sometimes Scala can't really tell that this is what you are trying to do, and it complans in your def of g. You solve that problem like so:

  def g = sum((x) => x * x) _
  g(1,3)

... which uses the trailing underscore to tell Scala, "Hey! Don't worry -- this call of 'sum' just returns a function and I promise to pass the right arguments to that function when I call it. (I think.)

<pFor the ultimate in brevity, you can define g and call it in a single line:</p>

sum(x => x * x)(1, 10)

The "sum(x => x * x)" generates the new (unnamed) function and the "(1, 10)" calls it with the arguments 1 and 10.

 

more soon

Getting Started with Scala's Lift Framework

I thought I'd take a look at Scala and the Lift Framework. Everything below is running in my Win2K VM with 512MB memory assigned to the VM. My Eclipse Workspase is K:\code.

Prerequisites

  1. Maven 2.0.7
    1. unzipped to K:\Maven
    2. Add M2_HOME=K:\maven to environment
    3. Create the folder K:\code\.m2\repository
    4. Create C:\Documents and Settings\<your-ID>\.m2\settings.xml containing:
      • <settings>
      • <localRepository>K:/code/.m2/repository/</localRepository>
      • </settings>
  2. Ensure your PATH contains C:\Java\bin;C:\Java\jdk\bin;C:\java\jdk\jre\bin;K:\maven\bin;
  3. Add JAVA_HOME=C:\Java\JDK to environment
  4. Java EE 5 installed to C:\Java
  5. Scala 2.6.0-final installed to C:\Scala
  6. install Eclipse 3.3.0 (Eclipse IDE for Java EE Developers) to K:\eclipse
  7. Subclipse 1.2.4 (http://subclipse.tigris.org/update_1.2.x)
  8. Install Maven 2.0 Integration V0.0.11.20070603... (http://m2eclipse.codehaus.org/update/)
  9. Install Eclipse PDE Plug-in Developer Resources 3.3.1 (The Eclipse Project Updates/Eclipse SDK Eclipse 3.3.1)
  10. Scala Plug-in (http://scala-lang.org/downloads/scala-plugin)


Basic Setup and Sanity Test

  • Using Eclipse SVN support, check-out Lift by right-clicking in the Package Explorer, Selecting Import/Other/Checkout Projects from SVN, repository = http://liftweb.googlecode.com/svn/trunk
  • Close Eclipse
  • Open a command prompt in K:\code\liftweb
  • mvn clean:clean install
  • cd example
  • mvn jetty:run
  • http://localhost:8888

Getting Eclipse to Work Well With Scala

  1. cmd prompt in K:\
  2. mvn -Declipse.workspace=K:\code eclipse:add-maven-repo
  3. cd \code\liftweb
  4. mvn eclipse:eclipse
  5. Start Eclipse
  6. Right-click liftweb, select Build Path/Configure Build Path/Libraries:
    1. connect each library with a real jar file in the file system
    2. Add log4j-1.2.12.jar
    3. Add commons-collections jar
    4. Add mail jar
    5. Delete the reference to scala-actors.jar
  7. Window/Preferences/Run-Debug/String Substitution: Add variable maven_exec=K:\maven\bin\mvn.bat
  8. Run/External Tools/Open External Tools Dialog. Define the following Maven tasks
    1. Name=Lift-Clean; Base-Directory=K:\code\liftweb; Goals=clean:clean
    2. Name=Lift-install; Base-Directory=K:\code\liftweb; Goals=install
    3. Name=Lift-run-example; Base-Directory=K:\code\liftweb\example; Goals=jetty:run

VMWare Notes and Learnings

Which VMNet is Which?

  • VMnet0 is for bridged networking
  • VMnet8 is for NAT networking
  • VMnet1 is for Host-only networking

DNS Failure in Guest

I was getting DNS failures in my Windows XP Guest most of the time at work, and some of the time at home.  I read numerous posts suggesting that VMWare's NAT DNS is flakey.  However in my case, the guest was simply timing out on DNS resolution.  To confirm that this is the problem, do the following in the guest:

If it succeeeds (and lookups failed before) then you need to increase your DNS timeout in the guest. Using regedit, update (or create -- type is REG_MULTI_SZ) HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DNSQueryTimeouts with a value that resembles: 9 1 1 1 1 0

  1. The first digit is "Query the preferred DNS server on a preferred connection"
  2. Second digit: "Query the preferred DNS server on all connections."
  3. 3rd digit: "Query all DNS servers on all connections (1st attempt)."
  4. 4th digit: "Query all DNS servers on all connections (2nd attempt)."
  5. 5th digit: "Query all DNS servers on all connections (3rd attempt)."
  6. 6th digit: Must be zero.

Slow Guest

  • VMWare client (Windows 2000) was running VERY slow.  Response time was OK, but the clock ticked off the seconds at about 1 tick per 5 real seconds.
    • Solution 1: It turns out that my Dell Precision M70 laptop's Windows XP Pro had recognized the PC as a ACPI Multiprocessor PC.  It has only one processor.  Start Device Manager, open Computer, right click on ACPI Multiprocessor PC, Update Driver, Install from a list or a specific location, Don't search - I will choose, select Advanced Configuration and Power Interface (ACPI) PC.  It will want to reboot twice.  (Let it do so.)
    • Solution 2: Open a Cygwin bash prompt and run a "while true do echo foo done" loop to keep the CPU busy and prevent it going to S3 or S4 power state. 
  • VMNet1 keeps showing as disabled in vmnetcfg, but the Windows host thinks the virtual NIC is connected. Network Neighborhood/[VMNet1 NIC]/Status shows no IP address. Host and guest are unable to communicate via VMNet1's IP addresses (ping fails).
    • Using vmnetcfg.exe, delete VMNet1 (don't forget to click Apply), and re-create VMNet1. No need to stop the VM first.

Getting Vmware networking set up just the way I want it has proven to be time consuming, so I want to capture the setup that is working for me.

vmnetcfg

  1. Run vmnetcfg.exe (in "C:\Program Files\Vmware\Vmware player")
  2. Set up the following interfaces (check the Summary tab):
    1. VMNet0 (Bridged)
    2. VMNet1 (Host-only)
    3. VMNet8 (NAT)
  3. On the Automatic Bridging tab, disable automatic bridging. (Corporate network control freaks don't like unauthorized bridges on their networks.)
  4. On the Host Virtual Network Mapping tab (via the ">" buttons):
    1. VMNet1:
      1. Subnet = 192.168.11.1, Mask = 255.255.255.0, then click Apply on the Virtual Network Mapping tab
      2. DHCP = Start: 192.168.11.128, End: 192.168.11.254
    2. VMNet8:
      1. Subnet = 192.168.18.1, Mask = 255.255.255.0, then click Apply on the Virtual Network Mapping tab
      2. DHCP = Start: 192.168.18.128, End: 192.168.18.254
      3. NAT: Gateway = 192.168.18.2
  5. On the HOST PC, open Network Connections:
    1. Configure "VMware Network Adapter VMnet1"
      1. IP address = 192.168.11.1, Mask = 255.255.255.0, Gateway is empty, DNS servers are empty
    2. Configure "VMware Network Adapter VMnet8"
      1. IP address = 192.168.18.1, Mask = 255.255.255.0, Gateway is empty, DNS servers are empty
  6. Make your vmx files look a lot like the following (but with different MAC addresses for different VMs)

ethernet0.present = "TRUE"
ethernet0.startConnected = "FALSE"
ethernet0.addressType = "generated"
ethernet0.generatedAddress = "00:0c:29:87:11:00"
ethernet0.generatedAddressOffset = "0"

ethernet1.present = "TRUE"
ethernet1.connectionType = "nat"
ethernet1.addressType = "generated"
ethernet1.generatedAddress = "00:0c:29:89:11:01"
ethernet1.generatedAddressOffset = "10"
ethernet1.startConnected = "TRUE"

ethernet2.generatedAddress = "00:0c:29:89:11:02"
ethernet2.generatedAddressOffset = "20"
ethernet2.addressType = "generated"
ethernet2.present = "TRUE"
ethernet2.connectionType = "hostonly"
ethernet2.startConnected = "TRUE"

  1. In the guest OS
    1. Set its NICs to use DHCP.  This will let you figure out which NIC is on which net.  Write down which is which or rename the connections to the vmnet.   I like names such as:
      1. Ethernet1-VMNet0-Bridged
      2. Ethernet2-VMNet8-NAT
      3. Ethernet3-VMNet1-HostOnly
    2. ping and tracert 192.168.11.1 and 192.168.18.1 and make sure they are routed correctly.
    3. ping and tracert mindspring.com (or other external address that responds to ping)
    4. Set its NICs to use static IPs:
      1. My Win2K is on 192.168.11.10 (no gateway, no DNS) and 192.168.18.10 (192.168.18.2 for gateway and DNS)
      2. My Ubuntu7 is on 192.168.11.20 (eth1: no gateway, no DNS) and (eth2: 192.168.18.2 for gateway and DNS) 192.168.18.20
    5. ping and tracert 192.168.11.1 and 192.168.18.1 and make sure they are routed correctly.
    6. ping and tracert mindspring.com (or other external address that responds to ping)
  2. Note: changing ethernetx.present from True to False or vice-versa, re-arranges which NIC is which in the client OS.  Try to avoid doing it.

Slow or Stuck or Two Mouse Pointers

If your mouse pointer movement is erratic, it won't go to some points on the VMWare virtual display, or it moves VERY slow, check CPanel/Mouse/Hardware.  Do you see "PS/2 Compatible Mouse?"  You should see "VMWare Pointing Device".  If you don't, install or upgrade VMWare Tools in the guest.

temporary end

 

nlsookup
  set timeout=9
  www.google.com

Proxy PAC Files

For Firefox, use file:///c /pac/proxy.pac
For Internet Explorer, use file://c:/pac/proxy.pac

Moving Cygwin

Suppose you have Cygwin installed on one drive, and you need to move it to another.  Just for grins, let's assume that you are going to move it using Windows Explorer (i.e. not using Cygwin to move Cygwin).  This is something that I have to do from time to time, because I work as a consultant, and I move from PC to PC pretty often.  When you do this, pieces of Cygwin break.  Here's where I keep track of the things I have to do after moving Cygwin.

  1. cd ~
  2. chown kevin:kevin *
  3. chown kevin:kevin .*
  4. chmod go-rwx .ssh/*