Backup your iphone SMS’s as a conversation transcript.

Posted in Computers, IT, Programming on February 4th, 2010 by matt – Be the first to comment

At the point in writing there aren’t many ways of backing up your SMS’s from your iPhone, but you do a system backup when you sync with itunes but what if you want your SMS conversions backed up as a simple non proprietary format? Well the answer is here!

Shea recently upgraded to an iPhone, and was having trouble with bluetoothing the data across from her old phone. She told me she had saved the most important SMS’s but was a shame to loose the record of our entire SMS communication history.
And she’s right, in today’s world where everything is digital a lot of important relationship related stuff was discussed and it would be a shame to loose it all. So I started googling, at first I thought it would be a feature of itunes.. i was wrong.. which is a shame. But it turns out people have done it before, and some applications where written to do just that, unfortunately though all report that they only work for the iphone OS version 2.0. Sure it would be alot easier if the phone was jail broken, but there must be an easier way.. and there is!

Step 1 – Extract the SMS database from one of your iPhone backups:

I came across this OSX app, I’m not sure if there is a windows equivalent but seeing as I sync my iPhone under OSX I don’t really care.
Anyway this app allows you to access one of your iPhone backups and extract parts of it. For this post we are only interested in the SMS’s so once you have chosen a backup from the list scroll to the bottom and extract “System Files” or “Other Files” (can’t remember the name will check when I get home).

You’ll be prompted for a location to extract to, I suggest you extract the contents to an empty folder.
Once the files have been extracted you should find a sms.db file under:

<extracted folder>/System Files/Library/SMS/sms.db

This sms.db turns out to be a sqlite file.. and for those in the know, know that this is good news! With a few lines of python we can access and extract what we need from the file, but first we need to find the structure, which leads us to step 2.

Step 2 – Determine the sms.db table internal table structure.

There are many sqlite applications, but I’ll point you to 2 of them. A OSX app and a Linux app.
For OSX there is  sqlitebrowser and for Linux I simply used sqliteman which to install is as simple as:
For Debian/Ubuntu:

apt-get install sqliteman

For Fedora:

yum install sqliteman

Now inside the sms.db file there turns out to be 5 tables:

_sqlitedatabaseproperties
group_member
message
msg_group
msg_peices

All actual SMS text are stored in the ‘message’ table, and as the conversion I needed to backup was a simple 1 on 1 conversation all I needed was to query this one table.
While we are here what’s the structure of the ‘message’ table, well there are 17 columns but the only ones that I required where address, date, text and flags.

  • address – Is the number of the person you were having the SMS communication with.
  • date – Date of the text in epoch format.
  • text – The text itself.
  • flags – numerical flags attached to the message, but just looking at the table I realised that if the flag field contained a 2 then the text was from the recipient, a 3 indicated it was send from you.

With all that information I was ready to write my simple script, which leads to step 3.

Step 3 – The basic script

This python script does need some work, I only wrote it as a once off, so adding more exception handling and passing in the main parameters into the script rather then using variables would be useful, but outside the scope.

It is also worth a mention that I am using python 2.6 and it does also require the sqlite module, under fedora it is as simple as:

yum install python-sqlite2

Note: Yes its the 2nd version of the python sqlite module, but is actually supports sqlite version 3, so inside python you ‘import sqlite3′ so it actually is the sqlite3 module.

Now for the script, don’t forget to change the <data place holders> with the data you require:

#!/usr/bin/env python                                                                                                                                        

import sqlite3
import time
import sys
import os
import codecs 

DEBUG = True
names = {'2' : "<Recipient>", '3': "<your self>"}
key = "<number>"               

SQL = "select flags, address, date, text from message where address = '%s'"

output = """%s - %s
        %s         

"""

def getDate(epoch):
        return time.strftime("%a, %d %b %Y %H:%M:%S",time.localtime(epoch))

