Tag Archives: RHEL

Upgrading the MTP Support on CentOS 6

Introduction

The Media Transfer Protocol (MTP) provides us direct file access to devices such as our smart phones and other devices that choose to use the protocol. In my case, my Nexus 4 couldn’t correctly attach itself to my system. From my Google results; it seemed to be due to the version of libmtp I was running. You see, CentOS/RHEL ships with libmtp v1.0 and most of the support for cell phones that came out within the last 2 years isn’t available until v1.1. libmtp v1.1 additionally builds against most peoples FUSE implementations such as MTPfs, jmtpfs and simple-mtpfs. It’s through these FUSE/MTP implementations that we can easily mount and directly access the content on our smart phones and tablets that use the MTP protocol.

So upgrade libmtp already; why are you blogging about it?

Oh boy… well here are all the problems I faced:

  • VLC Media Player is built against this same library. Upgrading it means looking after this dependency too; or go without it (no, not going to happen).
  • Rhythmbox is also built against this same library (libmtp). Upgrading it means looking after this dependency too; or go without it (again… not going to happen).

Then the second problem… we’ve only tackled the upgrade of libmtp above if we go through with this… we still haven’t even tackled the FUSE implementation. Here are the results I had testing some of them:

  • MTPfs: At the time of this blog, the last update for this software was on February 4th, 2010. I got the software to compile by simply using the version that ships with Fedora 18 (1.1-0.3.svn20120510) but when I tried to use it, it just hung as a normal user. If I tried mounting the device as root it would fail (see below):
    $ mkdir media
    $ # As myself (non-root)
    $ mtpfs media/
    Listing raw device(s)
    Device 0 (VID=18d1 and PID=4ee1) is a Google Inc (for LG Electronics/Samsung) Nexus 4/10 (MTP).
       Found 1 device(s):
       Google Inc (for LG Electronics/Samsung): Nexus 4/10 (MTP) (18d1:4ee1) @ bus 2, dev 89
    Attempting to connect device
    libusb_open() failed!: Permission denied
    LIBMTP PANIC: Unable to initialize device
    Unable to open raw device 0
    
    $ # As root (superuser)
    $ sudo mtpfs media
    Listing raw device(s)
    Device 0 (VID=18d1 and PID=4ee2) is a Google Inc (for LG Electronics/Samsung) Nexus 4/10 (MTP+ADB).
       Found 1 device(s):
       Google Inc (for LG Electronics/Samsung): Nexus 4/10 (MTP+ADB) (18d1:4ee2) @ bus 2, dev 73
    Attempting to connect device
    Android device detected, assigning default bug flags
    Error 1: Get Storage information failed.
    Error 2: PTP Layer error 02fe: get_handles_recursively(): could not get object handles.
    Error 2: Error 02fe: PTP: Protocol error, data expected
    Listing File Information on Device with name: (NULL)
    LIBMTP_Get_Storage() failed:-1

    Now I don’t want to give MTPfs a bad name. It’s quite possible that it works really well but just not for my personal purposes. In fact it compiles perfectly in CentOS/RHEL 6 right out of the box without any modifications. Therefore just because it didn’t work for me doesn’t mean it won’t necessarily work for you. For this reason and the fact it was once maintained (up to Fedora 18) I’ll include my results with it here too.

  • jmtpfs worked the best for me. The only problems I ran into with this software was that it wasn’t already packaged for CentOS/RHEL. The only thing I had to work with for packaging it myself was a very long set of comments (see the link back to it’s official site to see what I’m talking about). That all said; the software works fantastic right out of the box. Kudos to the great work of the developer and his online support.
  • simple-mtpfs works well too but required some tweaking to make it possible. You see, simple-mtpfs relies on the new C++11 compiling features and standards (which truly are amazing BTW) but weren’t available during the release of CentOS/RHEL 6. Making these standards available by upgrading the glib core library to a newer version would be just crazy. In fact, you could seriously risk jeopardizing the stability of the OS itself since everything else would have been compiled against the old version. So, to work around this, I wrote a small patch file for portions of the simple-mtpfs code mimicking the old behavior prior to the C++11 standards.

Just hand over everything

Of course… and as always; I planned on it. Hopefully you’ll find the packages useful! Like my other blogs, the installation instructions will be near the bottom of this blog, along with the ‘do it yourself’ for those who don’t trust the sources.

First thing is first; this is what makes everything else tick:

Here are the dependencies you may or may not need to get out of the way. Note that I just went ahead and upgraded VLC to 2.0.6 (from the stock version 1.1). There may be other dependencies of libmtp you find that I didn’t simply because I didn’t use those packages. You can just assume that all of the binary packages listed below have been compiled against libmtp v1.1 (shared above).

