Wednesday, January 27, 2010

Resizing QEMU images with Win7 installed under Linux

Here's another Windows 7 post. I started with a 16GB virtual image for Windows and almost immediately ran out of space. It turns out that it's not that hard to resize your partition; I found a very helpful forum post on the subject written a few years ago, and a couple things have changed for Windows 7, so I'll post an updated method here.

First, I'm working from the poster's second set of instructions. He claims they're more dangerous, but they're really not. You never have to work on your only copy of your data; in fact, by the end you'll have three working copies of the drive. It's probably a good idea not to delete the extras until then, but if you are crunched for disk space that's fine. Make sure you have the following commands available: qemu-img, ntfsresize, hexedit. They all should be available in packages supplied by your distro. I'm starting from an image called win7.img, using an intermediate raw image called win7.raw, and ending with an image called win7.qcow2. Obviously, you should use whatever names you're comfortable with.

Before you start, be sure you shut down Windows normally last time you used it. Otherwise ntfsresize will refuse to touch the data.

First, your disk image is probably in qcow2 format. You need to convert it to "raw" format, which is just a flat readout of the data. Check the format:

$ qemu-img info win7.img

If necessary, convert to raw; this will take several minutes (where I have qcow2 you should put the format of your image):

$ qemu-img convert -f qcow2 win7.img -O raw win7.raw

Now expand the raw image by writing to a large offset in the file. This should run very quickly on most Linux filesystems, and not consume much extra space. The bs parameter specifies the "block size" for writes (in bytes) and the seek parameter the number of blocks to skip. So I will write 83886080 × 512 = 42949672960 bytes (40 GiB) in.

$ dd if=/dev/zero of=winb.raw bs=512 count=0 seek=83886080
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.2997e-05 s, 0.0 kB/s


Become root and use Linux's loopback device to operate on the raw image as if it were a real hard drive.

$ sudo su
(enter password)
# losetup /dev/loop0 win7.raw


Now you'll want to check out the fake disk geometry and edit the partition table using fdisk. You'll want to switch fdisk to display in units of sectors, print the partition table, delete the main partition, and remake a larger one in its place. Your input is in bold.

# fdisk /dev/loop0

The number of cylinders for this disk is set to 5221.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): u
Changing display/entry units to sectors

Command (m for help): p

Disk /dev/loop0: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x23830da9


      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1 * 2048 206847 102400 7 HPFS/NTFS
Partition 1 does not end on cylinder boundary.
/dev/loop0p2 206848 31455231 15624192 7 HPFS/NTFS

Windows 7 has created two NTFS partitions on my disk. The second one is the one we're interested in. Also note the disk geometry: 255 heads. If it doesn't say 255 heads, and your disk is large, it should say 255 heads. Obviously the disk geometry is completely made up, and I'm not really sure why Linux's loopback device should be expected to fake the same geometry as Qemu... comments on the forum suggest this value should always be 255. Anyway, on to editing the partition table entry. The number you use for the first sector must be the same as in the original partition table; for me that's 206848.

Command (m for help): d
Partition number (1-4): 2

Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First sector (63-83886079, default 63): 206848
Last sector, +sectors or +size{K,M,G} (206848-83886079, default 83886079):
Using default value 83886079

Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 7
Changed system type of partition 2 to 7 (HPFS/NTFS)

Command (m for help): p

Disk /dev/loop0: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x23830da9


      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1 * 2048 206847 102400 7 HPFS/NTFS
Partition 1 does not end on cylinder boundary.
/dev/loop0p2 206848 83886079 41839616 7 HPFS/NTFS

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 22: Invalid argument.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.


Now re-connect the partition table and check that it worked.

# losetup -d /dev/loop0
# losetup /dev/loop0 win7.raw
# fdisk -ul /dev/loop0

Disk /dev/loop0: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x23830da9


      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1 * 2048 206847 102400 7 HPFS/NTFS
Partition 1 does not end on cylinder boundary.
/dev/loop0p2 206848 83886079 41839616 7 HPFS/NTFS

# losetup -d /dev/loop0

