Sunday, November 28, 2010

C++ is like...

trying to build an octopus by nailing legs onto a dog.

This put me in mind of Dijkstra (I wasn't sure if it was actually Wirth but the 'net assures me it was EWD) -- as we can see here:

  • FORTRAN's tragic fate has been its wide acceptance, mentally chaining thousands and thousands of programmers to our past mistakes.
  • LISP has been jokingly described as "the most intelligent way to misuse a computer". I think that description a great compliment because it transmits the full flavor of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts.
  • When FORTRAN has been called an infantile disorder, full PL/1, with its growth characteristics of a dangerous tumor, could turn out to be a fatal disease.
That 2nd one isn't about FORTRAN but I enjoyed it so much I left it in. and then for some reason I stumbled across this brief incomplete and mostly wrong history of computer languages which I thought hilarious.

Thursday, November 18, 2010

Workplace humor US-Japan

Back in the previous millennium, during our six-year stint in Japan, Mizuno-san and Kamei-san had accompanied me on a business trip to the US. As we sat in the company cafeteria, my old buddy Paul, who I worked with back in the 1980s, stopped by to say hi.

We shook hands, and I introduced him to my Japanese colleagues. "You work with Collin?" he asked them.

When they replied in the affirmative, he said, "And you're willing to admit it??" The Americans guffawed, but my colleagues were mystified.

Back in Japan some time later, I described this interchange to some other colleagues. Kubo-san, one of the best English speakers in our department, was surprised at this sort of joke. "It is an honor," he said. He meant an honor to work with me. He was completely serious.

Fast forward to the 21st century...

My current boss asked the other day what I was working on, "besides beating on Chris two or three times a day."

I replied in mock exasperation, "You said two or three times a week!"

The reply was immediate: "That was before you moved right across the hall from him! Slacker."

Thursday, November 11, 2010

Two financial articles from The Atlantic

  1. Why Wall Street Always Blows It
    The magnitude of the current bust seems almost unfathomable—and it was unfathomable, to even the most sophisticated financial professionals, until the moment the bubble popped. How could this happen? And what's to stop it from happening again? A former Wall Street insider explains how the financial industry got it so badly wrong, why it always will—and why all of us are to blame.
    by Henry Blodget (December 2008 ATLANTIC MAGAZINE) link
  2. The Great Stock Myth
    Why the market’s rate of return—and your nest egg—may never recover
    By Megan McArdle
    Business September 2010 ATLANTIC MAGAZINE link

Saturday, November 06, 2010

A few films I want to remember

Before I head off to the market (gonna smoke some turkey before the rains start) I wanted to tell you about Date Night; while I'm here, I also want to find the title of that film about the young painter...

Based on the advice of a Blockbuster (MP) clerk, we watched Steve Carell and Tina Fey in "Date Night" (2010), an action farce billed as a romantic comedy. I'll have to say that overall I liked the film (Hey, I like all the corny jokes in "Live Free or Die Hard" and "Car Talk") because in spite of the somewhat, ah, raunchy stuff they get into, this husband and wife really want to make their marriage work.

Guys, I wouldn't recommend this film as a date night movie unless your wife/gf likes "Live Free or Die Hard."

Local Color (2009)

Really enjoyed this one, though I had a hard time remembering the title. Yes, as the above review says, it's got "formulaic structure, treacly score and earnest voice-over narration" but great acting. The basic idea is that a young would-be painter spends a summer in the country with a curmudgeonly old master. There's some "Karate Kid" stuff about mentoring, but more prominent is the writer-director's agenda related to art (real art, vs some of the stuff that passes for art today).

Our daughter is a painter, and especially after watching My Kid Could Paint That earlier this year, we found Local Color a winner.

Deja Vu (2006)

I don't know why we rented this one, but it was quite entertaining. It's got time travel (with the usual paradoxes -- finessed with a plot device at the end), terrific effects (the fire/explosion were real, not CGI), interesting reversal of racial stereotypes, and a little romance with Denzel Washington and Paula Patton.