def main(dbfile, outputfile):
        outFile = codecs.open(outputfile, encoding='utf-8', mode='w')

        conn = sqlite3.connect(dbfile)
        c = conn.cursor()
        c.execute(SQL % (key))

        count = 0
        firstDate = ""
        lastDate = ""

        for row in c:
                flags = str(row[0])
                for name in names.keys():
                        if name in flags:
                                user = names[name]
                date = getDate(row[2])
                text = unicode(row[3])

                outStr = output % (user, date, text)

                if DEBUG:
                        print outStr

                outFile.write(outStr)

                # Store the first Date
                if count == 0:
                        firstDate = date
                lastDate = date
                count += 1
        outStr = "Date Range: %s - %s" % (firstDate, lastDate)
        if DEBUG:
                print outStr

        outFile.write(outStr)
        outFile.close()

if __name__ == "__main__":
        if len(sys.argv) < 3:
                print "%s  " % (sys.argv[0])
                sys.exit(1)

        dbfile = sys.argv[1]
        outFile = sys.argv[2]

        if not os.path.exists(dbfile):
                print "%s doesn't exist" % (dbfile)
                sys.exit(1)

        main(dbfile, outFile)

This creates a transcript like:

Matt - Mon, 04 Feb 2010 08:01:38
This is a text message

Other Person - Mon, 04 Feb 2010 08:02:38
This is the response.

Anyway happy backing up!
Needless to say I believe Shea was happy :)

Fedora 12 Amarok playing non-OSS codecs.

Posted in Computers, IT, Linux on January 11th, 2010 by matt – 3 Comments

Fedora by default only supports free software, which is awsome.. but if you have some music in a non-free or non-OSS codec, you still want to play it.. if your using Amarok then just:
sudo yum install xine-lib-extras-freeworld

NOTE: The above package isn’t available in the default Fedora repositories, it requires the RPMFusion repos!

MySQL – show storage engine used

Posted in Computers, IT, Linux on January 5th, 2010 by matt – Be the first to comment

This is a simple post, I’ve been benchmarking some MySQL storage engines at work, and sometimes from the command line I want to make sure I know what storage engine I’m using. Its actually very easy, but for some reason I keep forgetting the command. This post is for memory sake.

mysql> show table status;

or
mysql> show create table <table name>;

Temporarily disable SELinux in Fedora.

Posted in Computers, IT, Linux on January 4th, 2010 by matt – 2 Comments

I know, I know, most Fedora users probably are giving me the evil eye as they read this, but I find this tip useful when something on my desktop machine isn’t behaving properly and I want to see if it’s SELinux causing the behaviour, or if I want to stop the security for I one time only test.

For example, when migrating some of our unit tests, some virus scanning unit tests were failing, as this was a test I don’t run on my Desktop except on this occasion, it was simply easier to disable SELinux while I run the test.. it ran fine, so I could turn it back on, and tick it off my list.

By disable I actually mean put SELinux into passive mode, which allows everything, but still logs problems.

Anyway, to temporarily disable SELinux as root run one of these:
echo 0 > /selinux/enforce
setenforce 0

To re-enable it simply echo 1:
echo 1 > /selinux/enforce
setenforce 1

MySQL Datetime precision… I think not!

Posted in Computers, IT, Programming on December 24th, 2009 by matt – Be the first to comment

We use Hibernate at work, and I’ve been working on getting all our JUnit tests to work on MySQL… Yes hibernate takes care of most of that, and it does, BUT some of our unit tests were failing when I pointed it at MySQL rather then PostgreSQL.

After some debugging I noticed that when we pulled one of our objects out of the database via hibernate, the Date object inside wasn’t the same as the Date inserted:
originalDate.getTime(); // = 1261613807262
retrievedDate.getTime(); // = 1261613807000

The two epoch dates are almost the same, except the last three digits are zero’d out. The keen observers might have already figured out these are microseconds.
It seems MySQL isn’t storing or retrieving the microseconds from the datetime datatype.  Even though MySQL does have the MICROSECOND() function. A quick search on Google supports my findings there is a “Feature Request” opened on the MySQL bug tracker, annoyingly though it was opened on 15 Feb 2005, yet nothing is yet implemented.