Now, especially if you're resizing from a much smaller drive, we should check that each of the NTFS partitions has the correct number of heads stored in it (the forum post has an explanation of why this is important; to make a long story short, Windows won't start if it's wrong). To find the address of each partition, take its start value from fdisk and multiply by the sector size of 512 bytes. Then convert to hex.

# bc
2048*512
1048576
(this is the start of the first partition in bytes
206848*512
105906176
(this is the start of the second partition in bytes)
quit
# printf "%x %x\n" 1048576 105906176
100000 6500000
(these are the hexadecimal addresses)

Open win7.raw in hexedit; hit return to enter an address, enter the first address, hit return again. Now you're at the start of the first NTFS partition. At an offset 0x1A bytes from that is the head count. Navigate to that byte (if the original address was 0x100000 you'll be at 0x10001A). Make sure it's FF (the hex value of 255). If not, type over that byte with FF. Then do the exact same thing for the second address. Hit ctrl-x to exit, confirming changes if necessary.

Now you can use ntfsresize to actually resize the Windows partition. You have to connect the loopback device to the start of the partition you're resizing this time; this is the decimal version of the second offset you found in the last step. Before doing anything with ntfsresize we check that everything is OK using the -n flag.

# losetup -o105906176 /dev/loop0 win7.raw
# ntfsresize -n /dev/loop0
ntfsresize v2.0.0 (libntfs 10:0:0)
Device name : /dev/loop0
NTFS volume version: 3.1
Cluster size : 4096 bytes
Current volume size: 15999169024 bytes (16000 MB)
Current device size: 42843766784 bytes (42844 MB)
New volume size : 42843763200 bytes (42844 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use : 15875 MB (99.2%)
Collecting resizing constraints ...
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
The read-only test run ended successfully.


If your output is something like that you're ready to go. The default action is to expand the partition to its largest size, so you only need to run:

# ntfsresize /dev/loop0
Device name : /dev/loop0
NTFS volume version: 3.1
Cluster size : 4096 bytes
Current volume size: 15999169024 bytes (16000 MB)
Current device size: 42843766784 bytes (42844 MB)
New volume size : 42843763200 bytes (42844 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use : 15875 MB (99.2%)
Collecting resizing constraints ...
WARNING: Every sanity check passed and only the dangerous operations left.
Make sure that important data has been backed up! Power outage or computer
crash may result major data loss!
Are you sure you want to proceed (y/[n])? y
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
Syncing device ...
Successfully resized NTFS on device '/dev/loop0'.


Hopefully your result is something like the above. Now you can disconnect the loopback device and end the sudo session.

# losetup -d /dev/loop0
# exit


You should try out the new image by starting Qemu/KVM the way you usually would, except substituting the name of the new image for that of the old one. Windows will check the disk (because ntfsresize told it to), and everything should come out OK. If not, you still have the original disk image. If everything works you can delete your original image and go on -- if everything is broken you should delete the raw image, figure out what went wrong, and start over.

Now you probably don't want to keep the image around as a raw; qcow2 takes up less space on the host system and has a lot of nice features. You can easily convert it to qcow2 like this:

$ qemu-img convert -f raw win7.raw -O qcow2 win7.qcow2

Make sure the new qcow2 image works. If so, delete the raw image and you're done.

Thanks to poster IntuitiveNipple on the QEMU forum for writing a nice explanation of the bit-hacking necessary on NTFS, and the overall procedure for resizing images with Windows installed.

EDIT: I edited this post to fix table formatting in fdisk output.

Monday, January 18, 2010

The Windows 7 Chronicles: GNU Patch, mt.exe, and the horror of UAC

Real quick one here. patch is a nice little command-line utility. GNU provides a fine version, and there's a Windows build available through the GnuWin32 project. When you try to run it on Windows 7 you get UAC prompts. Why? It turns out that Windows guesses, based on the name of the program, that it's going to patch application files, and goes ahead and requests elevated permissions for it that it doesn't really need. This was discovered a long time ago and a bug was filed against GnuWin, because it's clearly their responsibility to code around Microsoft's incredibly stupid heuristics*.

*in·cred·i·bly stu·pid heu·ris·tics, n: Heuristics that happen to be wrong in my case.

The bug report lists a manifest that you can embed into patch.exe to fix the problem. It looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

Embedding it took me a while, but it's ultimately not that hard. First copy the manifest into a file somewhere. You have to use a tool called mt.exe, which is part of the Windows SDK. It's probably not in your path, but it's in the path of a Visual Studio Command Prompt. So open up one of those with admin permissions (under Win7: Start->All Programs->Microsoft Visual C++ 200x->Visual Studio Tools; right-click on Visual Studio 200x Command Prompt, select Run as administrator...). Then cd '\Program Files (x86)\GnuWin32\bin' (or wherever you've installed it) and mt -manifest yourfile -outputresource:patch.exe;1. Why ;1 at the end? Because Microsoft says so.

Wednesday, January 6, 2010

QEMU/KVM, Windows 7, blurry text

My mom got me a copy of Windows 7 for Christmas so I could run it in virtualization under Linux for development purposes (Audacity, mostly). That's been somewhat successful. I'm using KVM/QEMU and none of the audio devices that QEMU emulates have 64-bit Win7 drivers. Maybe I'll look at writing an emulation layer for a more modern sound card (it might be slightly easier to write a new 64-bit Windows driver for one of the cards QEMU already emulates, but it might be easier to get an addition to QEMU distributed widely). Anyway. I'm mostly writing this because I just solved a smaller, odder problem: the text in Windows just looked horrible! I generally prefer my text on Kubuntu to text on Windows*, but I didn't remember it being bad on Windows.

* I think people come to prefer the fonts and rendering style of the systems they use every day. I mostly use Kubuntu, and I find text easier to read there than anywhere else. It could just be that I like the font shapes better. FreeType (X11) and ClearType (Windows) look pretty similar given the same fonts, although there are some things FreeType can't do with hinting information because of patents. I find Mac OS X's font rendering ugly and hard to read, but that's probably just because it's more different and I'm not used to it.

So these days QEMU's virtual VGA window can be resized. When you do this it just scales everything in the window. Unfortunately this makes anti-aliased, sub-pixel rendered text (ClearType) and deliberately sharp graphics (Diesel Sweeties) look really bad. KDE lets you set a window to an exact numerical size, which should fix the problem, but it doesn't; the size includes window decorations. Lame.

So I found a little program called xdotool that, among many other things, lets you resize windows from the command line by client size. Rad. It's in the Ubuntu repos, even. But setting the client size to exactly Windows' resolution didn't help.

So I took some screenshots, blew 'em up in the GIMP, and found that the window size was one pixel too large in each dimension. With my Windows resolution set to 1152x864 I actually need the QEMU window's client size to be 1151x863. I'm not sure if this is a weird problem with Windows, QEMU, or X11... but it's weird. And now that it's fixed, everything looks OK in virtualized Windows.

Sunday, December 20, 2009

Denver Airport Concourse Comparo!

Yesterday while waiting for a connecting flight in Denver Airport with Jess I realized that I've spent an unreasonably large portion of my life waiting for connecting flights in Denver Airport. When Jess suggested that we find food my first thought was, "There's no good vegetarian food in this concourse. Let's go to the United concourse." And thus the Denver Airport Concourse Comparo was born.

Concourse A

  • Airlines: Frontier (17 gates plus several more in the small-plane area operated by Lynx), Continental (3), JetBlue (2), AeroMexico/Air Canada/Lufthansa (sharing 2 gates), British Airways, Mexicana, Midwest, AirTran, Alaska, Frontier JetExpress, Great Lakes (several in the small-plane area)
  • Food (constraints: cheap-ish, fast, vegetarian): The only place to get quick vegetarian food in the A Concourse is Panda Express, and there your choice is basically lo mein and... more lo mein. Oh, yeah, there's some place called Lefty's with some vegetarian stuff, but they're on my blacklist from a previous trip for only serving breakfast food at 8 AM. THIS IS AN AIRPORT, PEOPLE! TIME HAS NO MEANING HERE! That's what pushed me to the Panda Express... I'm sure breakfast exists in China, and maybe even breakfast food, but in America Panda Express will sell you mushy lo mein all day. Um, where was I? Concourse A has Hope's Cookies, which are OK. No trendy coffee joints, but apparently there's a Quiznos with espresso and a full bar.
  • Centerpiece Art (There is lots of public art in Denver Airport, and much of it is in the terminal, which is outside the scope of this comparo; I'm limiting myself to the centerpieces around the tram stations and vertically above): On one side twisted train tracks through a desert; on the other a semi-flattened globe anchored by structures evoking satellite dishes or grandstands. There's some kind of museum exhibit on the mezzanine level, but it's not memorable.

Comments: Frontier is a pretty good airline but its concourse is the worst in the airport.

Concourse B

  • Airline: United (16 bazillion gates), United Express (7 bazillion gates in each small-plane area).
  • Food: There's a pretty good quick Mexican place on the second level. Lots of variety. There's a TCBY. Annoying hipsters and chipper businessdroids rejoice: B Concourse has a Coffee Beanery, a Seattle's Best, two Starbuckses, and a Caribou Coffee. There's something called Pour la France. I didn't know la France was a liquid.
  • Centerpiece Art: There is a sculpture of an astronaut down in the tram station. The motorized walkway continues through the center area, leaving room only for some random neon squiggles and some arches, like something out of that crazy walkway in O'Hare from the United concourse to baggage claim.

Comments: B is the biggest and busiest concourse. This last time there was an enormous Crocs stand on the upper level. It's the most mall-like of the concourses (but not even approaching DFW). The art is not so hot, the crowds are crowdy, this concourse ranks in the middle.

Concourse C

Concourse C is the concourse you're not supposed to know about. It's really a top-C-cret military base. Say it out loud: top-C-cret. And they thought they could get away with it. If you want to figure this stuff out you have to think like they think. See the patterns.

  • Airlines: I guess the army or whoever it was (CIA? WTO? Illuminati?) put up fake airlines and stuff there: 12 gates for "Southwest" and another 5 for "Northwest" and "Delta". Like I believe that -- worst fake airline names ever, amirite? It's rounded out by "US Airways" and "American", which are almost as obvious. We didn't see no planes take off, that's for sure. Oh, and they put the whole concourse in a TIME VORTEX.
  • Food: There's a TCBY in there. Not as big as the one in B. And some place that claims to have tamales, we haven't tried them.
  • TIME VORTEX: When you enter the TIME VORTEX you see spinning pinwheels. When you leave the TIME VORTEX you see flashing lights and a swinging sickle. A++++++ very good TIME VORTEX. Would TIME VORTEX again.
  • Centerpiece Art: It's this awesome decayed garden. Only the truly enlightened can see it, which is how it got so decayed: most people can't even see C Concourse at all, let alone the garden, so nobody can maintain it. Hell, I have it on good word the President's secret puppet master himself can only see the garden through a shard of a mirror once belonging to his puppetmaster. I am on to something for sure!

Comments: Jess and I just took the tram here to see what it was and it opened our eyes. They paged Jess over the intercom, so she picked up an information phone and dialed the number for "paging". Except that's for when you want to page someone else, so she hung up and dialed information. They said the page was actually for a "Jessica Mylan", not her. We got the message loud and clear: we know you're here and we're watching. So we went to a gate for a "Southwest" flight to San Francisco and sat and waited. We started talking one of the people at the gate. An agent or a dummy? We introduced ourselves as Jessica Mylan and Billy Philbert. He said, "Didn't they just page you, over the intercom?" The agent at the gate called for boarding. Nobody lined up. We got the hell out of Concourse C.

Saturday, October 31, 2009

mingw32, wine, library paths

Here is yet another thing I'm posting here just because Google searches turn up this blog sometimes and it might help someone save some time. Audience is people building Windows binaries on Linux with the mingw32 cross compiler and testing them in Wine. I do this sometimes for work on the Audacity project, which with a few minor modifications builds nicely with mingw32 -- it doesn't work exactly like a VS compile, but it lets me test wxMSW behavior, which is sometimes useful.

So you're running Linux, you've set up a mingw32 cross compiler (on Ubuntu just get all the mingw32 packages), and built some libraries with it. And you've built programs that use those libraries. But all the libraries are installed in places like /usr/i586-mingw32msvc/lib and /usr/local/i586-mingw32/lib. As far as I can tell, as of Wine 1.0, to get Wine programs to see libraries in those locations is to add them to PATH in a registry key. Typically Wine is configured so that your Unix root shows up at drive Z. So run regedit and go to HKLM/System/CurrentControlSet/Control/Session Manager/Environment and add to PATH, for example, ;Z:\usr\i586-mingw32msvc\lib;Z:\usr\local\i586-mingw32\lib (your paths may vary).

You'll also need to install the mingw32 runtime DLL to your Wine, which is usually something like gunzip -c /usr/share/doc/mingw32-runtime/mingwm10.dll.gz > ~/.wine/drive_c/windows/system32/mingw10.dll.

If you don't like having Z: point at root (for some people it's good for Wine to be highly integrated -- others would rather have it as far from their normal system as possible) you can point drives specifically at your library paths using winecfg, or other similar tricks. Symlinks from within ~/.wine/drive_c might be another appealing option.

Wednesday, October 1, 2008

Gentoo libselinux coreutils silliness

This blog entry probably isn't interesting to anyone. I'm writing it because Blogger blogs often turn up in Google results and it might be useful to a random searcher. Point: if you have libselinux on your system and want to get rid of it because it doesn't belong in your profile and is masked and frequently causes lots of obnoxious warnings, you probably shouldn't just emerge -C libselinux. You also probably shouldn't just do a emerge --depclean libselinux or even emerge -C libselinux && revdep-rebuild --library=libselinux.so.1. They might not work.

Not only will they not work, the emerge -C libselinux might not even finish correctly. The problem is that coreutils will build against libselinux even if you USE=-selinux. One of the autoconfiggey scripts does it. There's a bug in Gentoo bugzilla but no official action has been taken yet. If you happen to have updated coreutils since libselinux turned up, after you delete /lib/libselinux.so.1, lots of stuff doesn't work. /bin/ls, for example. And plenty of other programs you take for granted, and that emerge needs to finish unmerging libselinux. This was my experience and that of others. Learn from it.

The first thing you need to do is get a coreutils that doesn't need libselinux. First just make sure you need to do this at all: ldd /bin/mv | grep selinux. If no results you're OK. emerge -C libselinux && revdep-rebuild --library=libselinux.so.1 is all you need. Otherwise a new build of coreutils is in order. The person that filed the Gentoo bug kindly provided a couple patches that do the trick perfectly. It took a bit of messing around to figure out exactly where to put 'em, though.

The way I did it was to create a partial portage overlay. It has just one package in it. Hey, might as well learn this stuff. Create the directory /usr/local/portage/sys-apps/coreutils and copy the ebuild from the main portage tree into it. Also copy over the files directory and its contents from the the main portage tree. Apply the ebuild patch to the ebuild, and download the other patch into the files directory. Then run ebuild $fn manifest, where $fn is the name of the ebuild. This builds the manifest file so portage doesn't suspect your ebuilds of mischief. Now set up PORTDIR_OVERLAY in your /etc/make.conf to include your overlay directory (/usr/local/portage). At this point you should just be able to emerge coreutils and you'll get a version with no libselinux dependency. Now you can safely unmerge libselinux, run revdep-rebuild, and drink some delicous beer. I recommend a porter for this occasion, for obvious reasons. Then you can get rid of the overlay, because you shouldn't need it anymore.

If you don't want to mess with overlays you can always just download the straight source of coreutils, patch it up similarly to how Andreas did, and install that; you can just overwrite it with officially sanctioned coreutils whenever you get around to it, or not. However you do it, check your resulting binaries to be sure they don't need libselinux.so.1 before unmerging it. Also make sure the binaries get installed to /bin and not /usr/local/bin so portage, etc. will find them. You knew that.

Wednesday, January 16, 2008

Enoch Root and Edward Abbey on the El

In Cryptonomicon Enoch Root devises an encryption scheme that he initially calls "Pontifex" and describes with the following perl script:

#!/usr/bin/perl -s
$f=$d?-1:1;$D=pack('C*',33..86);$p=shift;
$p=~y/a-z/A-Z/;$U='$D=~s/(.*)U$/U$1/;
$D=~s/[A-Z]/$k=ord($&)-64,&e/eg;$k=0;
while(<>){y/a-z/A-Z/;y/A-Z//dc;$o.=$_}$o.='X'
while length ($o)%5&&!$d;
$o=~s/X*$// if $d;$o=~s/.{5}/$& /g;
print"$o/n";sub v{$v=ord(substr($D,$_[0]))-32;
$v>53?53:$v}
sub w{$D=~s/(.{$_[0]})(.*)(.)/$2$1$3/}
sub e{eval"$U$V$V";$D=~s/(.*)([UV].*[UV])(.*)/$3$2$1/;
&w(&v(53));$k?(&w($k)):($c=&v(&v(0)),$c>53?&e:$c)}


(The program is somewhat obfuscated; to really understand it I had to type it out in a more readable form. Also, in reality the algorithm was designed by Bruce Schneier and the Perl script written by Ian Goldberg. Here is Bruce's description of the system)

It's later revealed that the same instructions, written in natural language instead of Perl, can be followed by a person with a deck of cards to generate a "keystream" of random-looking numbers. Two people that start with their decks in the same order can generate this same random sequence. The sender writes out his message, writes a number from the keystream under each letter, then circularly-shifts each letter forward in the alphabet by that number. The receiver receives a message that looks random to anyone else, circularly-shifts each letter backward by the same number the first person used, and the result is the original message. The whole system relies on a shared secret: the two people communicating know how to arrange the deck into its initial position, but nobody else does. In this sense it's similar to a one-time pad, where the communicators generate long sequences of random numbers while physically in contact and agree on which to use for which messages before they start communicating this way. The advantage is that in this case the shared secret, instead of pages full of numbers that can be physically confiscated by eavesdroppers, could be something memorizable, like (as Bruce Schneier suggests in an appendix to the novel) a simple system for generating a deck ordering based on Bridge scenarios published in some newspaper on the day the message was written. As with a one-time pad, there are two major ways that an eavesdropper could break it. First, by discovering the shared secret. Second, by discovering a bias, that is, by mathematically analyzing the keystream-generating algorithm and finding patterns in it. Finding a bias would cut down the number of likely keystreams, perhaps enough that they can all be checked by brute force. Such a bias has been found in Solitaire, as mentioned in Bruce Schneier's page, linked above.

So.

Today after work I got on a Brown-Line train at the Merchandise Mart stop to ride all the way out to Francisco to go to my gym. Doors open on the right at Merchandise Mart, so I entered the crowded train from the right and had to stop and stand in the doorway, looking towards the left of the train. Seated to the right of the doors on the opposite side were a woman reading a book (not very interesting to watch) and a man repeatedly shuffling and fanning a deck of cards (somewhat more interesting). This guy must not have had much to do, or was practicing to escape the Chicago winters to become a card dealer in Vegas. Or maybe he was an Enoch Root, well-practiced at his card transformations, memorizing or analyzing the keystream generated from his deck transformations. It wasn't all that interesting, though, so I started reading.

Maybe at the Sedgwick stop the woman next to him got up, and I was the closest person to the seat she left, so I sat down. The man continued to shuffle his cards, sometimes accidentally jabbing me with an elbow, occasionally sneaking a glance at my book. I don't read secretly, so he may have caught a bit of Edward Abbey's description of his lazy trip down the Colorado River just before the building of the dam to form Lake Powell. At Belmont he stood up and flicked a card from his deck perfectly into the middle of the seat. The two of hearts. He walked out of the train. Transfer to Red- and Purple-Line trains at Belmont? Unlikely. Transferring at Belmont is for fools and amateurs. A man of his caliber would have obviously known to transfer at Fullerton.

So anyway a woman walked on the train, looked at the card on the seat. She recognized immediately that the first number of the keystream was 28! She probably looked at me funny, like I'd put the card there for some reason, but I don't really know because I had my face buried in Desert Solitaire trying to contain my laughter. Joy, mirth and laughter are not allowed on CTA vehicles. Do not make eye contact with other customers. If you see something, say something! Play safe; ski only in clockwise direction. Let's all have fun together. Especially with doomsday looming. She pocketed the card, sat down and started reading.

Monday, December 3, 2007

More Urban Jungle Shit

My Dear Readership, this might be a little rudimentary. I apologize. I do not apologize for, nay, do not even acknowledge whatever factual errors you may think you've found. "But pineapples don't grow on trees, Al!" Poppycock! My daydreams err not, and I err not in reporting them!

Al let out a little laughing yelp as he released himself from the tree. He swung his legs a bit, as if running in the air, then deftly braced himself for the landing. Hit the ground rolling into a somersault and then to his feet, presenting in his outstretched arms a pineapple. He paused to stare out at the sky, across the endless ocean. Just for a second now, the sky would be there the next day, too. He twisted the leaves off, discarded them, and drew a long, curved knife from a sheath at his hip.

Al peeked into the kitchenshit drawer. No, not in there. Surveyed the pile of dishes next to the sink that he'd been reusing for the past few weeks. Nope. He went over to the dark red drainboard (one of the better purchasing decisions he'd made in recent years), lifted up a skillet and a baking pan, and again came up empty. Ha, he was in an apartment in Chicago in December. Now the light from the setting sun was going to cast a shadow of his body, chiseled from years of swimming in the ocean and swinging up and down from trees, long across the beach. The traitorous yellow star had dipped below the sprawl on the western horizon more than an hour before he'd left work. The dishwasher. Top shelf. Eureka, choppin' knife! He sliced through the pineapple longitudinally, placed each half down flush against the dark red cutting board, then cut each half longitudinally also. He wondered if the dishwasher was clean.

Al continued making his lengthwise cuts until he bored of it, and then began cutting the rind off of each slice, and dividing each into slightly-larger-than-bite-size pieces. Al always chopped things a little coarser than most people did. He attributed this to laziness and low standards. The pineapple pieces piled high on a blue plate behind the cutting board. Al stopped to think in the middle of the process. He first thought that it was a lot of pineapple. Next that he could all of it easily. But that it wouldn't be proper. And then that he could probably satisfy his immediate desire for pineapple with just the flesh clinging to the rinds. But that wouldn't be proper either.

No. Al was alone in his apartment. There was no circle of knitters meeting in the church basement implementing social control by gossiping about the eating methods of young men. There was good fruit on those rinds! He grabbed one of the rinds and stuck it in his mouth, scraping his teeth down the flesh side, squeezing the nectar down his throat. Juice dripped down his chin, onto the cutting board, over the rinds and yet-uncut slivers. He sucked the rind dry. He picked up another rind and did the same. The nectar burned in the splits of his wind-dried lips. It danced sweetly across his tongue, and he looked up again at the sun as it melted into the ocean, then looked back at the rest of the people on the beach. A few rolled their eyes at him as they swallowed their last morsels, and one of those grabbed him by the arm and mock-dragged him behind the rest of the group headed back towards the village. He did get one last look at the sun before it sank into the ocean.

Al hoped Dan would get home soon and help him eat some of this pineapple. There was no Saran Wrap in the place and he couldn't find half his Tupperware lids.

Thursday, October 25, 2007

Dialog between wind and bike

42An accountant and an economist once walked down a dirt road, along the banks of a crick. The accountant saw a frog, and did offer the economist $20,000 to eat it. So the economist ate the frog, and the accountant did verily pay him. 43Another half hour down the road the economist saw a frog. He offered the accountant $20,000 to eat the frog, and, yea, they agreed and fulfilled their contract. 44The accountant thus said unto the economist, 45“We have now our original sums of money, and we have both eaten frogs. We are no better off than before.” 46The economist paused and wisely intoned, 47“Only if you neglect that we have engaged in $40,000 of trade”