After you’ve got libmtp correctly installed and your system appears to be right back in the state it was previously, we can now move on to adding one of the excellent FUSE/MTP packages some incredible developers have put together for us.

  • jmtpfs-0.4-1.el6.x86_64.rpm
    Author: Jason Ferrara (Website)
    Source: jmtpfs-0.4-1.el6.src.rpm
    Compilation Details: I made 1 small patch file (see here) introducing some of the nice idea’s his followers of his blog suggested for auto-mounting. I additionally had to make one small change so that his code could compile against the version of FUSE currently shipped with CentOS/RHEL 6. The only other thing I can take credit for is the rpm packaging itself; the rest of the work was that of the hard working developer who made this application possible. The spec file I wrote can be seen here.
  • simple-mtpfs-0.1-8.el6.x86_64.rpm
    Author: Peter Hatina (Website)
    Source: simple-mtpfs-0.1-8.el6.src.rpm
    Compilation Details: I created 2 separate patch files for this to properly compile in CentOS/RHEL. The first patch rolls back the C++11 coding styles to the older way of doing it (so it can compile against our existing libraries). The second patch introduces the auto-mounting for our environment (exactly how It was done in my patch for jmtpfs). To accommodate these patch files I needed to additionally update the spec file which you can view here.
  • mtpfs-1.1-0.3.svn20120510.el6.x86_64.rpm
    Author: Chris Debenham (Website)
    Source: mtpfs-1.1-0.3.svn20120510.el6.src.rpm
    Compilation Details: No magic went on here; I just grabbed the packaged code from a Fedora 18 release on pkgs.org and it compiled without any problems. Note: It appears the support for this package was dropped after Fedora 18 since it isn’t available for either Fedora 19 or 20.

Here are the source packages for those who are interested:

Show me what you did; I’m not using your stuff

In some cases you’ll need to use what I’ve done (patch wise); but to be as transparent as possible, I’ll show you how you can easily build everything and review all of what is going on before committing to using it. Now keep in mind also; there is A LOT of stuff covered here. There is libmtp itself, the dependencies issues and then finally the choice of FUSE/MTP implementation. I’ll cover the dependencies last since not everyone will have this issue.

First I set up a mock environment to work in; this allows us to do compiling outside of our native environment and means we don’t need to ever install any development libraries.

First prepare our development environment with mock if you haven’t already:

# Install 'mock' into your environment if you don't have it already
# This step will require you to be the superuser (root) in your native
# environment.
yum install -y mock

# Grant your normal every day user account access to the mock group
# This step will also require you to be the root user.
usermod -a -G mock YourNonRootUsername

At this point we can get away from the root user and build using our own user we created for our system.

Now we’ll cover libmtp v1.1 as everything revolves around this library.

# Fetch the latest copy (already packaged) of libmtp
wget http://dl.fedoraproject.org/pub/fedora/linux/development/20/source/SRPMS/l/libmtp-1.1.6-2.fc20.src.rpm
# As time goes on, this rpm may not be available, but
# you should be able to just get away with grabbing the latest
# copy of libmtp from http://pkgs.org

# Now we just rebuild it against our own environment
mock -v -r epel-6-x86_64 --resultdir=$(pwd)/results 
       --rebuild libmtp-1.1.6-2.fc20.src.rpm

# Now all our built RPMs will be in a directory
# entitled 'results' to make things easier, we'll just
# move it all into the directory we're working in now
find results -name '*.rpm' -exec mv {} . ;

# We can eliminate the results directory now
rm -rf results

Everything from this point forward assumes we have a built copy of libmtp to work with. Now we’ll focus on the FUSE/MTP options.

  • Option 1: simple-mtpfs
    # Fetch our source
    wget --output-document=simple-mtpfs-0.1-8.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/KEU68ZzLIv/20131015/mtp/simple-mtpfs-0.1-8.el6.src.rpm?dl=1
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the nessisary dependencies for simple-mtpfs
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       fuse-devel
    
    # Now if you don't have any insecurities with source rpms you
    # can finish with the next command... or you can skip it and
    # extract all of it's content for inspection before building.
    # all of the results will appear in the 'results' directory.
    # Note: You'll want to skip this step and move to the next if
    # you have any insecurities at all.
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/results 
                             --rebuild simple-mtpfs-0.1-8.el6.src.rpm
    
    # For those really insecure can keep reading and perform
    # the following steps instead of the single command above
    # Copy our source into the mock building environment
    mock -v -r epel-6-x86_64 --copyin simple-mtpfs-0.1-8.el6.src.rpm /builddir/build
    
    # Shell into our environment now
    mock -v -r epel-6-x86_64 --shell
    
    # Change to the build directory
    cd builddir/build
    
    # Install the source package (which will deploy within
    # the mock environment only)
    rpm -Uhi simple-mtpfs-0.1-8.el6.src.rpm
    
    # Now we can safely prepare the source for inspection.
    # - the spec file will be in the SPECS/* directory
    # - all patch files and source code will be in SOURCES/*
    #
    # Once your satisfied I'm not out to get you, you can build
    # the package:
    rpmbuild -ba SPECS/simple-mtpfs.spec
    
    # we're now done with our mock environment for now; Press Ctrl-D to
    # exit or simply type exit on the command line of our virtual
    # environment
    exit
    
    # We'll return to the directory we were previously in.  We can copy
    # out the packages we just built at this point. Ignore the warning
    # about SELinux if you get one because it doesn't impact our goals.
    mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/simple-mtpfs-0.1-8.el6.src.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/simple-mtpfs-0.1-8.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/simple-mtpfs-debuginfo-0.1-8.el6.x86_64.rpm .
    
  • Option 2: jmtpfs
    # Fetch our source
    wget --output-document=jmtpfs-0.4-1.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/KH6b9pmCRZ/20131015/mtp/jmtpfs-0.4-1.el6.src.rpm?dl=1
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the necessary dependencies for jmtpfs
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       fuse-devel 
                                       file-devel
    
    # Now if you don't have any insecurities with source rpms you
    # can finish with the next command... or you can skip it and
    # extract all of it's content for inspection before building.
    # all of the results will appear in the 'results' directory.
    # Note: You'll want to skip this step and move to the next if
    # you have any insecurities at all.
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/results 
                             --rebuild jmtpfs-0.4-1.el6.src.rpm
    
    # For those really insecure can keep reading and perform
    # the following steps instead of the single command above
    # Copy our source into the mock building environment
    mock -v -r epel-6-x86_64 --copyin jmtpfs-0.4-1.el6.src.rpm /builddir/build
    
    # Shell into our environment now
    mock -v -r epel-6-x86_64 --shell
    
    # Change to the build directory
    cd builddir/build
    
    # Install the source package (which will deploy within
    # the mock environment only)
    rpm -Uhi jmtpfs-0.4-1.el6.src.rpm
    
    # Now we can safely prepare the source for inspection.
    # - the spec file will be in the SPECS/* directory
    # - all patch files and source code will be in SOURCES/*
    #
    # Once your satisfied I'm not out to get you, you can build
    # the package:
    rpmbuild -ba SPECS/jmtpfs.spec
    
    # we're now done with our mock environment for now; Press Ctrl-D to
    # exit or simply type exit on the command line of our virtual
    # environment
    exit
    
    # We'll return to the directory we were previously in.  We can copy
    # out the packages we just built at this point. Ignore the warning
    # about SELinux if you get one because it doesn't impact our goals.
    mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/jmtpfs-0.4-1.el6.src.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/jmtpfs-0.4-1.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/jmtpfs-debuginfo-0.4-1.el6.x86_64.rpm .
    
  • Option 3: mtpfs
    # Fetch our source from pkgs.org
    wget http://dl.fedoraproject.org/pub/fedora/linux/releases/18/Everything/source/SRPMS/m/mtpfs-1.1-0.3.svn20120510.fc18.src.rpm
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the necessary dependencies for mtpfs
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       autoconf automake libid3tag-devel 
                                       glib2-devel fuse-devel
    
    # If you have insecurities at this point, you'll need to
    # take them up with someone else since I didn't make any
    # modifications to this FUSE/MTP option at all. So we
    # just need to build from source at this point.
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/result 
                             --rebuild mtpfs-1.1-0.3.svn20120510.fc18.src.rpm
    
    