Sunday, October 31, 2010

Taking every thought captive

Some decades ago I memorized 2 Corinthians 10:4-5 with only a vague idea of what it meant. I now have a slightly less vague idea.

The lovely Carol was reading an article to me from conversations journal volume 8.2 (Fall-Winter 2010) -- "How Not to Be a Hero" by Scott C. Sabin. This is a great article, and it resonated with something I heard at the Wright Lecture Series. It was fashionable a while back to talk about being the "hands and feet of Jesus." This is not all that bad a picture; if the Church is Christ's body, then some members might be hands and feet. But this "hands and feet of Jesus" thing has a pitfall: we might start thinking it's all up to us. Better to think of ourselves as John the Baptist, pointing people toward Jesus.

Back to the article, though: the author was having an Elijah-under-the-broom-tree moment (1 Kings 19:4), as he was bombarded by thoughts like "you don't really have what it takes" and "you didn't accomplish anything" and "you won't make a difference."

This reminds me of (I'll get back to this soon, I promise) something I heard maybe 20 years ago about some guys heading to a Promise Keepers event. Someone accused them of being shallow, and a spokesman for the group said, "You don't know the half of it! We're an inch deep and a mile wide!" His point, of course, is that we are nothing without Jesus; we really are in deep trouble without him.

OK, really back to the article now -- actually a sidebar titled "How to Stand" by Mindy Caliguire, on page 35. She listed a few sample thoughts that might come your way, approximately this:

  • You don't have what it takes.
  • You can't provide what this project (people, congregation, etc.) needs
  • You barely understand the problems, you don't have a good grasp of your resources, blah blah blah
  • You're no hero.
When I heard this list, those old Promise Keepers came to mind. You're right! I don't have what it takes! But I know someone who does! I really can't provide what this project or whatever needs. I barely understand the problems. I'm no hero. But that's OK, because I don't have to be; my Dad has what it takes, he can provide as he has so many times in the past, he understands the problems and the resources and all the rest. And he's always the hero.

And in a flash it came to me: this is taking every thought captive to the obedience of Christ. This is what it means to destroy speculation. "Gee, can I really do this?" has a very simple answer: "Without me you can do nothing" but "with God all things are possible." If God could deliver his message through a donkey (Numbers 22), then I'm going to go out on a limb and say he can use me for whatever task he wants me to do.

Put differently, we destroy speculation and take every thought captive to Christ by remembering that it's all about Him -- God in Christ is the hero -- and it's not about me.

Moses ran into this when God was telling him to go set the Israelites free from the king of Egypt. There's a part of this that would really be funny -- well, actually it is funny, to us. God says, "I am sending you to Pharoah" (Exodus 3:10) and Moses says, "Who am I, that I should go to Pharoah...?" (3.11) and God says, "I will be with you" (3:12). This goes on for a while, and then Moses says, "I have never been eloquent" (etc.) and God says, "I will help you."

Notice all those "I"s in there? Of course you know who wins. Moses learned what we all must remember: it's not about me; I'm never the hero. It's all about God; he is always the hero, because he's the only one who has what it takes for this sorry dark world.

And if whenever a thought like "You don't have what it takes" comes to you or me, we turn it into "Definitely I don't have what it takes, but the Lord Jesus Christ does; he is the only hope of the world. And he has sent me..." then I think that's taking those thoughts captive unto the obedience of Christ. To him be the glory!

Saturday, October 23, 2010

postfix, mac os X. also fetchmailrc

Continuing the Linux→Mac migration story started here... I had to get something set up to fetch mail automatically. What do you use to fetch mail?
$ type fetchmail
fetchmail is /usr/bin/fetchmail
$ 
Yeah. But I'm getting ahead of myself.

To fetch mail from my ISP, I need to authenticate across the wire. But this is a LAN; I don't want to authenticate with plaintext, and I'm not so sure about pop3s or whatever. How do you spell relief? S-S-H-T-U-N-N-E-L. What I'm gonna do is this:

$ ssh -f shell.my.isp.com -L 60110:popserver.my.isp.com:110 sleep 1200 
Every couple of minutes, I see if the port is still open locally and restart the tunnel if needed. I'll use fetchmail from port 60110 periodically.

How do you fetchmail from an alternate port? Here's what my .fetchmailrc looks like.
poll see.postman.fetchmailrc.invalid proto pop3 port 60110 user ISPUSERNAME pass ISPPASSWORD is postman here mda "/usr/sbin/sendmail -i -f %F %T"
What does all that stuff mean?

  • poll see.postman.fetchmailrc.invalid
    That "see.postnam.fetchmailrc.invalid" thing is an alias for 127.0.0.1 (i.e., localhost). The ".invalid" suffix means sendmail wouldn't try to send anything on it. (I'm not sure this is actually needed any more, but some time in the previous millennium I think, I hit upon this ".invalid" thing as a way to stop some Bad Thing from happening.)
  • proto pop3 port 60110
    This is how I tell fetchmail to use a different port. Since I'm just grabbing the email off my ISP's server (and deleting it as soon as I can deliver locally), there's no need for anything more sophisticated than POP.
  • user ISPUSERNAME pass ISPPASSWORD
    remote username/password
  • is postman here
    deliver remote email to user "postman" on the local host. The "postman" (not "postmaster") has a .procmailrc that figures out who the email is probably for (the lovely Carol, or one of the kids, or me -- actually the ex-teen no longer gets email here) and sends it accordingly. By the way, postman has this in ".forward":
    "|/usr/bin/procmail"
  • mda "/usr/sbin/sendmail -i -f %F %T"
    By default fetchmail will try to deliver to port 25. But the postfix daemon seems to want to stay alive for just a minute. This "mda" incantation says to send mail using this program, rather than trying to connect to port 25.
