2011-04-27

How to write a simple echo and chat server in Ruby 1.8

This blog post is an introduction to TCP socket server programming and thread programming in Ruby 1.8. It also illustrates how compact and expressive Ruby code can be. The intended audience is Ruby beginners.

require 'socket'  # TCPServer
ss = TCPServer.new(1233)
loop {
  Thread.start(ss.accept) { |s|
    begin
      while line = s.gets;  # Returns nil on EOF.
        (s << "You wrote: #{line.inspect}\r\n").flush
      end
    rescue
      bt = $!.backtrace * "\n  "
      ($stderr << "error: #{$!.inspect}\n  #{bt}\n").flush
    ensure
      s.close
    end
  }
}

Use telnet 127.0.0.1 1233 to connect to the echo server as a new participant, and then type your chat message(s) terminated by Enter (newline). The echo server sends back each message it receives with the You wrote boilerplate around it. Multiple independent clients can connect to the chat server at a time.

The chat server:

require 'socket'  # TCPServer
require 'thread'  # Queue
ssock = TCPServer.new(1234)
msgs = Queue.new
participants = []
Thread.start {  # Send chat messages to participants.
  while msg = msgs.pop;  # Always true.
    participants.each { |s|
      (s << msg).flush rescue IOError
    }
  end
}
loop {
  Thread.start(ssock.accept) { |sock|
    participants << sock
    begin
      while line = sock.gets;  # Returns nil on EOF.
        msgs << ": #{line.chomp!}\r\n"
      end
    rescue
      bt = $!.backtrace * "\n  "
      ($stderr << "error: #{$!.inspect}\n  #{bt}\n").flush
    ensure
      participants.delete sock
      sock.close
    end
  }
}

Use telnet 127.0.0.1 1234 to connect to the chat server as a new participant, and then type your chat message(s) terminated by Enter (newline). The chat server sends each message (with a colon prepended) to all connected participants.

The Ruby source files above demonstrate the following:

  • how to create a thread
  • how to use thread-local variables (e.g. sock)
  • how to report exceptions in a thread
  • how to ignore IOError
  • how to read a line from a socket
  • how to use the Queue class for synchronization between threads
  • how to clean up using an ensure block
  • how to pass values to a newly created thread

2011-04-09

python-xattr-compat: portable Python module to query and set POSIX extended attributes of files

This blog post is an announcement of python-xattr-compat, a portable Python 2.x module to query and set POSIX extended attributes of files.

python-xattr-compat is a wrapper around the xattr Python package, but if xattr is not available, python-xattr-compat provides compatible replacement implementations (using the dl or ctypes modules) for some systems (currently Linux), so we have a pure Python implementation for extended attribute manipulations.

How it works: Many scripting languages have a syscall function to call arbitrary system calls (like lsetxattr(2)). Python doesn't have syscall built in, but it has the dl and ctypes modules, which let the programmer call functions in any C library, lincluding libc. Since libc on Linux has wrappers for syscall and lsetxattr etc., we can call these to get system-specific extended attribute manipulation without installing non-built-in Python extensions like xattr.

2011-04-03

How to install CyanogenMod onto the ZTE Blade

This blog post explains how I managed to install CyanogenMod to a ZTE Blade phone (both Gen 1 and Gen 2). Please note that there can be multiple solutions, some of them working only on some phone submodels. The solution I give here did work on the model I had.

Pick one of the methods below.

Method one: without rooting the phone (recommended)

This method is recommended, because it is the more straightforward and safer method. Although its description is longer than of method two, doing method one is faster.

You will need a USB cable to connect the phone to a computer and an SD card in the phone.

