I started a little quest three months ago when I decided to purchase a netbook. I found those small devices extremely useful for me. Also, as a bonus, they are relatively cheap.
I started trying the acer one. It didn't quiet work for me. The performance was what I was looking for but it had a couple of big problems. First, the keyboard: extremely small and almost unusable if you are planning to do some serious typing. Also, the screen is too small, 8 inches is not enough for me.
My next attempt was the HP 1000. This one was the opposite of the acer: excellent keyboard but bad performance. With also another negative bonus: it run extremely hot. The Via C7 is just not what I need for my netbook.
Finally the Samsung NC10 came along. That was my winner. It basically has the best of the acer and the HP 1000. Very nice and usable keyboard, 10 inches screen and a Intel Atom cpu.
I planned to run an open source OS on it, most likely Linux so hardware compatibility was important for me. The NC10 hardware works out of the box with the latest versions of the Linux kernel and the latest Ubuntu/Fedora.
I performed an out of the box installation of fedora 10. Everything worked just fine: Video, suspend, hibernate, sound, wireless, etc... I used the netbook for around with more or less the default software that came with fedora. But gnome is too much for a netbook. Don't get me wrong, it works fine, but come on, we can do better than that. Then dwm came along. I don't recall how I found that amazing window manager but I am extremely happy I found it. It is exactly what I was looking for. First of all it allows me to control the computer mostly with the keyboard. On the other hand it is extremely fast and light. Actually I doubt it gets lighter than that.
Don't get scared by the minimalistic approach of dwm. If you try it, you will never go back to your old window manager. Check out the links I have in my delicious account (drio), under dwm. That's a pretty good start point. Don't forget of course the README.
Once you switch to dwm you lose all the convenient features you get for free in gnome: battery info, brightness control using fn keys, suspend/hibernate, wireless GUI wrapper, etc...
There are easy work arounds to that. Let's go one by one. For the battery info you can use the acpi command. Even better, use it to display info in your status bar. You'll find the details in the links I mentioned above.
For the brightness control use xbacklight. For example, to increase the brightness 10% do:
$ xbacklight -dec 10Of course these little tools work because your kernel has access to the hardware.
For the suspend/hibernate, use the pm-utils. Gnome goes a step forward and hooks the power button to these tools. We could do the same but I am particularly fine just using the pm-utils from the console.
Finally the wireless. The device driver that interacts with the wireless card is the ath5k. There are other options out there but this one works just fine for me. Again, you can probably fire a GUI iwconfig wrapper but I prefer the console. And particularly, for home, I use this script:
#!/bin/bash sudo rmmod ath5k sleep 0.5 sudo modprobe ath5k sleep 0.5 sudo ifconfig wlan0 down sleep 0.5 sudo ifconfig wlan0 up sleep 0.5 sudo iwconfig wlan0 ap XX:XX:XX:XX:XX:XX sleep 0.5 sudo iwconfig wlan0 essid "myessid" sleep 0.5 sudo killall dhclient sleep 1 sudo dhclient -v wlan0
Have you ever wonder how Rails and other ruby based frameworks include backtrace information whenever there is an exception? Me too. It is very well explained in the TRPL (The Ruby Programming Language). Check out this code:
SCRIPT_LINES__ = {__FILE__ => File.readlines(__FILE__)}
class Foo
def lala
code = []
(0..3).each { |i| code << SCRIPT_LINES__[__FILE__][__LINE__-(4-i)] }
raise ArgumentError,
"\n Problems here:\n #{"_" * 40}\n #{code} #{"_" * 40}\n ",
caller
end
def foo
lala
end
end
Foo.new.foo
If you run it (1.8.7), you'll get something like:
./foo.rb:14:in `foo': (ArgumentError) Problems here:
________________________________________
class Foo
def lala
code = []
(0..3).each { |i| code << SCRIPT_LINES__[__FILE__][__LINE__-(4-i)] }
________________________________________
from ./foo.rb:18
That is quite similar to the output you get in one of those frameworks we
were mentioning before. Yes, already, not as nicer. The secret is that
SCRIPT_LINES__ constant. There we hash our code file and then we use when
necessary. Here while raising an exception.
posted at: 13:47 | path: /ruby | permanent link to this entry
I came across these bits while going over ruby-talk:
class A < Struct.new(:a, :b)
def initialize(h)
# . (*self.class.members.map {|s| s.intern}
# self is A, but A extends Struct. .members return an array with
# all the names of the instance variables. We iterate over them with map
# and then we we call .intern to return the :symbol of it.
#
super *h.values_at(*self.class.members.map {|s| s.intern})
end
end
a = A.new(:a => 1, :b => 2)
p a
It is a very nice way to extend Struct so you instantiate the class by passing a Hash with attributes and values that you want to store in the struct.
That sort of inspired me to write this to help another developer:
# input.txt
# c,d,a,b
# 3,4,1,2
# Read first line and order the input
l1 = File.open("./input.txt", "r").read.split[1].split(',')
# Create a struct class to hold the stats per lane
line_stats = Struct.new(:c, :d, :a, :b)
# Instantiate a stat lines with the input data
l1_stats = line_stats.new(*l1)
# Display the contents of the struct
puts l1_stats.inspect
To get an idea about the domain of the problem. We want here to parse a
csv file, store the entries in memory and then call a perl script using
those values. There are a couple of things I would highlight about that
code. First of all, the nice way we can tell a ruby method that we
are sending the arguments in an array. Also, the Struct class fits right
in and avoid a bunch of lines of code.
posted at: 23:32 | path: /ruby | permanent link to this entry
Solid to SRF package from ABi in macosx
ABi has recently released a binary package that converts solid data into SRF (sort read format). That package was only tested and developed on linux, as usual, and it doesn't compile in macosx out of the box. Fortunately we have the source code.
Here you have the patch to make it work on osx:
From d8d85a3d4413be0c3523dbe0e977208cac3dca0e Mon Sep 17 00:00:00 2001 From: drioDate: Tue, 16 Sep 2008 13:06:32 -0500 Subject: [PATCH] Makes it compile on osx --- solid2srf-0.7.3/SRF/base/SRF_util.hh | 2 +- solid2srf-0.7.3/ZTR/src/ZTR_util.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solid2srf-0.7.3/SRF/base/SRF_util.hh b/solid2srf-0.7.3/SRF/base/SRF_util.hh index 1530700..b832065 100644 --- a/solid2srf-0.7.3/SRF/base/SRF_util.hh +++ b/solid2srf-0.7.3/SRF/base/SRF_util.hh @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include ADOPT char* SRF_cStrToPascalStr( const char* str ); diff --git a/solid2srf-0.7.3/ZTR/src/ZTR_util.hh b/solid2srf-0.7.3/ZTR/src/ZTR_util.hh index 08199c3..5f48f16 100644 --- a/solid2srf-0.7.3/ZTR/src/ZTR_util.hh +++ b/solid2srf-0.7.3/ZTR/src/ZTR_util.hh @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include // put in a global include -- 1.5.6.5
As you can see the patch is trivial, there are a couple of includes that have to change
in macosx.
posted at: 13:10 | path: /bioinformatics | permanent link to this entry
Working with ruby 1.9 and 1.8 (from trunk)
I want to start playing with 1.9 but I want to keep 1.8 around. And also, I want to have the *latest* version of each branch. This is what I came up with:
$ pwd /Users/drio/ruby $ svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby $ svn co http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8 $ cd ruby $ autoconf && ./configure --prefix=/Users/drio/local/ruby1.9 && make -j8 && make install $ cd ../ruby_1_8 $ autoconf && ./configure --prefix=/Users/drio/local/ruby1.8 && make -j8 && make install // add /Users/drio/local/ruby_local/bin to your path (change your user name of course)
Now, use this bash function:
funtion rversion() {
r_local="$HOME/local/ruby_local"
rm -rf $r_local && mkdir $r_local && cd $r_local
case "$1" in
'8')
version="ruby1.8"
l_dirs="bin lib share"
;;
'9')
version="ruby1.9"
l_dirs="bin include lib share"
;;
*)
echo "8 or 9 ?"
;;
esac
for d in $l_dirs
do
echo "linking $version/$d"
ln -s ../$version/$d .
done
cd - > /dev/null
}
Load that function and now, from the shell:
drio@lupita:~ $ rversion 8 linking ruby1.8/bin linking ruby1.8/lib linking ruby1.8/share drio@lupita:~ $ ruby --version ruby 1.8.7 (2008-09-03 revision 19079) [i386-darwin9.4.0] drio@lupita:~ $ rversion 9 linking ruby1.9/bin linking ruby1.9/include linking ruby1.9/lib linking ruby1.9/share drio@lupita:~ $ ruby --version ruby 1.9.0 (2008-09-07 revision 19210) [i386-darwin9.4.0]
Ruby long star conference, day 1
This year I am attending to the lone star lone star ruby conference in Austin, TX.
My first day was very interesting. I took a cap from the hotel to the conference center, then some crappy food for breakfast and then some training:
First one: Test Driven Development. I think we have already heart about this and hopefully we/you are already testing your code. Perhaps you are just writing your tests after writing your code. With this method, you write your test code first, then you code to make the test pass and so on.
I found interesting when they talk about rcov, a tool to calculate the test coverage of your code. Basically it shows you statistics about how many lines in your code haven't been covered by your tests.
The second talk I attended to was: the ins and outs of ruby IOs. The talk was also very
interesting but not what I expected. I missed more technical details about how ruby
interacts with the OS and how we can really improve, if possible, I/O against the filesystem.
Nonetheless quite interesting. James is a great speaker and his slides where impeccable,
full of interesting examples. I'll probably create another entry talking more about this
once I'll watch the slides again. The keynotes for the second day are starting now ... fun!
posted at: 09:09 | path: /ruby | permanent link to this entry
Para_srf: Convert your SoLiD data to srf, fast.
As you know, I released the para_srf version 0.2 in github some weeks ago. I have made some changes since then and I have put a new version available. This new version doesn't bring huge new changes. Mainly I added some integration tests. Very valuable by the way.
I am going to release a new version soon that will fix a little
issue Jingwei from ABi found. The current version splits the input
data in smaller chunks. By doing that, we may end up loosing some
pairing information since not all the reads have a pair. In order
to ensure the srf converter has the information for all the pairs
we have to perform the split base on the panels. For example:
first split panels from 1 to 20, split 2, panels from 21 to 40 and
so on.
posted at: 21:17 | path: /programming | permanent link to this entry
Using a macpro for bioinformatics research
Our group decided four months ago to get mac pro to help us in our research. The idea was having a unix box with some decent disk and ram to help us run our bioinformatics code. As a matter of fact we ended up using it in our SOLiD ABi pipeline. The machine has run most of our offline analysis for human dna samples.
The machine has been serving pretty well for its main task. Now that our LSF cluster starts behaving a little bit better we can use the spare cycles for other jobs. A colleague contacted me asking me for access to our machine. His group needed to run some perl code that was suppose to use more than 4G or ram. The first thing we checked was if our perl distribution (macports) was 64 bits. It wasn't. I must admit I didn't even care until then. But I always thought the binary would be 64 bits. It was not:
drio@arad /hgsc/solid/corona_lite/bin $ otool -tv ./mapreads ./mapreads: (__TEXT,__text) section start: 00002468 pushl $0x00 __SNIP___ 00002495 movl %ebx,0x0c(%esp) 00002499 calll 0x00004cf2 0000249e movl %eax,0x00(%esp) 000024a2 calll 0x00101081 __SNIP__
My first thought was, oh well, less check the macports framework, I am sure they had some flags to recompile in 64 bits mode. There isn't. I even asked in the IRC channel. The next logical move was to try to compile everything from scratch, but, the effort will be too much. I would had had to recompile not only perl but also all the dependencies.
All these made me reconsider if a macpro is a ideal machine for this
kind of tasks. The machine has already paid off his cost with all the
solid analysis we have done with it. But, now, if we want to run some
ram intensive code, we are a little bit screwed up. A Dell/HP/etc...
linux box will be perfect here (Check my other posts, we got one).
Another issue here is the noise. Initially we got the macpro because
it was very powerful yet very quiet. There is nothing like that
in the PC market. But, well, who cares, I can put the machine in the
lab, in front of the sequencers. Noise is not a problem there.
posted at: 20:58 | path: /apple | permanent link to this entry
I was in the market for an external storage array. I needed around 10Tb of space to run illumina's offline analysis. Our current LSF cluster is not stable enough and the resources are very limited.
I ordered a Dell MD3000 and a 2 cpus x 4 cores AMD machine with a SASe5 raid controller to hook up the MD3k.
My initial idea was to setup a Raid6 11Tb virtual disk and to format it for xfs. By the way, I was using CentOS since dell supports redhat for that hardware.
After reading some basic documentation I hooked the MD3k to the server (I ended up calling it milhouse). I wasn't sure how the server sends the commands to the md3k to configure the system. I setup a vtrack storage array two months ago and the configuration was done over ethernet. This array also allows that but if your server is physically connected to the md3k, that's the only thing you need.
The software installation wasn't very complicate. The CD comes with some rpms that install device drivers and some tools to control the array. I decide to start using the GUI, a java tool.
When I started it I thought, well, this is pretty typical. But then I had this issue: I couldn't configure volumes bigger than 2Tb. I spent a lot of time searching the documentation. The vtrak allowed me to configure a RAID6 11TB volume without problems.
Tired of searching I decided to pull from Linux once again: particularly from LVM. I created 6 volumes in the array and then I exposed them to linux. Once that was done I setup a lvm volume to join them, and finally I created the actual disk.
drio@milhouse ~/tmp $ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
128G 5.3G 116G 5% /
/dev/sda3 99M 28M 66M 30% /boot
tmpfs 16G 0 16G 0% /dev/shm
/dev/mapper/md3000-slx
11T 174G 11T 2% /mnt/slx
After some more research I found here
that the Dell MD3000 is a re-branded LSI/Engenio array. In that same blog entry, you have
a link to the LSI/Engio documentation. Much better than the Dell one.
posted at: 21:07 | path: /hardware | permanent link to this entry
Para_srf: Convert your SoLiD data to srf, fast.
I have just created a git repo for my para_srf project. This software paralellizes the SRF conversion of solid data.
The amount of sequence we get out of one ABi sequencer is extremely high. Performing the conversion in a non concurrent way can take a long time. This software parallelize the tasks so the whole process gets done much faster. Currently works only with LSF clusters but adding other alternatives is very simple.
This is the git url:
git://github.com/drio/para_srf.git
IRC is and old and yet extremely rewarding protocol. I have been there, in various channels for around 3 years now and I have found great people, always willing to help. I have found some trolls also, but that is a minority, I think.
Let me put a real example:
16:40:19 < drio> Is there any way to move around between tabs without having to go one by one.... 16:41:52 < samuel-veyre> drio : was you around five minutes ago ? ... try gt3 to go to tab 3 for example. 16:42:37 < samuel-veyre> drio, :he tabpage
The question is, are you going to be able to remember all this gems. I don't, in some cases. I just use and then I forgot, unless I use it over and over again. Quicksilver to the rescue here.
Let's say you are in #ruby and #vim, create some files like:
$ ls -lac the_knowledge_pool/ total 8 drwxr-xr-x 5 drio staff 170 Aug 6 16:46 . drwx------+ 69 drio staff 2346 Aug 7 17:18 .. -rw-r--r-- 1 drio staff 0 Jul 25 10:17 ruby.txt -rw-r--r-- 1 drio staff 0 Jul 25 10:11 todo.txt -rw-r--r--@ 1 drio staff 0 Aug 6 16:46 vim.txt
Once that is done, make quicksilver load those files so you can access them easily. Then, when you get a gem from IRC, just use the "append to" in quicksilver to add the bits to the particular txt file.
I was in the market for an external storage array. I needed around 10Tb of space to run illumina's offline analysis. Our current LSF cluster is not stable enough and the resources are very limited.
I ordered a Dell MD3000 and a 2 cpus x 4 cores AMD machine with a SASe5 raid controller to hook up the MD3k.
My initial idea was to setup a Raid6 11Tb virtual disk and to format it for xfs. By the way, I was using CentOS since dell supports redhat for that hardware.
After reading some basic documentation I hooked the MD3k to the server (I ended up calling it milhouse). I wasn't sure how the server sends the commands to the md3k to configure the system. I setup a vtrack storage array two months ago and the configuration was done over ethernet. This array also allows that but if your server is physically connected to the md3k, that's the only thing you need.
The software installation wasn't very complicate. The CD comes with some rpms that install device drivers and some tools to control the array. I decide to start using the GUI, a java tool.
When I started it I thought, well, this is pretty typical. But then I had this issue: I couldn't configure volumes bigger than 2Tb. I spent a lot of time searching the documentation. The vtrak allowed me to configure a RAID6 11TB volume without problems.
Tired of searching I decided to pull from Linux once again: particularly from LVM. I created 6 volumes in the array and then I exposed them to linux. Once that was done I setup a lvm volume to join them, and finally I created the actual disk.
drio@milhouse ~/tmp $ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
128G 5.3G 116G 5% /
/dev/sda3 99M 28M 66M 30% /boot
tmpfs 16G 0 16G 0% /dev/shm
/dev/mapper/md3000-slx
11T 174G 11T 2% /mnt/slx
After some more research I found ="http://blogs.smugmug.com/don/2007/10/01/dell-md3000-great-das-db-storage/">here
that the Dell MD3000 is a re-branded LSI/Engenio array. In that same blog entry, you have
a link to the LSI/Engio documentation. Much better than the Dell one.
posted at: 09:40 | path: /bioinformatics | permanent link to this entry
What's this cool picture about? Keep reading and you'll find out.
During my third year of college I was lucky enough to join a very nice group of people that started what is today iwith. From the iwith's site:
"Iwith.org's mission is to promote information and communication technologies as tools for solidarity and progress in society."
Recently I got an email from my friend Jordi, Iwith co-founder, letting me know they were going to have a Forum in Barcelona (Catalonia). The main topics of the forum are going to be: Broadcasting video on the Internet, Web2.0 and NGOs. The other main organizer of this event, besides Iwith, is the alternative channel.
If you read this and you are interested, there are different ways you can contribute:
So if you think you can help, please contact
the organizer's team.
posted at: 23:25 | path: /misc | permanent link to this entry
It is time to upgrade to 1.1.4 after confirming that the latest ziphone version works fine with 1.1.4. Thanks to Dani for showing my the right steps to do this: NOTE: I have a 1.1.3 iphone, unlocked + jailb NOTE 2: DO NOT USE THE DOCK STATION
So yesterday I decided I had all the information I needed and that it was time to get the IP to unlocked it. Let me first go back two days to explain something.
I decided to join the #ziphone channel to try to get some answers for questions that remained unanswered. I got luck enough to meet CLP. He was kind enough to talk to me for some minutes and nailed all the answers to my questions.
Thanks to that I was able to create an item list with the theoretical steps of the activation/jb/unlock process:
1. Get the firmware version of you OTB IP from itunes 2. If 1.1.3 skip 3 3. If 1.1.2 + plug the IP + fire up iTunes + download fir mare 1.1.3 + press Option/ALT-key to restore firmware 1.1.3 NOTE: repeat the process if you get a 1015 error 4. Close iTunes 5. Start ziphone and select activate + jailbreak + unlock. Click start. 6. Wait for ziphone to do its job. It should take 2' 30''. 7. You are done
That was what I expected the process was going to be. It wasn't exactly like that. But it was close enough.
First of all, currently ziphone doesn't unlock 1.1.4. Ordering online wasn't an option since the likelihood of getting a 1.1.4 was pretty high. I decided to go the apple store so the chances to get a 1.1.2 or a 1.1.3 would be higher. I entered the AS with my credit card (:)) and I asked the guy: "What do I have to do here to get an IP?" The girl was: umm.. not sure if still have.. bummer! I thought. She went check and she came back saying: "yes, we have only 8G". Excellent that is what I needed. I decided to try to get some information about the firmware. That was probably stupid since they are aware people gets IP to unlock them. She said I wasn't going to know what Firmware I had on my IP until using it with my computer. Ok, I knew that already :). So I left the store thinking, would my IP be 1.1.4? If that was the case I should had to wait for zibri to release ziphone 2.5.
Once at home, first problem: Once you fire itunes you are stucked in the activation process. I started thinking.. and I remembered I downloaded Independence some days ago and for some reason I knew the interface had some info about your firmware version, baseband version and so on... Nice, 1.1.3! The perfect scenario. First problem solved.
I closed iTunes. The crucial moment was here. I fired up ziphone and selected all the options and clicked start. Luckily, I checked some youtube videos and I read the documentation so I knew what the process was going to be: First the software puts the IP in recovery mode and then it warns you is going to take 2' 30'' to finish the process. During that period, ziphone changes the screen resolution and starts vomiting mem addresses and info about the process status. Everything looked as expected. The IP rebooted with the classical slide to unlock screen. It was done. I changed the sim card, put a tmobile one, reset the configuration and... wait for it... yes T-mobile signal. I stared trying all the phone basics. Everything was working. Yes!
Then I looked the output of ziphone and i saw the textarea with the log had a very disturbing error messages saying: "Error code 1". Damn it I thought. I googled the error and it seems some people got the same despite everything was fully functional. So far everything has worked perfectly.
One thing I wasn't sure about was the jailbreak process. Did I had to install something after the unlock was done? No! The unlock process installs installer.app (plus the nice Zibri blog app). From there you can install everything: in my case I started with the openssh server. I configured some rsa keys, and I sshed from my laptop to the phone. Nice! it is a full macosx. Or at least it seems so.
I think I should had gotten one of this before. I don't like the apple + ATT deal. I don't like to have to pay 90US or 75US or whatever when i can pay 40US or less. And I definitely don't like the 2 year contract deal. But the iphone is an amazing machine.
That's all so far. Thanks again to CLP.
posted at: 09:21 | path: /apple | permanent link to this entry
How to split a fasta file the ruby way
This is the ruby way to split a fasta file. Pure poetry.
#!/usr/bin/env ruby
sample = "indian_macaque_"
File.open(ARGV[0], "r").read.scan(/^>Chr[0-9A-Za-z]+\n[ACTG\n]+/) { |chrm|
File.open(sample + />(Chr[0-9A-Za-z]+)/.match(chrm).to_a[1], "w").puts(chrm)
}
UPDATE3: Nice explanation of what the baseband is, here.
UPDATE2: The Ziphone guys got it all together. Is it possible to unlock an iphone with just one click? We'll have to try it. here. Amazing people out there. A macosx version exists. Awesome. It seems that they integrated geohot's work on their software.
UPDATE: It seems this is another method to unlock 1.1.3.
I am considering getting an iphone. I kind of want to make it work with t-mobile. I don't want a pay 70US to att and get stuck in a two years contract.
Before getting one I have to be sure apple won't release a new version or reduce the price of this cult device. After that, I want to read about the software unlocking methods out there to try to get an idea how they work before I actually get one.
There is a lot of information on the Internet, unfortunately it already assume you have some previous knowledge. That's bad. First thing first, go ahead and read this. It will explain you some terms and concepts you have to know prior to reading other documents.
After reading that we should stop in the iphone status page which nicely shows what is the status of the unlocking process for the different versions of the iphone. If you read that, you'll find there is a very promising update in orange basically saying someone (Geohot) has released a software method to unlock 1.1.2 OTB (Out of the box). In the status overview there is an entry to Geohot's blog.
Once there, you can download his work and read the instructions txt file. That file was kind of my starting point and I am going over it here. This is just a method for me to try to understand what we are doing here:
geohot's 1.1.2 software unlock yes, this is what you have all been waiting for now fixed to support 1.1.3 and a little more idiot proof
Ok, pretty awesome, it seems to even works with 1.1.3. Again, 1.1.3 is the latest firmware that runs in the iphone.
1. Download these: gunlock and the secpack from http://iphonejtag.blogspot.com/ or the blog :) the 4.02.13 fls from around the internet
Umm.. hang on.. two much information here.
Ok, so we seem to have everything that gunlock requires. And more or less understand what's are each of these files. Next please:
2. Downgrade your phone to 1.0.2. See all the great tutorials online to do this. Your baseband won't be downgraded, this is normal. This will probably work on other versions too, but 1.0.2 doesn't lose wifi on bb access.
Let's review this for a sec. We have to downgrade to an earlier version of the firmware. Makes sense, I guess it was easier to hack the device with that older firmware. The downgrade process is explained here. Notice something here: It seems that downgrading the general firmware won't downgrade the baseband firmware. GeoHot warns us about it.
At these point that's what I have in my working directory:
drwxr-xr-x 11 drio staff 374 Feb 24 11:15 . drwxr-xr-x 8 drio staff 272 Feb 24 09:58 .. -rwxr-xr-x 1 drio staff 3157412 Feb 24 10:46 ICE04.02.13_G.fls drwxr-xr-x 6 drio staff 204 Feb 24 11:16 bricktool -rw-r--r--@ 1 drio staff 4176 Feb 24 11:15 bricktool.zip -rw-r--r-- 1 drio staff 19704 Feb 24 09:58 gunlock -rw-r--r-- 1 drio staff 10733 Feb 24 09:58 gunlock.c -rw-r--r--@ 1 drio staff 95627324 Feb 24 10:56 iPhone1,1_1.0.2_1C28_Restore.ipsw -rw-r--r-- 1 drio staff 1124 Feb 24 09:58 instructions.txt -rw-r--r-- 1 drio staff 279 Feb 24 09:58 runme.sh -rw-r--r-- 1 drio staff 2048 Feb 24 09:58 secpack
Next,
3. Make sure you have secpack and ICE04.02.13_G.fls in the folder you are in. 4. chmod +x runme.sh 5. ./runme.sh
This is pretty "straightforward". He wrote a shell script that actually runs the final gunlock. He does something before and after, don't know exactly why. --TODO: why is he doing that? Next,
6. For some reason my phone was in brick mode. Use the elite team bricktool to get out. 7. Also run iWorld on 1.1.2
These are some tools that fix some of the problems you get after running the gunlock software. You can find them here and here. TODO -- Find out more about these tools.
And that's suppose to be everything. Here the guy said you'll get a 1.1.2 or 1.1.3 unlocked. I am not sure how that is possible if we started with a 1.0.2 version.
So to sum up:
Still a lot of stuff to read.
posted at: 13:13 | path: /apple | permanent link to this entry
I recently started to push the firmware of my linksys router (WRT54G v2.2 if I remember correctly). Basically more torrents which means more sockets the router, and the nat subsystem have to deal with.
Despite using the latest version of the linksys firmware, the wireless device kept crashing at me and I had to reboot and restore default settings two times per month. Yes, I know, unacceptable.
Long time ago I heart about a group called dd-wrt which was building his own version of firmware for my router and other ones based on the same hardware and OS. The OS of this device is the venerable linux. Due to the license of this OS, linksys had to publish their source opening a new door for people to build their own firmware.
When I first heart about it, I thought it was very interesting but I didn't have a real need for replacing the firmware at that time. Things have obviously changed since then.
After reading a little bit about I found out what was the process of replacing the firmware of my device with dd-wrt. These are the simple steps:
I hope that after this upgrade, the montly reboots disapear. Let's see.
posted at: 22:34 | path: /wireless | permanent link to this entry
Apple has his own implementation of remote desktop. Despite you can remote desktop using VNC using the software from apple has his unique benefits. Performance is hands down better plus it understands the display layout and acts accordingly. In addition you have full control from applescript.
Thanks to that last feature, launching remote desktop to control another machine from quicksilver is pretty easy:
tell application "Remote Desktop" activate control computer "snowball" end tell
Don't forget to add your catalog in quicksilver so it indexes that directory so your applescripts are visible to qs.
Superbowl!
posted at: 09:55 | path: /apple | permanent link to this entry
Connecting/disconnecting an usb hard-drive from the console
I have an usb external hdd connected to my mac mini. Sometimes the disk is physically connected to the machine but the usb subsystem hasn't made it available to the rest of the OS. This is what you can do:
drio@snowball:~ $ disktool -m disk1s1
disk1s1 device will attempt to be mounted ...
***Disk Appeared ('disk1',Mountpoint = '', fsType = '', volName = '')
***Disk Appeared ('disk1s1',Mountpoint = '', fsType = 'hfs', volName = 'wdbackup')
Disk Mounting Completed
drio@snowball:~ $ disktool -e disk1s1
disk1s1 device will attempt to be ejected ...
***Notifications Complete for type 1
***Disk Unmounted('disk1')
***Notifications Complete for type 4
***Responding yes to eject - disk1
***Responding yes to eject - disk1s1
***Disk Ejected('disk1s1')
I want my terminals with their correct size
Let's say you are in your macosx and you want to start doing your work in the terminal. In my case, I use two terminals + screen. In one terminal I have always an ssh against a remote machine where I have my instance of irssi running. There, I can also check my email and IM to all the typical protocols (jabber, AOL, etc...). In the other Terminal window I have a session to another machine (It changes depending what machine I am working on).
The problem is that I want to create my two terminals and I want them to be in an exact position and with a particular size. Before writting this applescript, I had to that manually. Now I can run this from quicksilver and have my terminals ready:
tell application "Terminal"
activate
delay 1
close window 1
do script "ls"
do script "ssh -t whatever.com screen -RD"
set bounds of window 1 to {0, 0, 1240, 900}
set bounds of window 2 to {110, -80, 1440, 700}
end tell
This is priceless.
posted at: 01:33 | path: /apple | permanent link to this entry
If you have more than 20 windows, irssi assigns a two digit number to the new windows so you cannot quickly jump to them. Solution:
/bind meta-P change_window 20
Tip for one of those ones I can't leave without: screen
I am reading this book. At some point the authors talk about the beauty of plain text. They talk about being productive and how plain text and being able to comfortably work with text can help you.
One of my top5 tools is screen. Yes, you know what I am talking about. Probably the other four would be: bash, vim, ssh, irssi and mutt (ok, six). Not in any specific order. I work 99.9% percent of the time with that tools.
Screen allows you to add a status bar so you can keep track of your windows and some other stuff. I wanted it would to be able to check what is the status of your inbox so you can switch to your mutt window to check your email. This is what I did:
backtick 0 10 10 /home/your_user/scripts/screen-mail.sh
#!/bin/sh
mailbox="/home/your_user/Maildir/Inbox/new"
nMail=`find $mailbox -type f | wc -l | awk '{print $1}'`
echo -ne "[$nMail]"
Basically, we are instructing screen to get the output of our script and to use it
in some part of our status bar. How useful is that?
posted at: 22:52 | path: /screen | permanent link to this entry
Changing the timezone without restarting irssi
09:05:21 <+drio> Can I make irssi to read the TZ env variable without having to restart?
09:08:07 < znx> drio: yes ..
09:08:11 <+MonicaOff> Praise be to you.
09:08:22 <+drio> znx: how do I do it?
09:08:45 < znx> drio: two seconds .. ill dig it up
09:09:21 < znx> /script exec $ENV{'TZ'}="America/Los_Angeles";
Isn't it irssi great?
posted at: 13:50 | path: /irssi | permanent link to this entry
I am reading this book since I am in the process of writing a macosx cocoa application. The book has some "Challenges" at the end of every chapter and also a wiki where everybody can ask or post stuff for every part in the book.
I have been trying to implement all the challenges, and I noticed that people had some issues implementing the challenge in chapter 5, I had them myself also. It's the one about helper objects and delegation.
Basically we have to implement an application with a main window. When the window gets resized, the height has to be twice the width. This is my solution:
- (NSSize) windowWillResize:(NSWindow *) sender
toSize:(NSSize)frameSize
{
NSLog(@"W wants to get resized to: width=%f, height=%f", frameSize.width, frameSize.height);
frameSize.width = frameSize.height/2;
NSLog(@"Windows being resized to: width=%f, height=%f", frameSize.width, frameSize.height);
return frameSize;
}
NOTE: you have to return an NSSize object. Read the documentation for more info.
And that's it.
posted at: 21:57 | path: /cocoa | permanent link to this entry
Cracking wep with a ipw2200 based card
I wanted to find out more about how to crack wep. I started reading a lot about it on this great wiki form the aircrack-ng tools developers.
I found myself having to do some research in order to make my hardware work with the tools used to
crack wep and I ended up creating a
document in the wiki.
posted at: 22:57 | path: /wireless | permanent link to this entry
Irssi: Running a command on each window
In some cases you may want to run an irssi command on each window you have open. This is the way to do it:
18:00:50 < drio> Is there any way to run a command to all the windows open? 19:01:58 < imMute> drio: /foreach window /
Proper way to add a new channel
18:18:49 < drio> I want to add a new network and a new server to my irssi.. 18:18:56 < drio> and then I want to join a channel.. 18:19:03 < drio> I want all of them to be loeaded automatically.. 18:19:09 < drio> server + channel.. 18:19:11 < drio> I tried this first: 18:19:33 < drio> /SERVER ADD -auto -network operanet irc.opera.com 6667 18:19:40 < drio> but then.. 18:19:42 < drio> when I do 18:19:47 < drio> /network list 18:19:50 < drio> it doesn't show up.. 18:19:56 < drio> so I cannot change the server... 18:19:59 < drio> using ctrl + x 18:20:05 < drio> what is the proper way to do this? 18:20:22 <@znx> drio: do .. 18:20:30 <@znx> /network add something 18:20:47 < drio> done 18:20:49 <@znx> /server add -auto -network something server.com 6667 18:21:03 <@znx> /channel add -auto #channel something 18:23:36 < drio> umm.. 18:23:39 < drio> I did that.. 18:23:48 < drio> but still cannot change the server using ctrl + X 18:23:57 < drio> the list of servers shows operanet... 18:24:01 <@znx> drio: did you connect to it yet? 18:24:07 <@znx> /connect something 18:24:17 < drio> ups.. 18:24:26 < drio> since I did the -auto.. 18:24:33 < drio> I thought it was goign to connect.. 18:24:36 < drio> beautfil..
Bottom line:
18:20:30 <@znx> /network add something 18:20:49 <@znx> /server add -auto -network something server.com 6667 18:21:03 <@znx> /channel add -auto #channel something 18:24:07 <@znx> /connect something
11:45:51 < drio> Is there any shortcut that takes you to the previous window?
11:46:20 < drio> Let's say I am in window5 .. I go to number 8... and then I want to go back to number 5 but I
don't remember I was in 5
11:48:04 <@Wibla> not really no, im actually looking for that myself
11:48:10 <@Wibla> i usually alt-a through alot of shit, quite fast
11:48:23 <@Wibla> and sometimes i see something interesting, but by then its already too late, im in the next
channel before I notice what chan it is
11:48:27 <@Wibla> ;P
11:48:31 < drio> Correct!!!!!!!!!
11:48:32 < drio> same here
11:48:42 < drio> time to do some scripting?
11:48:48 <@Wibla> hehe
11:49:40 < drio> Instead of /clear
11:50:03 < drio> What the fuck is that.. I didn't write that..
11:50:09 < drio> umm..
11:54:30 <@jilles> /window last
11:54:42 <@jilles> you can put it on a alt+ thing yourself
11:56:53 < drio> jilles: a great thanks
[16:46:04] [drio(+i)] [5:#irssi(+nst)] [87 nicks (@24 %0 +2 61)]
That's how the status bar in my irssi looks like. Some of the entries are easy to understand but some are not.
We first have the current time. Then, we have the nick and (+i). What's that? Well, it means I am invisible. And if we check irchelp we find exactly what it means:
If someone starts harassing or flooding you, leave the channel or use the /ignore command. For more details, mIRC users see our flood protection page, ircII users type /help ignore. It is a good idea to set your user mode to +i (invisible) to avoid unsolicited messages and harrassment -- if you are "invisible" generally only users on a channel with you can determine what nick you are using.
After that, we have: window number:channel_name(+channel modes). An specifically, that channel has this modes on: +nst. What are they? Let's use irchelp again to find out:
No external messages to the channel (n): People outside the channel cannot do /MSG #channel_name [whatever] which would otherwise be sent to everybody on the channel
Topic control (t): Only channel ops are allowed to change the topic
The "+p" or "+s" will be explained later, for now consider them to be flags
denoting the nature of the channel. These channels provide privacy and security
for insiders and may or may not welcome newcomers. If you don't know the names
of these exclusive channels already, you won't find them using /LIST. Even if
you know the channel name, you still cannot use /WHO #channelname to see who is
presently in there unless you join the channel yourself. Note: private and
secret are not the same thing, but the difference is pretty arcane.
posted at: 18:48 | path: /irssi | permanent link to this entry
10:43:42 < drio> I use ESC+n ESC+p to scroll down and up in a channel... When I perform an scroll some of the
lines that I have read still show up.. is there any way to make irssi scroll the whole screen
/page?
10:44:16 < Moggie> yes it's an environment setting telling irssi how much to scroll up by
10:44:23 < Moggie> default is half the screen
10:44:49 < Moggie> scroll_page_count
10:44:55 < drio> Thanks Moggie
10:45:01 < Moggie> welcome
This is what I did:
/set scroll_page_count /1
From the manual:
How many pages to scroll the scrollback buffer when pressing
page-up or page-down. Expressed as a number of lines, or as a
fraction of the screen:
/2 = Scroll half a page.
.33 = Scroll about a third of a page.
4 = Scroll four lines.
I do all my chatting with irssi and bitlebee. I have to post what's my current setup for using bitlebee with irssi, but in this post I just want to show a tip for irssi that it was been very helpful to me.
irssi has different levels of outputs that get written to a channel. Running /help levels:
23:34:40 CRAP - Can be almost anything 23:34:40 MSGS - Private messages 23:34:40 PUBLIC - Public messages in channel 23:34:40 NOTICES - Notices 23:34:40 SNOTES - Server notices 23:34:40 CTCPS - CTCP messages 23:34:40 ACTIONS - Actions (/me) - usually ORed with PUBLIC or MSGS 23:34:40 JOINS - Someone joins a channel 23:34:40 PARTS - Someone parts a channel 23:34:40 QUITS - Someone quits IRC ..
In my case, I don't want irssi to send everything to the channel. I just want some stuff to be ignored. This document explains clearly how to control the levels and how to ignore them. But this what I have in place in my irssi windows/channels:
/IGNORE #channel ALL -PUBLIC -NEVER -HILIGHTS
That allows me to see only content, making thinks much easy to follow and read.
If you want at some point remove all the ignore levels, just runP:
/IGNORE #channel -ALL
Also, there is a very useful script called:
printlevels that you can use to
figure out what is what. The script will print the level name for every thing that is send to the
channel. Very useful.
posted at: 01:41 | path: /irssi | permanent link to this entry
Solaris/SysV pkgs and blastwave
After some days of work I have created the blastwave package for the new version of lighttpd. Phil was helping me a lot to fix a lot of issues I had in the post/pre remove scripts.
As you should know already, blastwave is an open source project that provides binary packages for solaris. I am a maintainer of some packages there. Among them: lighttpd.
It is pretty easy to get any open source project compiled in a solaris 10+ box. It is not that easy to get them in previous versions, specially solaris 8. That was precisely my first contact with blastwave. I wanted to get trac working (with a lot of dependencies) in a solaris 8 box. I tried to compile the software myself, but I was a pretty tedious tasks since solaris 8 didn't have most of the libraries pre-installed. Then I found blastwave and I got everything working pretty fast, thanks to the help of some of the maintainers there.
Then, I decided to help the project and I joined it.
You may be interested in knowing how do I release and create new packages for the project. Well, I have a nice systems that I would like to show here. I keep everything under revision control software, in this case subversion. Let me show you how the filesystem tree for the lighttpd package looks like:
-rwxr-xr-x 1 drio drio 4086 Jul 27 10:01 build_lighttpd.sh -rw-r--r-- 1 drio drio 384 Aug 3 10:10 checkinstall -rwxr-xr-x 1 drio drio 529 Apr 20 14:57 copy_to.sh -rwxr-xr-x 1 drio drio 1001 Aug 1 15:44 cswlighttpd -rw-r--r-- 1 drio drio 500 Aug 5 12:09 i.smfno -rw-r--r-- 1 drio drio 509 Aug 5 12:09 i.smfyes -rw-r--r-- 1 drio drio 11420 Apr 20 14:57 lighttpd.conf -rw-r--r-- 1 drio drio 3091 Apr 20 14:57 lighttpd.xml -rw-r--r-- 1 drio drio 1557 Aug 5 12:11 postinstall -rw-r--r-- 1 drio drio 518 Aug 3 18:51 preremove -rw-r--r-- 1 drio drio 193 Apr 20 14:57 space -rw-r--r-- 1 drio drio 1252 Apr 20 14:57 todo.txt
Check this link if you want to know how to create a Solaris/SysV pkg. Keep in mind that in this case, the lighttpd has some extra files inside to deploy the daemon in the solaris smf framework and the ancient init.d.
The blastwave project has a nice infrastructure to compile and generate the binaries for solaris machines, both sparc and i386. Newer versions of solaris are backwards compatible so we work against solaris 8 so in that way we ensure that the packages work with this old version of solaris. I always try to compile my code using Sun Compiler, Sun Studio. But in some cases you have to use gcc because the code is too dependable of gcc particularities, specially C++ code.
What is nice about my system here is that I can get a new version of the package without having to type that much. I just make the changes in my local machine and then I run a little script that sends the code to the blastwave machines and the package gets generated pretty fast. Normally depends how much load the machine has.
Anyway, if you are interested in creating a Solaris/SysV pkg for blastwave, let me
know and I can send you my code so you can reuse it.i
posted at: 01:27 | path: /blastwave | permanent link to this entry
Quicksilver is one of my favorite tools for macosx. Unfortunately seems to be very unstable. Particulary crashes a lot when I am bringing my mbp back from sleeping.
This tip in macosxhints show you how to use launchd to keep an eye in the quicksilver crash log so it can be relaunched when crashes.
It really saves you time.
posted at: 15:37 | path: /quicksilver | permanent link to this entry
I wanted to embed a video in a piece of html. Basically I wanted someone to be able to play a video just by pointing her browser to a URL. Kind of what you see these days in a bunch of blogs. Most of them use flash. Youtube uses flash.
This is how it works: First of all, you have to convert your video to a format that flash understands: flv. To do that I used mencode (you can read more about it here):
$ mencoder raw.avi -o flash.flv \ -of lavf -oac mp3lame -lameopts br=96 \ -af lavcresample=22050 -srate 22050 -ovc lavc -lavcopts \ vcodec=flv:vbitrate=128:autoaspect:mbd=2:trell:v4mv \ -vf scale=320:240 \ -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames
Play with the audio/video bitrates. That ones give me a good trade off between video quality and size.
After that, you have to download some flash and javascript code that will load your video and display a nice video player. In the ffmpegx page, they suggest this one. That's the one I used.
And that's it. Easy eh?
One more thing. My video source format was the one that comes from my video camera. It is raw audio+video without any kind of compression. If you want to encode your video in divx (Your flash code won't play that), you can use this:
AVI="raw.avi"
OUT="divx.avi"
for p in 1 2; do
mencoder $AVI \
-channels 1 -srate 48000 -oac mp3lame -lameopts mode=3:abr:br=16 \
-ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=496:vpass=$p -o $OUT
done
wmware fusion when you use parallels already
I started to read a book and I needed to try some code against FreeBSD. The first idea that came to my mind was to create a virtual machine using parallels. The problem is that you still have to go through all the annoying installation process (OS installation I mean).
Then I remembered I read about the new
virtualization product for MacOSX.
It's called fusion. For a regular user, parallels
and fusion are pretty much the same. They allow you to run guest oses. I have been using
parallels for 8 months or so and I am pretty happy with it. But fusion has an interesting
"bonus" feature that was crucial for me:
Appliances.
Basically you have a long list of preinstalled images that you can download and run.
That's what I was looking for. They use bittorrent to distribute the images, and the
download speed was good.
posted at: 12:14 | path: /virtualization | permanent link to this entry
7:00am, I get paged.. Umm.. probably just some minor heavy load. Five seconds later another sms, and another, and another. Ok time to wake up and check what's going on.
Apparently our oracle machine was about to day and also our frontends were acting weird. The person in charge of those machines left the company and I am in charge.
I cannot ssh to them or if I can, latencies are really bad. I tried to access using the serial port. Better. I check the status of the machine (frontend first). Cpu is not being used that match but I have 1500 sockets active. That's not very normal. For some reason I initially thought it may be a TCP SYN Flooding attack. After checking how many sockets were in SYN_RCVD state I discarded that option.
Then, the someone pointed me to mod_status. How come I didn't think about it before? This module shows you in real time what is the status of your apache server. You can configure it like this:
SetHandler server-status Order deny,allow Deny from all Allow from x.x.x.x y.y.y.y
Checking the output of server-status the problem became clear: our servers were being hit to the same page. The problem is that page was being generated dynamically. That's why the frontends were not using that much cpu but we had a bunch of httpd instances and sockets open. The database serer could not handle all the request. The solution was simple: Just generate the static page of the page being hit and then perform a redirect. In your virtual host:
Redirect permanent /slashdot_effect/page.html http://site.com/stattic.html
After doing that, everything went back to normal.
posted at: 13:03 | path: /apache | permanent link to this entry
I have my irssi instance running in a machine that is somewhere in the US, in the east coast. But I am normally in the west coast. Irssi was showing me the time using Eastern Time. Umm.. Annoying. If you use bash as your shell, just by adding this to your .bashrc file and reloading it you can make bash and all the processes that run on top of it to use the timezone you want:
export TZ="/usr/share/zoneinfo/America/Los_Angeles"
That variable points to a zoneinfo file. If you want to check the contents of that file use zdump:
user@machine /usr/share/zoneinfo/America $ zdump -v /etc/localtime | tail -3 /etc/localtime Sun Nov 1 06:00:00 2037 UTC = Sun Nov 1 01:00:00 2037 EST isdst=0 gmtoff=-18000 /etc/localtime Mon Jan 18 03:14:07 2038 UTC = Sun Jan 17 22:14:07 2038 EST isdst=0 gmtoff=-18000 /etc/localtime Tue Jan 19 03:14:07 2038 UTC = Mon Jan 18 22:14:07 2038 EST isdst=0 gmtoff=-18000
This is related to my previous post. I sent this to support@ today:
From: David
Subject: my virtual host (is04607.com) is forcing charset=iso-8859-1
To: support@
My virtual host (is04607.com) is configured in such a way that sends this
header to the browsers:
Content-Type: text/html; charset=iso-8859-1
By doing that, browsers cannot render utf8 characters.
Could you please fix it?
I just need apache not to force the character set, or if it does, to use
utf8.
Support replied to me, telling me that the other virtual hosts where not having the same problem (BTW, these guys rock. Thanks Matt!). They even pointed me to an utf8 blosxom plugin. But Matt pointed me in the right direction:
From: Matt
Subject: Re: charset=iso-8859-1 .. found it!!
To: David
Its the perl module your blog uses :)
Reading the source code:
$ more /usr/local/lib/perl5/5.6.1/CGI.pm
The B<-charset> parameter can be used to control the character set
sent to the browser. If not provided, defaults to ISO-8859-1. As a
side effect, this sets the charset() method as well.
I did find a plugin for blosxom that forces utf8
http://www.vrtprj.com/misc/output_utf8
I dunno if that helps.,
And finally my answer with the solution:
From drio Sun Jun 24 19:48:13 2007
Subject: Re: charset=iso-8859-1 .. found it!!
To: Matt
I read about that plugin you sent me. I tried it out but it failed because
in required the Encode.pm module.
I read the code of the plugin and I think that plugin was not going to fix
the problem. My output, my blog entries, they use utf8 characters already.
That plugin was basically encoding to utf8 your blog entries.
I read the blosxom code and I found this line:
$header = {-type=>$content_type};
That was the one in charge of setting the character set in the http headers.
I changed it to:
$header = {-charset => 'UTF-8'};
and ...... success. My browser now renders the utf8 characters properly.
Thanks for your help!
Some of my friends were working in a site and they were using utf-8 to write their html/js. The main page page had a drop-down where you could switch between different languages:
English
Français
Español
Deutsch
日本語
中文
한국어
NOTE: I am assuming that your browser will render this last utf8 characters the proper way. At the time I was writing this, the http server that was sending these content to your browser was forcing this character set:
drio@simba:~/wwwroot $ curl -I http://blog.is04607.com HTTP/1.1 302 Found Date: Sun, 24 Jun 2007 18:45:10 GMT Server: Apache/1.3.37 (Unix) mod_perl/1.29 PHP/4.3.11 mod_gzip/1.3.26.1a Location: http://www.is04607.com/blog/blosxom.cgi Content-Type: text/html; charset=iso-8859-1
I have to shoot an email to the sysadmin where I am hosting this so he can force utf8 on my virtual host.
That was exactly the same problem my friends had. Just by telling apache to use utf8 ( or at least not to force iso-8859-1) things get fixed.
By the way, do you know how many bits does utf8 uses to encode the Japanese characters? 32 bits, 4 bytes:
drio@simba:~/wwwroot $ cat test5.html ----日----- drio@simba:~/wwwroot $ hexdump test5.html 0000000 2d2d 2d2d 97e6 2da5 2d2d 2d2d 000a 000000d
Yes 日 is 0x97e62da5.
I found this document
highly useful to understand what unicode is. I think it has become a classical already.
posted at: 13:11 | path: /programming | permanent link to this entry