By the way, I also had to tweak postfix a bit. I messed with the plist file in /System/Library/LaunchDaemons/org.postfix.master.plist, but after learning about the 60-second timeout, I'm not sure that was needed. The below certainly is, though, for outbound mail -- I mean mail sent with mail(1) -- to go anywhere:
$ diff /etc/postfix/main.cf{.install,}
70a71
> myhostname = MYDOMAINNAME
76,77c77,78
< #
< #mydomain = domain.tld
---
> 
> mydomain = MYDOMAINNAME
307a309,310
> # collin 2010-10-23
> relayhost = [MY_ISP.MAILSERVER.HOST]

Getting it all to start on boot

Those details were fascinating (at least they were to me), but how about getting the ssh tunnel kicked off when the box boots?

On a Linux distro with sysV-based startup, you'd put something into /etc/init.d or something; Mac OS X doesn't do that sort of thing. Instead there are files in /System/Library/LaunchDaemons/ . Following some web advice, I created this file:

$ cat /System/Library/LaunchDaemons/collin.postman.tunnel.plist 
## NOTE: owned by root and perms no greater than 0644 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>collin.postman.tunnel</string> <key>Program</key> <string>/Users/postman/tunnel.sh</string> <key>RunAtLoad</key> <true/> </dict> </plist> $
(where /Users/postman/tunnel.sh is the shell script that creates the tunnel if needed, runs fetchmail, etc.)

Then to make the system aware of this...

$ launchctl load /System/Library/LaunchDaemons/collin.postman.tunnel.plist 
$ launchctl start collin.postman.tunnel
And basically, it should work.

UPDATE! 2010-11-07

A few gotchas that threw me off... discovered somewhat (!) later. Easy one first. To determine whether the tunnel was active, tunnel.sh said
 if netstat -an -finet|grep LISTEN | grep 60110 > /dev/null; then
Trouble is, the default path doesn't have a "netstat" in it. Solved by adding this to the script:
PATH=$PATH:/usr/sbin

