Friday, July 28, 2017

Linux Mint: Mount your iPhone like an external drive to transfer photos and videos

Objective


I want to mount my "iPhone 5s" like any external disk-drive on my Linux Mint 18.2 "Sonya" to access my photos and videos. The "out-of-box" solution stopped working since my upgrade to iOS 10.3.

Motivation


Since iOS 8, I was used to install libimobiledevice with my package-manager (usually synaptic or "apt-get install libimobiledevice" from the Mint repository, to have access to my "iPhone 5s".
Until now, this was a very convenient way, to exchange photos and videos between my iPhone and a my Laptop with Linux Mint. Recently I updated my Linux installation to Linux Mint 18.2 "Sonya" and my iPhone to iOS 10.3.3. After that, I recognized that libimobiledevice didn't work reliable anymore.
First, I couldn't really find out, whether the newer version of Linux Mint or the newer version of iOS was in charge for the decline of service. After a while reading posts on the subject on the internet, I really suspect, that the main reason was the upgrade to iOS 10.2 and later 10.3. In iOS 10.2 I already, only sporadically, could connect my phone, but mostly just to see the "Documents" folder mounted, but not the "Photo" folder. Rarely the "Photo" folder appeared, too. If I was lucky and it was mounted, I wasn't asked whether I will trust the connection to the computer by my phone.
However, without the confirmation of this question (which didn't even appear) the "Photo" folder always was displayed as empty. Bummer!

Prerequisites


  • Linux Mint 18.2 Sonya
  • iPhone 5s with iOS 10.3.3

Solution: Compiling most of the sources yourself


On the internet, I found a manual, that promised to make the connection between an "iPhone" and Linux Mint work again [1]. This manual was written originally for users of Ubuntu in the first place. Still with Linux Mint, it did mostly work as described, but was kind of incomplete.

After you follow this description, the tools, to mount and unmount your phone, will be installed in the home account for the current user, just only one library usbmuxd must be installed as root in the system, otherwise mounting would not work.

Install necessary software for building the source packages


To check-out and compile the needed packages from source, you have to install some additional software first.

Therefore, open a bash-command-shell and install git to be able to check-out the source code repository to be compiled.

$> sudo apt-get install -y git

Then install the compiler suite via the meta-package build-essentials including gcc and such...

$> sudo apt-get install -y build-essential

In contrary to the original manual at [1], I had to install some additional build tools.

$> sudo apt-get install -y libtool m4 automake

I also needed the package libfuse-dev from the Mint repository, this seems maybe not to be necessary on Ubuntu.

$> sudo apt-get install -y libfuse-dev

Setup the shell environment to build the software


If you don't want to install the new commands directly into your system (which also would additionally need sudo for all "make install" commands, which is not recommended), you have to setup your shell environment.

As for this tutorial, all new commands to mount and unmount the file-system of your iPhone, will be installed in the sub-directory "${HOME}/usr/bin/".

Create the sub-directory to store the source files of the packages to be compiled:

$> mkdir -p "$HOME/usr/src"

Set all required environment variables to ensure to build the packages from source as desired:

$> export PKG_CONFIG_PATH="${HOME}/usr/lib/pkgconfig:${PKG_CONFIG_PATH}"
$> export CPATH="${HOME}/usr/include:${CPATH}"
$> export MANPATH="${HOME}/usr/share/man:${MANPATH}"
$> export PATH="${HOME}/usr/bin:${PATH}"
$> export LD_LIBRARY_PATH="${HOME}/usr/lib:${LD_LIBRARY_PATH}"

Make the path to your new tools permanent


It is recommended, to put the last two export statements into your .bashrc, to be loaded every time you open a new command shell, otherwise you must type

$> export PATH="${HOME}/usr/bin:${PATH}"
$> export LD_LIBRARY_PATH="${HOME}/usr/lib:${LD_LIBRARY_PATH}

in every newly opened command-shell to mount and unmount the file-system of your iPhone, because the first export is needed to find the new commands and the second is needed to load the correct run-time for the commands.

Clone all needed repositories from Github


$> cd ~/usr/src
$> for x in libplist libusbmuxd usbmuxd libimobiledevice ifuse; do git clone https://github.com/libimobiledevice/${x}.git;done

You should see something similar to the following output:

Cloning into 'libplist'...
remote: Counting objects: 3767, done.
remote: Total 3767 (delta 0), reused 0 (delta 0), pack-reused 3767
Receiving objects: 100% (3767/3767), 1.13 MiB | 727.00 KiB/s, done.
Resolving deltas: 100% (2304/2304), done.
Checking connectivity... done.
Cloning into 'libusbmuxd'...
remote: Counting objects: 382, done.
remote: Total 382 (delta 0), reused 0 (delta 0), pack-reused 382
Receiving objects: 100% (382/382), 123.94 KiB | 0 bytes/s, done.
Resolving deltas: 100% (209/209), done.
Checking connectivity... done.
Cloning into 'usbmuxd'...
remote: Counting objects: 1954, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 1954 (delta 0), reused 1 (delta 0), pack-reused 1949
Receiving objects: 100% (1954/1954), 604.44 KiB | 424.00 KiB/s, done.
Resolving deltas: 100% (1191/1191), done.
Checking connectivity... done.
Cloning into 'libimobiledevice'...
remote: Counting objects: 8095, done.
remote: Total 8095 (delta 0), reused 0 (delta 0), pack-reused 8095
Receiving objects: 100% (8095/8095), 2.47 MiB | 617.00 KiB/s, done.
Resolving deltas: 100% (5666/5666), done.
Checking connectivity... done.
Cloning into 'ifuse'...
remote: Counting objects: 499, done.
remote: Total 499 (delta 0), reused 0 (delta 0), pack-reused 499
Receiving objects: 100% (499/499), 92.37 KiB | 0 bytes/s, done.
Resolving deltas: 100% (242/242), done.
Checking connectivity... done.

Additionally to the original manual [1], I also had to compile libplist from source.

Build and install the packages in the following order


Build libplist


$> cd ~/usr/src/libplist
$> ./autogen.sh --prefix="$HOME/usr"
$> make && make install

Build libusbmuxd


$> cd ~/usr/src/libusbmuxd
$> ./autogen.sh --prefix="$HOME/usr"
$> make && make install

Build libimobiledevice


$> cd ~/usr/src/libimobiledevice
$> ./autogen.sh --prefix="$HOME/usr"
$> make && make install

Build usbmuxd


The package usbmuxd must be installed with administrative rights, because it needs write access to "/lib/udev/rules.d" and "/lib/systemd/system".

$> cd ~/usr/src/usbmuxd
$> ./autogen.sh --prefix="$HOME/usr"
$> make && sudo make install

Build ifuse


$> cd ~/usr/src/ifuse
$> ./autogen.sh --prefix="$HOME/usr"
$> make && make install

Test if everything works


It's assumed that you put the two exports into your ~/.bashrc as mentioned above.
Open a new bash command-shell.

Connect your iPhone


Create a mount point, where you want the content of your iPhone to appear.

$> mkdir -p ~/usr/mnt

Check which command executable will used, just in case you also have libimobiledevice additionally installed from the Mint repository, to avoid confusion.

$> type -p ifuse

/home/csch/usr/bin/ifuse

$> type -p idevicepair

/home/csch/usr/bin/idevicepair

Pair your iPhone with your computer


Now, grab your lightning-usb-cable and connect your iPhone to the computer.
Try to pair the iPhone with your computer.

$> idevicepair pair

ERROR: Could not validate with device 45ad6a77ae03f2d03f14a68fae178e45e70e7a04 because a passcode is set. Please enter the passcode on the device and retry.

Ooops, what's that? What happened? Again...

$> idevicepair pair

No, worry ... the ERROR just tell you that you forgot to confirm that you trust the connected computer on your phone, by entering your PIN on your phone and accept the trustworthy question.

cschmidt@pippin:~/usr/src/ifuse$ idevicepair pair
ERROR: Please accept the trust dialog on the screen of device 45ad6a77ae03f2d03f14a68fae178e45e70e7a04, then attempt to pair again.

After doing so, you finally can mount your iPhone (All good things come by in threes, therefore again)

$> idevicepair pair

SUCCESS: Paired with device 45ad6a77ae03f2d03f14a68fae178e45e70e7a04

Mount the file-system of your iPhone and check the content


Finally, mount the file-system of your phone.

$> ifuse ~/usr/mnt/
$> ls ~/usr/mnt/

AirFair com.apple.itunes.lock_sync iTunes_Control Photos Radio
Books DCIM MediaAnalysis PublicStaging Recordings
CloudAssets Downloads PhotoData Purchases Safari

Unmount and disconnect


To safely disconnect your iPhone, you have to unmount the file-system in ~/usr/mnt first with fusermount.

$> fusermount -u ~/usr/mnt

Now, you can plug-off your iPhone again.

References:

  1. gist: samrocketman/libimobiledevice_ifuse_Ubuntu.md
  2. Github repository https://github.com/libimobiledevice/
  3. type command reference