For those who want to get around this issue, and want to Assert the dates, and want them to actually work, you simply need to zero out the microseconds component of the date, here is the simple function I used:
private Date removeMicroseconds(Date date) {
return new Date(date.getTime() - (date.getTime() % 1000));
}

Australian FTP RPMFusion Repository

Posted in Computers, IT, Linux on December 10th, 2009 by matt – Be the first to comment

There is an Australian FTP RPMFusion mirror:
baseurl=ftp://mirror.transact.net.au/rpmfusion/free/fedora/releases/$releasever/Everything/$basearch/os/
baseurl=ftp://mirror.transact.net.au/rpmfusion/nonfree/fedora/releases/$releasever/Everything/$basearch/os/

For updates:
baseurl=ftp://mirror.transact.net.au/rpmfusion/free/fedora/updates/$releasever/$basearch/
baseurl=ftp://mirror.transact.net.au/rpmfusion/nonfree/fedora/updates/$releasever/$basearch/

NOTE: This purpose of this post is simply for future reference.

Installing Sun Java on Fedora 12

Posted in Computers, IT, Linux, Programming on December 8th, 2009 by matt – 1 Comment

By default Fedora 12 doesn’t install Sun’s Java, and it isn’t in the repository. This isn’t a mistake, in fact I think this is a good decision! Fedora is only dealing with free open source software. You can add other repositories to give you the extra non OSS software you want, for those who cannot live without certain software.

Fedora uses the OpenJDK, which I think is awesome.. but unfortunately as I am a Java developer at the moment, and it seems some of the software I work requires the Sun version of Java, at least to compile.

So I needed to install Sun JDK on my 64bit machine.. this is how I did it:

  1. Download the Sun Java JDK 64bit Linux bin installer.
  2. Run it to install.
  3. Even though I ran it as root it installed in the current folder. So move the folder to we it should be installed:
    sudo cp -a jdk1.6.0_16 /usr/lib/jvm/
  4. Use the alternatives command to tell Fedora to use the new Java binary, to do so we need to “install” the new binary as an option in alternatives:
    sudo /usr/sbin/alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_16/bin/java 20000
    Then use alternatives and make sure our new binary is selected:
    sudo /usr/sbin/alternatives --config java
  5. Use the following command to verify that Fedora is pointing to the right binary:
    java -version

That’s it, Sun’s Java should now be installed!

Iptables NAT routing

Posted in Computers, IT, Linux on December 7th, 2009 by matt – 2 Comments

Intro

Over the years I have been turning my desktop into a NAT router.. why for virtual machines of course!

If your using 1 virtual machine the virtual machine software does it for ya, but when you want to simulate your own virtual network, separate from the LAN your desktop is on this is how to do it.
I used to do this a lot back when I was working at the ANU, to enable a test network.. and now suddenly I need it again to work on multi master MySQL replication at work.

It easy to do, only a few commands really, but it something I like to have filed away, I have it on a private wiki, but thought why not post it here.

Routing in Linux

To turn on routing in your kernel at runtime, without needing to reboot, as root run:
echo 1 > /proc/sys/net/ipv4/ip_forward

To make this permanent, edit ‘/etc/sysctl.conf’  and turn on IP packet forwarding:
net.ipv4.ip_forward = 1

Now that we have packet forwarding (trouting) enabled, we need to use iptables to allow us to connect our private LAN to the internet via NAT.
To do this we need to write an iptables rule on the nat table to MASQUARADE every packet coming from the virtual or internal network interface and out to the world through our public interface.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Where eth0 is the public interface.

The above rule, after routing changes the source IP address to that of the public interface, so traffic can get back to this machine. once a packet is returned iptables knows to change it back to the hidden LAN machine’s IP address.

In many distributions, iptables default configuration is to ACCEPT all traffic going through the FORWARD chain. But I’ve noticed Fedora doesn’t. it actually rejects forwarded packets. To check this out run the command:
iptables -L