Instructions:

  1. Make a backup of your data on the phone, this page has some suggestions how (don't use Titanium Backup though, because that needs a rooted phone). You may safely skip this step if you don't have any SMS, phone call log entry, application data, application configuration etc. to save (e.g. because the phone is new and you haven't customized it yet).
  2. Make sure you know your wifi connection credentials (e.g. network name, security type, passphrase).
  3. Make sure you know your Google account name (e-mail address) and password.
  4. On the phone: Settings » Applications » Development » enable USB Debugging.
  5. On the phone: Settings » Applications » enable Unknown sources – Allow installation of non-Market applications
  6. Install the Ask Mr Pigfish application from the Market, run Ask Mr Pigfish, and see it displaying the generation number of your phone (gen1 or gen2). Take a not on paper containing the generation number.
  7. Install the adb and the fastboot tools to your computer. For Linux, see How to install instructions below. For Windows or Mac, see this page. Another download for fastboot is on this page.
  8. The command lines in following instructions are for Linux. Do it similarly on Mac and Windows (e.g. instead of wget, use your browser or download manager to download the file).
  9. Download the ClockworkMod recovery with wget -O /tmp/recovery-clockwork-3.0.1.4-blade.img http://android.d3xt3r01.tk/cyanogen/blade/recovery/recovery-clockwork-3.0.1.4-blade.img
  10. Download the latest version of CyanogenMod from this page. When these instructions were written, the equivalent download command was: wget -O /tmp/update-cm-7.0.0-RC4-Blade-signed.zip http://mirror.cyanogenmod.com/get/update-cm-7.0.0-RC4-Blade-signed.zip
  11. Download the latest version of Google Apps from this page. When these instructions were written, the equivalent download command was: wget -O /tmp/gapps-gb-20110307-signed.zip http://android.d3xt3r01.tk/cyanogen/gapps/gapps-gb-20110307-signed.zip
  12. If already connected, disconnect the phone from the computer.
  13. Remove the SIM card from the phone if you don't have a data plan. This is to prevent the unconfigured CyanogenMod from making expensive data transfers before the wifi is configured. This needs powering off your phone first.
  14. Power the phone back on and wait for it to start up.
  15. Connect the phone to the computer using the USB cable. The phone should display a notification that an USB cable is connected (and possibly another notification that USB debugging is enabled).
  16. Run adb devices on the computer, it should display something like
    List of devices attached 
    Blade-CM7       device
  17. Copy the CyanogenMod ZIP file to the SD card by running adb push /tmp/update-cm-7.0.0-RC4-Blade-signed.zip /sdcard/cm.zip
  18. Copy the Google Apps ZIP file to the SD card by running adb push /tmp/gapps-gb-20110307-signed.zip /sdcard/gapps.zip
  19. To prevent data loss below, make sure the phone is fully charged. You can charge it quickly if you connect it to a wall socket instead of a computer.
  20. If you have a gen1 phone and you want to install CyanogenMod 7.0.1 or later, then upgrade your phone to gen2 by following the How to upgrade a gen1 phone to gen2 and start ClockworkMod recovery below. Otherwise, follow these instructions:
    1. Reboot the phone to fastboot mode by running adb reboot bootloader
    2. Wait for about 20 seconds until the phone reboots into bootloader mode, showing only the green android logo on the screen. (If your phone boots normally a few seconds later, then this method has failed for you, please choose another method to install CyanogenMod to your phone. You may try removing the battery, reinserting the battery, holding the Volume Up key on the phone, and powering on the phone while Volume Up is still held.)
    3. Run fastboot flash recovery /tmp/recovery-clockwork-3.0.1.4-blade.img
    4. Run fastboot reboot
    5. Wait for the phone to start up and detect that the USB cable is connected.
    6. Run adb reboot recovery (this should take about 5 seconds).
    7. Wait for about 5 seconds until the phone reboots into recovery mode, running the ClockworkMod recovery.
  21. Your phone should be running ClockworkMod recovery now. It should display ClockworkMod Recovery v3.0.1.4 (or a larger version number) and a menu below, starting with reboot system now. Use the Volume Up and Volume Down keys to navigate the menu up or down. Navigate to the advanced item, use the Home button to select it. Use the Back button to go back to the main menu.
  22. Select the main menu option Wipe data/factory reset
  23. Select the main menu option Wipe cache partition
  24. Select the main menu option Install zip from sdcard
  25. Select the menu option Choose zip from sdcard
  26. Select cm.zip . This will install CyanogenMod.
  27. Go back to the main menu. Select the main menu option Install zip from sdcard
  28. Select the menu option Choose zip from sdcard
  29. Select gapps.zip . This will install Google Apps.
  30. Go back to the main menu.
  31. Select the main menu option reboot system now
  32. CyanogenMod should be booting now. Configure everything for your needs.
  33. Use the Menu button to configure the wifi first (i.e. below you enter your Google account password).
  34. CyanogenMod might ask you which Google applications to install. If unsure, select all of them. After you make your selection, CyanogenMod will take you the Market page of all these applications. Accept and install them one by one.
  35. If you don't have a data plan, make sure you configure the phone so it won't accidentally make data transfers.
  36. Reinsert the SIM card. This needs powering off your phone first.

How to install adb and fastboot on Linux

# You might need to use anoter package manager for installation:
$ sudo apt-get install wget unzip
$ wget -O /tmp/linux_adb_fastboot.zip \
  http://android.d3xt3r01.tk/cyanogen/tools/linux_adb_fastboot.zip
$ (cd /usr/local/bin && sudo unzip /tmp/linux_adb_fastboot.zip)
$ sudo killall -9 adb
# This starts the daemon. `sudo' is not necessary on some systems.
$ sudo /usr/local/bin/adb devices

How to upgrade a gen1 phone to gen2 and start ClockworkMod recovery

Don't follow these steps unless you are asked to by another step in this howto.

Please note that these instructions apply only to gen1 (1st generation) ZTE Blade models. Doing it on any other phone (i.e. on a gen2 ZTE Blade or any phone other than a ZTE Blade) will most probably make the device useless beyond repair. You can use the Ask Mr Pigfish application (available from the Android Market) to check if you have a gen1 ZTE Blade.

Please note that by following these instructions, not only the configuration and user data, but the operating system will also be removed from the phone. (But the contents of the SD card will remain intact.) To make your (gen2) device useful after these instructions, you should already have an operating system installer ZIP file (e.g. cm.zip above) already on the SD card.

Instructions:

  1. Download the ZIP file Gen1-to-Gen2-TPT-v2.zip from here. The download link can also be found in the section Update to Gen2 Radio of this page.
  2. Unzip the contents of the ZIP file to the SD card, so there should be a folder named image in the root folder of the SD card, and that folder should contain 17 files, from amss.mbn to userdata.img . Make sure that the image folder is in the root folder of the SD card. The easiest way to do this is connecting your phone to the computer using the USB cable, mounting the SD card (using the notification area of the phone), and running a ZIP file extractor on the computer. Disconnect the drive from the computer, and umount the SD card when done.
  3. Make sure the phone is fully charged.
  4. Disconnect the phone from the computer and the charger.
  5. Turn off the phone (by long pressing the power button).
  6. Remove the battery.
  7. Reinsert the battery.
  8. Hold the volume up and menu buttons. Don't release them yet.
  9. (Before doing this, read the next instruction step.) Push the power button to turn the phone on.
  10. Text in green would start appearing on a black background. Release the volume up and menu buttons.
  11. More text in green would start appearing with some indication of progress percentage. Wait for 30 seconds until its done.
  12. The phone boots to ClockworkMod Recovery .

Method two: rooting the phone first

You will need an SD card in the phone.

Outline (see the detailed instructions in the links below):

  1. Make a backup of your data on the phone. (See in method two below.)
  2. Make sure you know your wifi connection credentials (e.g. network name, security type, passphrase).
  3. Make sure you know your Google account name (e-mail address) and password.
  4. Root the phone.
  5. Install the ROM Manager application (from the Android Market).
  6. Install ClockworkMod recovery using the ROM Manager application. (This step needs a rooted phone.)
  7. Download the CyanogenMod update ZIP file (and possibly the Google Apps ZIP file) to the /sdcard.
  8. To prevent data loss below, make sure the phone is fully charged. You can charge it quickly if you connect it to a wall socket instead of a computer.
  9. Remove the SIM card from the phone if you don't have a data plan. This is to prevent the unconfigured CyanogenMod from making expensive data transfers before the wifi is configured. This needs powering off your phone first.
  10. Use the ROM Manager application to start the ClockworkMod recovery.
  11. Within ClockworkMod recovery, wipe the phone.
  12. Within ClockworkMod recovery, install the CyanogenMod update ZIP file (and possibly the Google Apps ZIP file)
  13. Within ClockworkMod recovery, reboot the phone.
  14. CyanogenMod should be booting now. Configure everything for your needs.
  15. If you don't have a data plan, make sure you configure the phone so it won't accidentally make data transfers.
  16. Reinsert the SIM card. This needs powering off your phone first.

All these steps worked for me as explained in detail on the official install CyagnogenMod to ZTE Blade page, except for rooting the phone. That page and also most other web sites instruct the user to reboot the fastboot mode by holding the Volume Up key while powering up the phone. This didn't work for me, because my ZTE Blade had fastboot disabled (so it always booted normally). So I had to find another way to root the phone. The instructions on this page (those containing tinyurl.com/urooted) worked for me. These instructions use a version of the Universal Androot application specialized to the ZTE Blade. Please note that Universal Androot claims that the phone is already rooted — just ignore this message and root it anyway. Please also note that during the installation process you have to re-root the phone using Universal Androot each time you reboot the phone. So if ROM Manager complains that your phone is not rooted, then just run Universal Androot again, and then retry in ROM Manager.

Performance

If the phone feels slow and games are not enjoyable, then tune the performance settings:

  1. Make sure that the latest version of CyanogenMod (at least 7.0.0 without RC in the version number) is installed. Get the newest version of the ZIP file from here. Copy the ZIP file to the (root of the) SD card. Reboot the phone to recovery mode (using adb reboot recovery or the ROM Manager application). In recovery mode, clear the cache and then select the update file (the ZIP file), install it, and reboot the phone.
  2. Make sure that Application / Settings / CyanogenMOD Settings / Performance / Enable surface dithering is off.
  3. In Application / Spare Parts make sure that all animations are disabled.
  4. There seems to be no need for enabling GPU acceleration (debug.sf.hw=1 in /system/build.prop), CyanogenMod seems to be fast without it.