The next one was a bit harder. As I mentioned before, I followed somebody's plist instructions. Which mostly worked, except for two things:

  1. On startup I'd get this message about how dovecot might use 640 FDs and we have a limit of 256. Ick. I tweaked the parameters it said to, and got the 640 down to something like 528 -- still too high. I may actually fix this someday, but in the meanwhile I'm just becoming root, saying "ulimit -n 1024" , and then spawning dovecot in the same root shell. Ick.
  2. Every 10 seconds or so, syslog got a "dovecot already running" spam. Every 10 seconds! This I addressed by rtfm and changing the plist file to look like this:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
            <key>Label</key>
            <string>com.diymacserver.dovecot</string>
            <key>ProgramArguments</key>
            <array>
                    <string>/opt/local/sbin/dovecot</string>
                    <string>-F</string>
            </array>
            <key>RunAtLoad</key>
            <true/>
            <key>KeepAlive</key>
            <true/>
    </dict>
    </plist>
    See that "-F" added to ProgramArguments? The manual says that daemons spawned this way must not daemonize but stay in the foreground. "-F" is how we tell dovecot not to say "if (fork()) exit(0);"

Migrating mail: kmail on SuSE Linux to maildir on mac os X Snow Leopard; also dovecot

Updated! See also part deux.
I'm not running Snow Leopard server edition (or whatever they call it) so I had to download dovecot, then configure it. Here's my journey....

Ports

First, I found the install media and installed Xcode. I like having compilers; it makes me feel like I'm on a real system.

Then, as I wrote earlier, it's not darwinports any more; instead, I downloaded macports. This creates a hierarchy under /opt/local, and also does nice things to the system-wide profile files. So once I had ports installed, every terminal session I started had these directories prepended to $PATH, like this:

$ echo $PATH
/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/Users/carol/bin

Install dovecot

Short version: click here. Even shorter:
sudo port install dovecot

Configure dovecot