My Fedora 12 Desktop FORWARD chain by default  looked like:
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Which REJECT’s anything being forwarded.

There are many ways to solve this:
Insert a rule to accept all:
iptables -I FORWARD 1 -j ACCEPT

Flush the chain:
iptables  -F FORWARD

If the policy is DROP, then change it to ACCEPT:
iptables -P FORWARD ACCEPT

Finally if you need to port forward to a machine behind your new NAT router then use a rule like:
iptables -t nat -I PREROUTING -p tcp -i eth0 --dport 6346 -j DNAT --to 192.168.0.2:6346

And if your interested in rate-limiting then read: http://www.debian-administration.org/articles/187

Fedora 12 + Nvidia

Posted in Computers, IT, Linux on December 4th, 2009 by matt – 5 Comments

By default Fedora 12 comes with the nouveau driver.. which is awesome, but my machine at work needed a bit more video card grunt so I needed to install the Nvidia driver.

Now I’m new to Fedora.. as in installed it an hour before I wrote this post, so thought I’d document here how to do it.
It wasn’t as straight forward as it _should_ have been, as apparently there is a bug in the current (at time of writing) version of Xorg, which causes X to run really slow. Anyway this is what you do:

  1. Add the rpmfusion repositories (to gain access to proprietary and other packages not supported by Fedora).
    su -c 'rpm -Uvh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm'
  2. Update yum:
    sudo yum update
  3. Now install the Nvidia drivers:
    sudo yum install kmod-nvidia xorg-x11-drv-nvidia-libs.i686 xorg-x11-drv-nvidia-libs.x86_64
  4. This should blacklist the nouveau, but doesn’t remove it from the initrd, so we run:
    sudo dracut -f /boot/initramfs-$(uname -r).img $(uname -r)
  5. Then we can restart, or just restart X (sudo pkill kdm) to see the new Nvidia card in action.

You should now been using the new nvidia module, however on my Fedora 12 KDE installation the X response time was really slow. However on a friends Fedora 12 Gnome installation there wasn’t an issue.
Apparently it is a bug in Xorg, but seeing as it doesn’t effect a friend it makes me wonder if it is a KDE/Xorg/Nvidia bug.

Anyway to fix it up we need to install a patched Xorg:

  1. First we need to add a repository:
    sudo vim /etc/yum.repos.d/xorgFix.repo
    And paste the contents:
    [rdieter]
    name=xorg-x11-server rebuilds for nvidia users
    baseurl=http://rdieter.fedorapeople.org/repo/fedora/$releasever/$basearch/
    enabled=1
    gpgcheck=0
  2. Run ‘yum update’  again, and it should need to update Xorg. Update it then restart X.

X should now run correctly. Phew.. not too hard right.

Eclipse @author

Posted in Computers, IT, Programming on October 15th, 2009 by matt – Be the first to comment

Most Java developers know eclipse is an awesome IDE, it’s customisation and auto-completeness is great.. It even auto completes annotations in the code far ya.

When added a @author annotation to some code, it’ll automatically try and add your name.. which is great, but it uses your logon name, not my real name. It’s not that big a deal, cause retyping your name is easy!

But curiosity got the better of me, I wanted to know if there was a place you can set the author name correctly.. and there is! When starting eclipse you can pass in an option:
eclipse -Duser.name=Matthew Oliver

But most people want to run eclipse from the menu, sure you can update the menu item, but there is another way. In the eclipse installation directory there is an eclipse.ini file, just append -Duser.name=<name> and that’s it.

For those of you following along at home, or those of you who are sysadmins, may realise that is a major problem.. can you figure it out?

By setting the user.name in the ini file, you forcing the user.name for everyone who uses eclipse on that machine, if there is only one person then there is no problem, but if there’s more however…

Maybe editing the menu item is better after all ;) or maybe there is an eclipse.ini file under ~/.eclipse somewhere!! Who knows.