Finally our libmtp dependency issues (if you have them).

  • Rhythmbox
    # Fetch our source from pkgs.org
    wget http://vault.centos.org/6.4/os/Source/SPackages/rhythmbox-0.12.8-1.el6.src.rpm
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the necessary dependencies for Rhythmbox
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm
    
    # Now we just rebuild from source using the new library
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/results 
                             --rebuild rhythmbox-0.12.8-1.el6.src.rpm
    
    # Your rpm's will appear in the 'results' directory.
    
  • VLC
    # The catch with VLC is it's development isn't frozen with
    # the version of CentOS/RHEL like Rhythmbox does. This is because
    # if your running this, you've already chosen to link to other
    # repositories like RPMForge, ATrpms, LinuxTECH, etc.
    
    # Mock however (out of the box) does not link to these locations
    # at all. The quickest (and dirty) work around to this fix is to
    # simply install 'yum' into the mock environment which we can
    # use to fetch all of our dependencies (the best way is to actually)
    # create a new mock configuration that just includes them. But
    # everyone uses to many different alternatives; so we'll do it
    # my way :)
    
    # Fetch VLC source from the repository you use. You can do this
    # using yum if you have the --download-only rpm addon. Otherwise
    # just utilize pkgs.org and get the package:
    # http://pkgs.org/search/?keyword=vlc&search_on=name&distro=82&exact=1
    # At the time v2.0.6-1 was the version available to me.
    # You may need to adjust the below commands depending on which
    # package you get; I'll use a variable so you can set it to
    # whatever you get at the time.
    
    # If you are comfortable just using the version I have; you can
    # download it here:
    wget --output-document=vlc-2.0.6-1.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/pm7MCGHa9K/20131015/mtp/vlc-2.0.6-1.el6.src.rpm?dl=1
    
    # Set this variable to something else if you fetched a different
    # version
    VLCVER=2.0.6-1
    # Store our original source RPM Name; we do it this way
    # because some people might use different packages that
    # have the ending f20 (Fedora), atr (ATrpms), rf (RPMForge), etc
    # This way we're working with the same file regardless of
    # the version you picked
    VLCSRPM=$(find -name "vlc-$VLCVER.*.src.rpm" 2>/dev/null)
    
    # Make sure we found your rpm at this point
    # The following should output a file that exists
    echo $VLCSRPM
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the nessisary dependencies for vlc which we must
    # additionally include the libmtp package we just built
    # including 'yum' so we'll fill all the dependencies
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       yum
    
    # Now this is the dirty trick I was telling you about; we'll
    # just install your current yum repositories into your mock
    # environment. This will make it really easy to fill our
    # dependency problems:
    find /etc/yum.repos.d/ -maxdepth 1 -mindepth 1 
                           -type f -name '*.repo' 
                           -exec mock -v -r epel-6-x86_64 
                                  --copyin {} /etc/yum.repos.d/ ;
    
    # Now we want to copy our VLC Source into the environment
    mock -v -r epel-6-x86_64 --copyin $VLCSRPM /builddir/build
    
    # Shell into our mock environment
    mock -v -r epel-6-x86_64 --shell
    
    # Change to our building directory
    cd /builddir/build
    
    # Install all our dependencies including our source
    yum install $(rpm -qp --requires vlc*.src.rpm | cut -d' ' -f1)
    
    # Install our source RPM
    rpm -Uhi vlc*.src.rpm
    
    # There is a chance this failed for you... if so
    # you can use the collection of rpms I built manually
    # to make it possible for me; just visit here:
    # https://www.dropbox.com/sh/9dt7klam6ex1kpp/_pczPoH-Wx/20131015/mtp/dep.vlc2.0
    # You can exit the shell (Ctrl-D) or type exit and by now
    # you should have enough info as to how you can install these
    # rpms into your mock environment using mock and --install
    
    # Now build your RPM (this can take some time):
    rpmbuild -ba SPECS/*.spec
    
    # We're now done with our mock environment for now; Press
    # Ctrl-D to exit or simply type exit on the command line
    # of our virtual environment
    exit
    
    Now just copy out our packages:
    mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/vlc-$VLCVER.el6.src.rpm .
    
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-$VLCVER.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-core-$VLCVER.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-extras-$VLCVER.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-plugin-jack-$VLCVER.el6.x86_64.rpm
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-devel-$VLCVER.el6.x86_64.rpm
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-debuginfo-$VLCVER.el6.x86_64.rpm
    
    # You're done now! Phewf...
    

Installation

The installation will vary depending on your environment. If you are using either VLC or Rhythmbox, your life might be easier if you uninstall them now (knowing your going to re-install them again shortly).

yum remove rhythmbox vlc

Now you can install libmtp and your choice of FUSE/MTP implimentation (as root):

  • Option 1: simple-mtpfs
    yum localinstall libmtp-1.1.6-2.el6.x86_64.rpm simple-mtpfs-0.1-8.el6.x86_64.rpm
    
  • Option 2: jmtpfs
    yum localinstall libmtp-1.1.6-2.el6.x86_64.rpm jmtpfs-0.4-1.el6.x86_64.rpm
    
  • Option 3: mtpfs
    yum localinstall libmtp-1.1.6-2.el6.x86_64.rpm mtpfs-1.1-0.3.svn20120510.el6.x86_64.rpm
    

It’s important to note that you can go ahead and install all 3 options if you really wanted to (but it’s not really worth it). Pick one… if it doesn’t work well for you, try another.

Feel free to reinstall any other packaging you were using:

# VLC v2.0
yum localinstall vlc-core-2.0.6-1.el6.x86_64.rpm vlc-2.0.6-1.el6.x86_64.rpm

# Rythmbox v0.12.8
yum localinstall rhythmbox-upnp-0.12.8-1.el6.x86_64.rpm
Enable USB Debugging Mode
Enable USB Debugging Mode

It still isn’t mounting for me:

Some phones/tablets may require you to toggle the USB debugging mode of your phone and/or tablet for things to work smoothly for you. If you already have it enabled, then try disabling it. This is what I had to do with my Nexus 4 anyway; it worked beautifully for me after I toggled this option. I think this may be a bug with the current MTP v1.1 libraries that don’t seem to correctly handle the mounting of the device when being first connected. But whatever handshaking goes on, through the toggling of this option corrects the problem. I’m sure we will see this resolved in future builds.

Other MTP Alternatives

There are other alternatives; but this blog was going to be long enough just trying to share the ones I chose already.

  • FUSE Binding for Go is another alternative I didn’t test which seems to have a lot of active development on it as well. For those who aren’t familiar with The Go Programming Language, it is basically a fairly new language that is catching on with a lot of developers.
  • Gnome MTP is designed to be a simple MP3 player client for MTP based devices.

Credit

Please note that this information took me several days to put together and test thoroughly. I may not blog often; but I want to re-assure the stability and testing I put into everything I intend share.

If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

Sources:

Offline Blogging Solutions with CentOS 6

Introduction

BloGTK v2.0
BloGTK v2.0

Offline Blogging in Linux doesn’t offer us a wide selection of free (open source) choices. Of the choices we do have at our disposal each have their own pros and cons which are really just bias opinions we’ll all carry with each other. This blog isn’t going to tell you which product is better and which one isn’t. It will provide you some alternatives to what’s already available and allow you to choose on your own. I also make additionally options available to you here as well should you choose to try them.

Keep in mind I run CentOS 6 as my primary OS (currently), so I focus primarily on making these products work on this distribution. But this doesn’t mean that all of the source RPMs I provided won’t compile for you in another distribution.

Drivel v3.0.0 Login Screen
Drivel v3.0.0 Login Screen

Open Source Offline Blogging Choices

The below outline some of the choices I found to be worth of digging further in:

I’m not sure what the status is on all of these project themselves. At this current time, I have to assume that both Drivel and BloGTK are some what dead since the last update to either of them

Gnome Blog v0.9.2
Gnome Blog v0.9.2

was back in late 2009. Meanwhile the last update made to Gnome Blog was in early 2010.

It is said that beggars can’t be choosers. So rolling with that in mind and the Open Source solutions available to us, we’ll accept what is offered and move on.

Hand over your work

With pleasure; it really didn’t take any time at all to package these properly.

Drivel (v3.0.0) took the most time to package; but even that didn’t take much effort. Drop Line provided a spec file of their own which didn’t work out of the box. It also didn’t include all the necessary dependencies. For this reason I just spun my own version of it. Have a look here if you want to see the spec file I generated.

BlogGTK v2.0 didn’t take me hardly any time at all. They didn’t change the installation that much from v1.1. The fact that it’s python based; there really isn’t a whole lot too it. You can view the spec for yourself if you’re interested.

Alternatively you can just fetch bloGTK from Pkgs.org which does such a great job organizing packages other people have put together. It’ll probably be an older version (as it was for me). At the time I wrote this blog it was BloGTK v1.1 on Pkgs.org hosted by RPMForge. It might be different when you try.

Gnome Blog was another one that actually packaged it’s own spec file within the official packaging. But the file was drastically missing dependencies and would not work out of the box at all. I had to massage it quite a bit; you can view the spec file here if you feel the need.

I will never trust you; I’ll build it for myself

Still feeling that way? No problem; here is how you can do it:

First off, I’m not a big fan of compiling code as the root user on the system I work with daily.   I am however a big fan of a tool called ‘mock‘ which allows us to develop software as root except within a safe virtual environment instead of our native one. I am also a big fan of package management; whether its a .DEB (Debian Package) or .RPM (Red Hat Package) for obvious reasons. For this tutorial; I’ll stick with RPMs since it’s what CentOS uses. We’ll prepare the RPMs and preform all our compilations within the mock environment.

# Install 'mock' into your environment if you don't have it already
# This step will require you to be the superuser (root) in your native
# environment.
yum install -y mock

# Grant your normal every day user account access to the mock group
# This step will also require you to be the root user.
usermod -a -G mock YourNonRootUsername

At this point it’s safe to change from the ‘root‘ user back to the user account you granted the mock group privileges to in the step above.  We won’t need the root user again until the end of this tutorial when we install our built RPM.

# Optionally fetch bloGTK v2.0
wget https://launchpad.net/blogtk/2.0/2.0/+download/blogtk-2.0.tar.gz
wget --output-document=blogtk.spec https://www.dropbox.com/sh/9dt7klam6ex1kpp/GR0uXU6PaC/20131008/blogtk.spec?dl=1

# Optionally fetch Drivel 3.0.0
wget --output-document=drivel-3.0.0.tar.bz2 http://prdownloads.sourceforge.net/drivel/drivel-3.0.0.tar.bz2?download
wget --output-document=drivel.spec https://www.dropbox.com/sh/9dt7klam6ex1kpp/MKD34uuBMs/20131008/drivel.spec?dl=1

# Optionally fetch gnome-blog v0.9.2
wget http://ftp.gnome.org/pub/GNOME/sources/gnome-blog/0.9/gnome-blog-0.9.2.tar.gz
wget --output-document=gnome-blog.spec https://www.dropbox.com/sh/9dt7klam6ex1kpp/O9nJdxoJMZ/20131008/gnome-blog.spec?dl=1

# Initialize Mock Environment
mock -v -r epel-6-x86_64 --init

# bloGTK dependencies
mock -v -r epel-6-x86_64 --install 
  python pygtk2 pygtk2-libglade desktop-file-utils

# Drivel dependencies
mock -v -r epel-6-x86_64 --install 
  gnome-doc-utils intltool gtk2 gtkspell-devel 
  glib-devel gtk2-devel GConf2-devel 
  gnome-vfs2-devel gtksourceview2-devel 
  libsoup-devel libxml2-devel

# gnome-blog dependencies
mock -v -r epel-6-x86_64 --install 
  pygtk2-devel gettext intltool 
  desktop-file-utils GConf2-devel 
  python-devel

mock -v -r epel-6-x86_64 --copyin blogtk.spec /builddir/build/SPECS
mock -v -r epel-6-x86_64 --copyin gnome-blog.spec /builddir/build/SPECS
mock -v -r epel-6-x86_64 --copyin drivel.spec /builddir/build/SPECS

mock -v -r epel-6-x86_64 --copyin drivel-3.0.0.tar.bz2 /builddir/build/SOURCES
mock -v -r epel-6-x86_64 --copyin gnome-blog-0.9.2.tar.gz /builddir/build/SOURCES
mock -v -r epel-6-x86_64 --copyin blogtk-2.0.tar.gz /builddir/build/SOURCES
mock -v -r epel-6-x86_64 --shell

# Within Shell Environment, Build the Desired RPM
rpmbuild -ba builddir/build/SPECS/drivel.spec
rpmbuild -ba builddir/build/SPECS/blogtk.spec
rpmbuild -ba builddir/build/SPECS/gnome-blog.spec

# exit shell (or press Cntrl-D)
exit

# Copy out your blogger of interest
mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/drivel-3.0.0-1.el6.src.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/drivel-debuginfo-3.0.0-1.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/drivel-3.0.0-1.el6.x86_64.rpm .

mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/blogtk-2.0-1.el6.src.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/blogtk-2.0-1.el6.noarch.rpm .

mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/gnome-blog-0.9.2-1.src.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gnome-blog-0.9.2-1.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gnome-blog-debuginfo-0.9.2-1.x86_64.rpm .

# Install your blogger of choice; you'll need to be root or
# have sudoers permission to do this:
yum localinstall drivel-3.0.0-1.el6.x86_64.rpm
yum localinstall blogtk-2.0-1.el6.noarch.rpm
yum localinstall gnome-blog-0.9.2-1.x86_64.rpm

Drivel & WordPress

Drivel supports WordPress with a small with the following configuration:

  1. Configure your User/Pass as you normally would have
  2. Set the Movable Type to Journal type
  3. Set the Server Address field to be http://yourusername.wordpress.com/xmlrpc.php. For example I would have put http://nuxref.wordpress.com/xmlrpc.php for my own blog.

Another thing to note about Drivel is I was unable to retrieve a list of recent posts made to the WordPress server. However every other aspect of the tool appears to fine. People using different blog engines may not notice any problem at all.

Gnome-Blog & WordPress

  1. Set the Blog Type to Self-Run Other
  2. Set the Blog Protocol to MetaWeblog
  3. Set the XML-RPC URL field to be http://yourusername.wordpress.com/xmlrpc.php. For example I would have put http://nuxref.wordpress.com/xmlrpc.php for my own blog.
  4. Configure your User/Pass as you normally would have

Not Open Source, but other Free Alternatives:

  • ScribeFire:A plugin exists for Firefox & Chrome users called ScribeFire which also enables blogging functionality from within your browser. It’s worth noting as another alternative if you want it. It doesn’t involve extra packaging since it can be installed from within your browser.
  • Thingamablog: Another free solution; Thingamablog provides the binaries directly from their website here

Credit

If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

If I forgot any (Open Source) Offline Bloggers that you know about; please let me know. I have no problem updating this blog to accommodate it.

Sources

I referenced the following resources to make this blog possible:

Upgrading the PTP Support on CentOS 6

Introduction

I picked up the Nikon D7100 a few weeks ago to suppress my amateur photography needs. A long story short: my new camera isn’t recognized in CentOS 6. After much Googling, I found out the problem lies in the libgphoto2 library which grants PTP support to Linux. CentOS/RHEL 6 ships with the libgphoto2 library at version 2.4.7 and the Nikon D7100 isn’t supported with it until version 2.5.2.

So then… just upgrade; what’s the big deal?

It wasn’t that simple unfortunately but it was the starting point. In fact grabbing the latest (already) packaged source from our friendly Fedora (20) distribution and rebuilding it for our environment was the first approach.

Then following issues then surfaced:

  • The version of GVfs that ships with CentOS/RHEL 6 is compiled against the old libgphoto2. As a result, I needed to re-compile this package against the new version of libphoto2. I also needed to create a patch to accommodate the changes that reside in the libgphoto2 library.

Enough talking; just give me the goods.

You can scroll to the bottom of this blog for information on how to install these packages onto your system if your not familiar with the task at hand.

Binary Packages

Source Packages

I don’t trust you; I’d like to do it myself

I was prepared for this; just to cover myself until I gain your trust, here is what I did:

First I set up a mock environment to work in; this allows us to do compiling outside of our native environment and means we don’t need to ever install any development libraries.

First prepare our development environment with mock if you haven’t already:

# Install 'mock' into your environment if you don't have it already
# This step will require you to be the superuser (root) in your native
# environment.
yum install -y mock

# Grant your normal every day user account access to the mock group
# This step will also require you to be the root user.
usermod -a -G mock YourNonRootUsername

At this point we can get away from the root user and build using our own user we created for our system.

# Download the official libgphoto2 packages from their official
# hosting site:
wget http://downloads.sourceforge.net/project/gphoto/libgphoto/2.5.2/libgphoto2-2.5.2.tar.bz2
wget http://downloads.sourceforge.net/project/gphoto/gphoto/2.5.2/gphoto2-2.5.2.tar.bz2

# Download the source rpms
wget --output-document=gphoto2-2.5.2-3.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/MN-ZInf7cl/20131007/ptp/gphoto2-2.5.2-3.el6.src.rpm?dl=1
wget --output-document=libgphoto2-2.5.2-1.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/FZv_8wmpka/20131007/ptp/libgphoto2-2.5.2-1.el6.src.rpm?dl=1

# Initialize our Environment
mock -v -r epel-6-x86_64 --init

# Just install the nessisary dependencies
mock -v -r epel-6-x86_64 --installdeps libgphoto2-2.5.2-1.el6.src.rpm

# readline-devel is required by gphoto2, but we can't use the
# --installdeps flag because another dependency is libgphoto2
# which we haven't built yet... that will come later.  Just type
# the following command to speed up and simplify this tutorial
mock -v -r epel-6-x86_64 --install readline-devel

# Copy our packages into our environment
mock -v -r epel-6-x86_64 --copyin 
   gphoto2-2.5.2.tar.bz2 
   libgphoto2-2.5.2.tar.bz2 
   gphoto2-2.5.2-3.el6.src.rpm 
   libgphoto2-2.5.2-1.el6.src.rpm 
   /builddir/build

# Shell into our enviroment
mock -v -r epel-6-x86_64 --shell

# Change to our build directory
cd builddir/build

# You're now in the build environment within the mock environment.
# If you type the following, you should 'only' see the 2 RPMs we
# copied into here in addition of the the 2 .tar.bz2 files we
# downloaded from sourceforge.
find -type f

# You can confirm that you do infact have properly formatted source
# rpms by executing the following:
rpm -qlp gphoto2-2.5.2-3.el6.src.rpm libgphoto2-2.5.2-1.el6.src.rpm

# You're going to install the src.rpm's now.  Don't worry; this is
# safe to do since src.rpm's don't contain executable scripts.
# Instead they'll just distribute the files you saw in the above
# command within the SPEC, and SOURCE directory you see infront of
# you into the '/builddir/build' directory.
rpm -Uhi gphoto2-2.5.2-3.el6.src.rpm libgphoto2-2.5.2-1.el6.src.rpm

# You can see how the files were distributed using the find command
# above we specified earlier
find -type f

# There is no magic here; we basically just extracted the gphoto
# packages
#
# The only reason I took you this far is so you can see there is
# nothing Place the .tar.bz2 files you downloaded over the ones
# provided so you're confident I haven't introduced something you're
# not expecting. The following command will overwrite the files
# provided in the src.rpm with the fresh ones you downloaded from
# the website.
mv -f *.tar.bz2 SOURCES

# Inspect anything your uncertain of... such as the patches I ported
# from earlier versions. Feel free to download the previous version
# and compare.
less SOURCES/gphoto2-cjc-device-return.patch
less SOURCES/gphoto2-cjc-pkgcfg.patch
less SOURCES/gphoto2-cjc-storage.patch

# Inspect the SPEC file (which is a copy from the v2.4.7 version
# with all patches ported forward)
less SPECS/libgphoto2.spec

# There aren't any chages made to this spec file but have a look
# anyway if you like
less SPECS/gphoto2.spec

# Once your satisfied; build the libgphoto2 rpm first; it won't take
# too long (maybe 5 minutes or so)
rpmbuild -ba SPECS/libgphoto2.spec

# When this is done you'll have several RPMS built
find RPMS SRPMS -type f

# We need to install the libgphoto2-devel and libgphoto2 into our mock
# environment as they are required to build the gphoto2 package
rpm -Uhi RPMS/libgphoto2-devel-2.5.2-1.el6.x86_64.rpm 
         RPMS/libgphoto2-2.5.2-1.el6.x86_64.rpm

# Now we can build gphoto2 (this goes really fast - 10 seconds or so)
rpmbuild -ba SPECS/gphoto2.spec

# we're now done with our mock environment for now; Press Ctrl-D to
# exit or simply type exit on the command line of our virtual
# environment
exit

# We'll return to the directory we were previously in.  We can copy
# out the packages we just built at this point.Ignore the warning
# about SELinux if you get one. It doesn't impact our goals at this
# moment.
mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/gphoto2-2.5.2-3.el6.src.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/libgphoto2-2.5.2-1.el6.src.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gphoto2-2.5.2-3.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gphoto2-debuginfo-2.5.2-3.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/libgphoto2-2.5.2-1.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/libgphoto2-debuginfo-2.5.2-1.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/libgphoto2-devel-2.5.2-1.el6.x86_64.rpm .

GVfs can provide an easy mountable filesystem out of the PTP protocol for those who don’t like the Command Line Interface (CLI) gphoto2 provides. For those who think they’ll use it (or already are) can now recompile it against the new library we just built along with a small patch file to make it possible. The patch is already prepared in the source rpm I provide in the example below. If you wish to download the GVfs source that ships with CentOS instead; consider that it won’t compile right out of the box with libgphoto2 without the patch I backported from a newer distribution. You can skip this if you don’t use GVfs.

# Initialize our Environment
mock -v -r epel-6-x86_64 --init

# Install the only dependency we know mock can't otherwise fetch
# externally since it's sitting right here in front of us
mock -v -r epel-6-x86_64 --install 
   libgphoto2-2.5.2-1.el6.x86_64.rpm 
   libgphoto2-devel-2.5.2-1.el6.x86_64.rpm

# Download the version of gvfs that includes the patch I created
wget --output-document=gvfs-1.4.3-16.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/n-cFArw3i4/20131007/ptp/gvfs-1.4.3-16.el6.src.rpm?dl=1

# GVfs has one problem... it won't compile against the new libraries
# and design offered by the latest version of libgphoto2. I've already
# modified it to handle the patch (112) and incremented the build so
# it can easily built onto your system.
mock -v -r epel-6-x86_64 --installdeps gvfs-1.4.3-16.el6.src.rpm
mock -v -r epel-6-x86_64 --copyin gvfs-1.4.3-16.el6.src.rpm /builddir/build

# Shell into our environment
mock -v -r epel-6-x86_64  --shell

# Change to our build directory
cd builddir/build/

# Install our Source RPM (you can refer to the above section if you
# feel the need to inspect the contents first)
rpm -Uhi gvfs-1.4.3-16.el6.src.rpm

# Here is your chance to preview the patch (112) i put in place as well as
# the SPEC file that I updated to accomodate it.
less SOURCES/gvfs-1.4.3-gphoto25-support.patch
less SPECS/gvfs.spec

# Build GVFS
rpmbuild -ba SPECS/gvfs.spec

# we're now done with our mock environment for now; Press Ctrl-D to
# exit or simply type exit on the command line of our virtual
# environment
exit

# We'll return to the directory we were previously in.  We can copy out
# the packages we just built at this point (ignore the Warning about
# SELinux if you get one. It doesn't impact our goals at this moment.
mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/gvfs-1.4.3-16.el6.src.rpm .

mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-devel-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-obexftp-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-fuse-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-debuginfo-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-archive-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-afc-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-gphoto2-1.4.3-16.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/gvfs-smb-1.4.3-16.el6.x86_64.rpm .

SANE backends grants access to your scanner software you may or may not be using. It tool will have to be recompiled if you were using it as it links to the gphoto2 libraries. You can skip this if you don’t use the backend.

# Initialize our Environment
mock -v -r epel-6-x86_64 --init

# Install the only dependancy we know mock can't otherwise fetch
# externally since it's sitting right here infront of us
mock -v -r epel-6-x86_64 --install 
   libgphoto2-2.5.2-1.el6.x86_64.rpm 
   libgphoto2-devel-2.5.2-1.el6.x86_64.rpm

# Download the sane-backends package
wget --output-document=sane-backends-1.0.21-4.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/v5VyYHjsUu/20131007/ptp/sane-backends-1.0.21-4.el6.src.rpm

# Prepare the environment to support the sane-backend libraries
# You should be noticing a trend now as to how we're getting
# all the compilation and setup done.
mock -v -r epel-6-x86_64 --installdeps sane-backends-1.0.21-4.el6.src.rpm
mock -v -r epel-6-x86_64 --copyin sane-backends-1.0.21-4.el6.src.rpm /builddir/build

# Install our Source RPM (you can refer to the above section if you
# feel the need to inspect the contents first)
rpm -Uhi sane-backends-1.0.21-4.el6.src.rpm

# The only change I made to the SPEC file was to increment the build #
# so it would link properly back to our libgphoto2 libraries.
# Thankfully there is no patch need here.
less SPECS/sane-backends.spec

# Build GVFS
rpmbuild -ba SPECS/sane-backends.spec

# we're now done with our mock environment for now; Press Ctrl-D to
# exit or simply type exit on the command line of our virtual
# environment
exit

# We'll return to the directory we were previously in.  We can copy out
# the packages we just built at this point (ignore the Warning about
# SELinux if you get one. It doesn't impact our goals at this moment.
mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/sane-backends-1.0.21-4.el6.src.rpm .

mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sane-backends-devel-1.0.21-4.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sane-backends-1.0.21-4.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sane-backends-libs-gphoto2-1.0.21-4.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sane-backends-libs-1.0.21-4.el6.x86_64.rpm .
mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sane-backends-debuginfo-1.0.21-4.el6.x86_64.rpm .

You are now all done with the building!

Installation

You can upgrade/install your system with these new packages through the following (or variations of) commands:

# You may need to tailor the lower line depending what you have
# installed on your system. In my case, I also use the smb package
# where as you might not.  You can remove that from the line below
# if you wish.
yum localinstall libgphoto2-2.5.2-1.el6.x86_64.rpm gphoto2-2.5.2-3.el6.x86_64.rpm 
   gvfs-1.4.3-16.el6.x86_64.rpm gvfs-fuse-1.4.3-16.el6.x86_64.rpm 
   gvfs-gphoto2-1.4.3-16.el6.x86_64.rpm gvfs-smb-1.4.3-16.el6.x86_64.rpm 
   gvfs-archive-1.4.3-15.el6.x86_64

# in fact; if you want be really clever, I suppose you could do
# it like this:

# The following will loop the rpms we built and prepare a yum
# upgrade command for you
PKGS=$(find . -mindepth 1 -maxdepth 1 -type f -name '*.rpm' ! -name '*.src.rpm' -exec rpm -qp --queryformat="{}|%{NAME} " {} ;)
FILES=""
for PKG in $PKGS; do
   FILE=$(echo $PKG | cut -f1 -d'|')
   ID=$(echo $PKG | cut -f2 -d'|')
   rpm -q $ID &>/dev/null
   [ $? -eq 0 ] && FILES="$FILES $FILE"
done
echo "$FILES" | egrep -q "gphoto2"
if [ $? -ne 0 ]; then
   echo "Note: You're not using gphoto2 at all right now."
   FILES="$FILES libgphoto2-2.5.2-1.el6.x86_64.rpm gphoto2-2.5.2-3.el6.x86_64.rpm"
fi
echo "Type the following to upgrade/install it into your system:"
echo "  yum localinstall $FILES"

GPhoto2 CLI Reference

Just a script file I created and keep in ($HOME/bin) for myself to simplify extracting content from my camera when I connect it.

#!/bin/sh
# Script: getPhotos.sh
# Author: Chris Caron
# Date: Oct 7th, 2013
# Desc: Just a really simple tool for extracting all of the
#       images off of the camera based on the date you run
#       it.
PHOTOALBUM="$HOME/Nikon"
NOW=$(date +'%Y-%m-%d')

[ ! -d "$PHOTOALBUM/$NOW" ] && mkdir -p "$PHOTOALBUM/$NOW"
pushd "$PHOTOALBUM/$NOW" && gphoto2 --get-all-files
if [ $? -eq 0 ]; then
  # Transfer went okay; We need the recurse entry so we look
  # past the / directory
  gphoto2 --delete-all-files --recurse
fi
popd &>/dev/null

But it’s really worth checking out all the great options and examples gphoto2 offers if you choose to use it. The man pages show all of the other options supported; it truely is a fantastic tool!

Credit

Please note that this information took me several days to put together and test thoroughly. I may not blog often; but I want to re-assure the stability and testing I put into everything I intend share.

If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

Sources

  • I used pkgs.org to obtain rpm source packaging for libgphoto2, gphoto2, gvfs, and sane-backends so I could rebuild with content that was already stable and tested.
  • The gphoto official website was a great source of information as to how to utilize their tool and explain how it works.
  • I can’t find the examples I found for the GVfs patch I wrote at the time. But Googling for it now turns up many results of people who have done the same thing. Although at the time I regret not tracking the source I used as reference; you will see a similar patch here. Keep in mind this link is again nothing but a reference; it patches a newer version of GVfs over the one shipped with CentOS and RHEL. If you choose to use it over mine; you’ll need to read from it and rebuild the patch file yourself. It will definitely not work as is.