Following instructions at http://wiki.dovecot.org/BasicConfiguration:
  • Where's the config file?
    $ dovecot -n
    # 1.2.14: /opt/local/etc/dovecot/dovecot.conf
  • Simple authentication
    $ echo "$USER:{PLAIN}password" > passwd.dovecot
    $ sudo mv passwd.dovecot /opt/local/etc/dovecot/
  • Modify dovecot.conf to use plaintext -- no longer disable plaintext login
  • mail location: "echo hi | mail -s dovecot.test carol" yields /var/mail/carol. but it's more than that; we have this sort of arrangement:
    $ ls ~/Mail
    ACFW                            MailLists
    AShland                         MailisWork
    ASthma research                 Mariko
    AWP                             Marketing
    Addresses                       Meet Up
    Affirmations                    Menlo Atherton HS
    ...
    JapanLifeInfo                   inbox
    ...
    $ ls ~/Mail/inbox
    cur     new     tmp
    $ 
    Therefore I'm thinking to create Maildir with directories cur,new,tmp, and the rest of the directories can be subdirectories under it. Like this:
    $ ls -o Maildir
    total 24
    lrwxr-xr-x  1 carol  27 Oct 23 10:58 cur -> /Users/carol/Mail/inbox/cur
    lrwxr-xr-x  1 carol  27 Oct 23 10:58 new -> /Users/carol/Mail/inbox/new
    lrwxr-xr-x  1 carol  27 Oct 23 10:58 tmp -> /Users/carol/Mail/inbox/tmp
    $ ls -F ~/Mail | grep / | cut -d/ -f1 | while read D; do ln -s "~/Mail/$D" Maildir; done
                # OOPS! The above doesn't work; see below
    $ rm Maildir/inbox
    $ 
  • But as noted above, mail isn't currently being delivered there. the dovecot page doesn't tell me about combining /var/mail/USERNAME mbox with ~/Maildir maildir format, so does procmail work? What if I set DEFAULT=$HOME/Maildir/ and put this into .forward?
    $ cat .forward
    "|/usr/bin/procmail"
    Yes! A test produced this:
    $ ls Maildir/new
    1287857872.59228_2.mini1.local
  • Turn off SSL TEMPORARY ONLY! -- otherwise I keep getting
    $ dovecot -n
    # 1.2.14: /opt/local/etc/dovecot/dovecot.conf
    Error: ssl_cert_file: Can't use /opt/local/etc/ssl/certs/dovecot.pem: No such file or directory
    Fatal: Invalid configuration in /opt/local/etc/dovecot/dovecot.conf
  • Putting the above together, we have:
    $ diff -u /opt/local/etc/dovecot/dovecot{-example,}.conf 
    --- /opt/local/etc/dovecot/dovecot-example.conf 2010-10-16 17:26:05.000000000 -0700
    +++ /opt/local/etc/dovecot/dovecot.conf 2010-10-23 11:36:26.000000000 -0700
    @@ -1,4 +1,5 @@
     ## Dovecot configuration file
    +# from dovecot-example.conf 2010-10-22 collin
     
     # If you're in a hurry, see http://wiki.dovecot.org/QuickConfiguration
     
    @@ -45,7 +46,7 @@
     # SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
     # matches the local IP (ie. you're connecting from the same computer), the
     # connection is considered secure and plaintext authentication is allowed.
    -#disable_plaintext_auth = yes
    +disable_plaintext_auth = no
     
     # Should all IMAP and POP3 processes be killed when Dovecot master process
     # shuts down. Setting this to "no" means that Dovecot can be upgraded without
    @@ -86,7 +87,7 @@
     #ssl_listen =
     
     # SSL/TLS support: yes, no, required. 
    -#ssl = yes
    +ssl = no
     
     # PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
     # dropping root privileges, so keep the key file unreadable by anyone but
    @@ -215,7 +216,7 @@
     #
     # See  for full list. Some examples:
     #
    -#   mail_location = maildir:~/Maildir
    +mail_location = maildir:~/Maildir
     #   mail_location = mbox:~/mail:INBOX=/var/mail/%u
     #   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
     #
    @@ -860,11 +861,11 @@
       # The deny passdb should always be specified before others, so it gets
       # checked first. Here's an example:
     
    -  #passdb passwd-file {
    +  passdb passwd-file {
         # File contains a list of usernames, one per line
    -    #args = /etc/dovecot.deny
    +    args = /opt/local/etc/dovecot/passwd.dovecot
         #deny = yes
    -  #}
    +  }
     
       # PAM authentication. Preferred nowadays by most systems. 
       # Note that PAM can only be used to verify if user's password is correct,
    @@ -872,7 +873,7 @@
       # database (passwd usually), you can use static userdb.
       # REMEMBER: You'll need /etc/pam.d/dovecot file created for PAM
       # authentication to actually work. 
    -  passdb pam {
    +  #passdb pam {
         # [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=]
         # [cache_key=] []
         #
    @@ -905,7 +906,7 @@
         #   args = session=yes %Ls
         #   args = cache_key=%u dovecot
         #args = dovecot
    -  }
    +  #}
     
       # System users (NSS, /etc/passwd, or similiar)
       # In many systems nowadays this uses Name Service Switch, which is
    $ dovecot -n
    # 1.2.14: /opt/local/etc/dovecot/dovecot.conf
    # OS: Darwin 10.3.3 i386  
    ssl: no
    disable_plaintext_auth: no
    login_dir: /opt/local/var/run/dovecot/login
    login_executable: /opt/local/libexec/dovecot/imap-login
    mail_location: maildir:~/Maildir
    auth default:
      passdb:
        driver: passwd-file
        args: /opt/local/etc/dovecot/passwd.dovecot
      userdb:
        driver: passwd
    $ 

Correct folder names

Fired up mail.app and it found the inbox: 382 unread of 4951 items, something like this. But! None of the folders were there. H'm... I obviously don't grok Maildir format.

