NUTS AND BOLTS Admin Story: Mounting an iPad Lead image: © 2012 Apple Inc.
© 2012 Apple Inc.
 

An IT nomad's diary

Patched

The latest gadget lies temptingly on the table in front of you, but it doesn't work with the Linux distribution you are currently using. What now? This month's Admin Story is all about modifying standard Linux packages. By Thorsten Scherf

I finally gave way to marketing pressure and decided to invest in an iPad. Now, some of you will be shaking your heads and asking yourselves why it had to be an Apple product of all things; after all, there are some really neat tablets with Android. Well, to avoid endless debate – which I've already had – just accept this purchase as a fact of life. As a road warrior, I typically have the tablet along with me, and I really use it a lot to transfer photos directly onto the web or to a computer. This works perfectly with iOS devices, thanks to Libimobiledevice [1]. The library lets users synchronize all kinds of media files between the tablet and Linux devices, and you can even use it to activate an iPhone.

Contact

A while ago, I needed to transfer a number of photos and podcasts that I'd collected on my iPad to my desktop system. I use Shotwell for the photos and Banshee for audio files. Both tools can use Libimobiledevice to synchronize and manage the files on my tablet. After connecting the tablet to my PC, I encountered some disappointment. Nautilus told me that there was a problem mounting the device. And, despite some manual attention, all of my attempts failed. What was going on? A quick visit to the Libimobiledevice forum confirmed my suspicions: An update to iOS 5 was to blame.

When I checked the IRC channel for the software, the developers confirmed that some patches for iOS 5 were in the Git repository, but they had not even been bundled into an archive, let alone a pre-built installation package. The question was, should I wait until the maintainers had integrated the patches into the RPM package or go ahead and build my own package?

The first approach offered the benefit of not having to mess around with my system's package management system and potentially provoking issues with the next package update. On the other hand, I couldn't access my tablet and would need to wait until somebody had prepared a new package with the required patches. Of course, I didn't want to wait that long; thus, I decided to do it myself.

Libimobiledevice uses Git as its versioning system. To access the latest patches, you probably want to download the whole source tree from the project's Git repository. Of course, you also need Rpmbuild. If you don't have the required developer tools and libraries in place on a Fedora system, you can run

yum groupinstall Development Libraries Development Tools

to fix that. If you prefer to check what software this puts on your machine, you can set the Yum groupinfo option to do so.

Before I started building a new RPM package, I first had to download the latest source package from the distribution repository:

yumdownloader --source libimobiledevice

Then, the following

rpm -i libimobiledevice*.rpm

tells RPM to unpack the package and store the source files in ~/rpmbuild/SOURCES. The spec file, that is, the construction plan for the package, is stored in ~/rpmbuild/SPECS. The spec file contains a note about the software version used in the package; in my case, this is version 1.1.1.

In addition to the sources for the RPM package, I also need the latest sources from the Git repository for the software; after all, I need the latest crop of patches to fix my iOS 5 problem. Running Git puts them on my computer:

git clone git://git.sukimashita.com/libimobiledevice.git

This creates a libimobiledevice subfolder with the source code files. A bit of Git guru work quickly gives you a few insights into the project. The command

git tag -l

tells Git to show you the tags; these are simply labels that let you access specific snapshots of the software. Developers like using tags to label releases. The latest tag was 1.1.1, which indicates that 1.1.1 really is the latest release of the software. The latest available tarball on the website also uses this version number; however, that doesn't mean development has come to a standstill. Running the Git command in Listing 1 confirms that many things have happened in the repository since the 1.1.1 release.

Listing 1: Repository Status

01 # git diff 1.1.1..HEAD  --stat
02  configure.ac                |    2 +-
03  src/idevice.c               |   17 +++--------------
04  src/lockdown.c              |   31 +++++++++++++++++++++++--------
05  src/notification_proxy.c    |    4 +++-
06  tools/idevicebackup2.c      |   18 +++++++++++++-----
07  tools/ideviceimagemounter.c |    1 -
08  tools/ideviceinfo.c         |   12 ++++++++----
09  7 files changed, 51 insertions(+), 34 deletions(-)

In other words, 51 lines of program code have been added, and 34 removed, spread across seven files. The next thing I am interested in is the commit messages that the developers wrote when they checked in their changes (Listing 2).

Listing 2: Commit Messages

01 # git log --pretty=one 1.1.1..HEAD
02 e855f246b3d869a60375207fde1294bbe761fe23 lockdown: iOS 5: handle 'Error' key in lockdown_check_result
03 d2db9b97b0487e3e0c65cca0e0dd02a747a61113 Fix memory leak in idevice_device_list_free
04 d51431edc3987cb9e595fdec874cdf869935d21d idevicebackup2: plug another memory leak
05 c90fc4c934ac7b024c1fc1813bb3cffb5333e18f lockdown: move writing of device uuid to client struct inside lockdownd_client_new()
06 f0487376671ffd6ac3fc121657f1fbd0acea3cb0 lockdown: fix support for iOS 5
07 f8f3f299a56aeccce1b978fed7620137f7072518 idevicebackup2: plug a small memory leak
08 ceae1d897597c66c19c2ed30b3049ce09db78233 ideviceimagemounter: remove bogus g_free()
09 565b5901d666de3bfe538be27aebb9f443de98f0 notification_proxy: use free() instead of g_free()
10 5c10f12e408b11afbd7c3cc93ddf7d85f1527417 ideviceinfo: fix possible segmentation fault when parsing empty data nodes
11 27d0da3bc196d28c1095e7c74054f5a6efb7ccf2 idevicebackup2: fix restore command option handling
12 f20cf2b4f14b66f38984e21dbed41da27c03e23a idevicebackup2: Add typedef for GStatBuf for backwards compatibility
13 6dccecddf012a0a404d121cc2c42ddce7c485fb7 Remove deprecated gnutls_*_set_priority() and use gnutls_priority_set_direct()

This looks very promising. Two patches contain notes on iOS 5-specific changes (lines 2 and 6). Gimme, gimme! Because it won't hurt to add the other patches to my own package, I write all of the available changes to a patch file, like this:

git diff 1.1.1..HEAD > ~/rpmbuild/SOURCES/ios5.patch

First, I take a look at the changes. Because I don't anticipate any nasty surprises, I edit the Libimobiledevice spec file that I downloaded previously and list the patch in the preamble like this:

Patch1: ios5.patch

In the prep section, I add %patch1 -p1 to make sure the patches really are applied to the software sources and the changes will be available after building the package. No problems here, I just typed:

rpmbuild -bb ~/rpmbuild/SPECS/libimobiledevice.spec

Before this call, you need to increment the release number in the spec file to make sure RPM identifies the update as such. I then update my system with the package I created by typing:

yum update libimobiledevice

The tension increases as I connect my iPad to my desktop again.

Connected

Now, just as the doctor ordered, Nautilus happily tells me that it has found a new device and proceeds to mount it. I can again access my media files without any trouble, and my wife is happy she has the Mac back, without somebody interrupting her all the time to synchronize his tablet.