[a few minutes later] Gaaaa! Need to modify the above (wrong) format! Folder names must begin with a dot! http://wiki.dovecot.org/MailboxFormat/Maildir#Directory_Structure says so. Remedy is here:

$ ls -F ~/Mail | grep / | cut -d/ -f1 | while read D; do 
     rm "Maildir/$D"; ln -s "~/Mail/$D" "Maildir/.$D"; done
rm: Maildir/inbox: No such file or directory
$ rm Maildir/.inbox 
$ 

With the correct directory names, I quit mail.app, then stopped dovecot -- like http://wiki.dovecot.org/RunningDovecot#Stopping says:

$ sudo cat /opt/local/var/run/dovecot/master.pid 
59267
$ sudo kill -s TERM 59267  # and wait a few seconds, then: 
$ sudo dovecot 
Brought mail.app back up... And that worked!

Oops, forgot nested folders. And more

If I have a folder Trips with subfolders Alaska and Hawaii, kmail apparently creates Mail/Trips, Mail/.Trips.directory/Alaska, Mail/.Trips.directory/Hawaii; those directories each have cur,new,tmp; therefore we'll do this:
$ cd Mail
$ find . -type d | grep directory | grep -ve '/cur$' -e '/new$' -e '/tmp$' | 
  grep '/[^.]' | sed -e 's:^./::' | while read F1; do 
      DEST=$(echo "$F1" | sed 's:.directory/:.:g'); 
      ln -s ~/Mail/"$F1" ~/Maildir/"$DEST"; done
$ 
Ah, almost! “sed 's:.directory/:.:g'” should probably instead be:
sed 's:\.directory/\.:.:g' | sed 's:\.directory/:.:g'

Here's something else!

$ ls -Ao Maildir
total 13008
lrwxr-xr-x  1 carol       11 Oct 23 11:57 .ACFW -> ~/Mail/ACFW
lrwxr-xr-x  1 carol       14 Oct 23 11:57 .AShland -> ~/Mail/AShland
...
Oops! Somehow I have a literal “~/” instead of /Users/carol/. Sigh... OK then...
$ cd Maildir
$ find . -type l | while read X; do 
      Y=$(readlink "$X"); 
      if [[ $Y == ~* ]] ; then ln -sf "${HOME}${Y#?}" "$X"; fi; 
   done
$ 

Real authentication

First up is creating SSL certificates; I'll start at http://wiki.dovecot.org/SSL.

No; we'll use IMAP and not disable plaintext. It's just home; I'm not running a business with secret information. And we don't put sensitive stuff in email anyway. This works:

$ diff dovecot-example.conf dovecot.conf 
1a2
> # from dovecot-example.conf 2010-10-22 collin
48c49
< #disable_plaintext_auth = yes
---
> disable_plaintext_auth = no
56c57
< #shutdown_clients = yes
---
> shutdown_clients = yes
89c90
< #ssl = yes
---
> ssl = no
218c219
< #   mail_location = maildir:~/Maildir
---
> mail_location = maildir:~/Maildir
907c908
<     #args = dovecot
---
>     args = login

Multiple addresses, outbound mail, address book

Fortunately I remembered this issue before the lovely Carol hit it while I was at the office. Sometimes I want to send email as myself, sometimes as an identity that results in replies coming back to both of us. So does the lovely Carol. Kmail allows multiple identities; mail.app does too. You can configure this by editing account preferences -- multiple email addresses, as shown in this nice article at hints.macworld.com .

Outbound mail works great too; I set the outbound mail server to be our ISP's server and everything Just Worked. Basically mail.app connects to the ISP (never mind postfix) and... yeah.

The address book turned out to be pretty easy. From kde's address book, export as CSV; copy file to Mac; from address book (the tan book with the big @ ) File→Import, select the file, validate how columns are imported, and bob's yer uncle.

Make dovecot run on boot

Followed these directions. Looks reasonable, but the test will be when she reboots the box. (I shut down the Linux box, then had to restart it for some reason; some filesystems hadn't been checked in 446 days...)