My thoughts on Slackware, life and everything


How to access your e-books online

In a previous article about the Calibre e-book library management program, I wrote that I did away with USB cable connections to transfer e-books from my Calibre library to my E-reader. Instead, I made my e-book library accessible on-line and now I am able to download my books securely over the Internet – no matter where I am, as long as I have a network connection.

In this article today, I am going to explain how I make my Calibre library accessible on-line.

Understandably, the article will be Slackware-centric, because that is where I have my Calibre library and where I run all the programs that I need. But, the technology and the configuration is generic enough that readers of this article running another distro or even employing an embedded (ARM) device will be able to make it work.

Which software is used?

Apache and PHP are standard part of Slackware Linux. I assume that you know how to setup an Apache web server. The good news is that Slackware’s default httpd configuration works out of the box. However, it does not enable a secure (https) web site. That part is on you.
If your content server is going to be used in your home network only, then HTTPS is not even needed.
I have a package for Calibre in my repository which of course you will definitely need if you want to build an e-book library.
You’ll have to download the ZIP file of the latest COPS release from – the ZIP contains the extra stuff that is not contained in the source .tar.gz file.
The remainder is just configuration.

Now let me explain my setup.

The Calibre library

It all starts with Calibre of course. It is a desktop program, available for Linux, Windows and MacOS. It stores your e-book library as a directory tree.  The directories immediately below the root of the tree are the book authors. In the root of the directory tree, Calibre creates a SQLite database file containing all the library metadata. The simple directory structure and the SQLite database file make that a Calibre library is independent of the Operating System that Calibre runs on. Its database scheme can be updated between major releases though. From within the Calibre GUI, it is however trivial to re-create this database file from scratch if it becomes corrupted.
This simple library setup has the advantage that if you store the library on a Cloud service like Dropbox, you can have access to your library from multiple computers running different Operating Systems (but preferably all the same version of Calibre). As long as one person accesses the library at any time, the Calibre database file will not get corrupted. This is how I have setup Calibre for my wife so that she can manage her e-books from every computer in the house.

Where to create the library

Myself, I use Calibre on a Linux machine which runs 24/7 (my package-build server in fact). I run a XFCE graphical desktop session inside a VNC server and that allows me to work in a desktop environment that’s always there for me. I use NoVNC to access this desktop using a web browser and that is perfect for corporate envronments which put a firewall up for everything except HTTPS traffic. Perhaps I’ll write another article sometime, explaining how to set that up.

What matters is that the Calibre library is stored on a machine with Internet access, and that this computer is running a web server like Apache. In Slackware, Apache httpd is the default webserver program.
I made this web server accessible from the Internet by configuring my ISP’s Internet router to forward ports 80 (http) and 443 (https) to the internal IP address of my Slackware machine.
For the sake of this article, let’s assume that two separate Calibre libraries exist on this computer, mine is located in /data/Calibre/EricLibrary and my wife’s books are stored in /data/Calibre/WifeLibrary . In Calibre itself, you can easily switch between libraries so that me and my wife are both able to maintain a separate collection of books. Our book tastes have no overlap…

How to configure the web server

I want both libraries to be accessible online.
I do not want to use Calibre’s own content server but instead use COPS. COPS is a collection of PHP scripts, and it does not require the Calibre program to function. It just needs access to the physical directory containing your Calibre library and it understands the Calibre SQLite database format.
If you want to get creative, you can install COPS on an Internet server – e.g. if you do not have a webserver at home. In that case, use a cloud storage service like Dropbox to keep your library in sync between your computer at home and that remote server running Apache.

My example setup is a Slackware computer at home with Apache enabled:

# chmod +x /etc/rc.d/rc.httpd
# /etc/rc.d/rc.httpd start

Apache uses the concept of a DocumentRoot, which is a directory accessible by the httpd server. Everything stored below that DirectoryRoot will be accessible via the URL of the webserver. Never store files below the DocumentRoot that you do not want to share!
I downloaded and extracted the COPS zip file directly into the Apache DocumentRoot directory (the default in Slackware is configured in the file ‘/etc/httpd/httpd.conf’ to be “/srv/httpd/htdocs/” but you can change that default location of course):

# cd /tmp
# links
# cd /srv/httpd/htdocs/
# unzip /tmp/
# ln -s cops-1.1.3 mybooks
# cd mybooks
# cat <<EOT > config_local.php
$config = array();
$config['calibre_directory'] = array ("Eric" => "/data/Calibre/EricLibrary/", "Wife => "/data/Calibre/WifeLibrary/");
$config['cops_title_default'] = "Aliens Library";
$config['cops_use_url_rewriting'] = "1";
$config['cops_recentbooks_limit'] = '100';
$config['cops_update_epub-metadata'] = "1";
$config['cops_books_filter'] = array ("Books" => "!News");

The lines from the “cat << EOT” until the “EOT” on its own line is called a “here document“. You can copy/paste these lines into a terminal and it will create the file “config_local.php” with the content as shown between the “EOT” lines.
This is a configuration which allows access to two separate libraries. If you access the “recently added” section of a library it will show the latest 100 books instead of the default 20 books. It does some URL re-writing to generate cleaner URLs and it will not show any News sources (in Calibre, you can add various paid-for and free newspaper subscriptions and those will then be dpwnloaded daily, but I do not want to see those online).
Compare this configuration of mine to the ‘config_local.php.example’ file in the COPS directory. The above is not all you can configure, although it is sufficient. All configurable parameters are documented in ‘config_default.php’ which also defines their default values.

You’ll have noticed that I created a symlink to the extracted cops files, which allows me to use an easy to remember URL to access my books. Suppose my apache server is accessible as – then my COPS installation will be accessible at .

That’s all!

Under the above ‘mybooks’ URL you will now find a COPS installation with two Calibre libraries with separate names “Eric” and “Wife”. Pick a nice template and theme, and try out the ebook-reader which is part of COPS (you  can read EPUBs in a web browser, no E-reader required).

Accessing COPS through the OPDS protocol

You want to configure your E-reader to access the library. An E-reader which contains a webbrowser is easy, just open and click a book to download it.
Other E-readers, like FBReader for Android, are able to connect to an OPDS (Open Publication Distribution System) catalog. The COPS program exposes your library as a OPDS catalog if you just add ‘feed.php’ to the URL.
I.e. enter into the Network Library menu of FBReader and you’ll get instant access to “Alien’s Library” where you can browse Authors, Series, Categories, Recent Additions and read book descriptions, and then download the books you want to read.
If you want to always start with a list of recent library additions, you  can add ‘?page=10’ at the end of the URL so that it becomes

Hiding the cops files from the Apache DocumentRoot

Some people feel a bit anxious having these cops files accessible in their DocumentRoot – suppose someone gains access to them trough other means. You can use Apache’s “Alias” directive to install COPS in e.g. /usr/local instead. In that case, add the following lines to your /etc/httpd/httpd.conf or whatever file holds your website definition:

    <Directory "/usr/local/cops-1.1.3/">
        AllowOverride All
        Options +ExecCGI +FollowSymLinks
        Require all granted
    Alias /mybooks/ /usr/local/cops-1.1.3/

You should check the validity of your httpd configuration before restarting the webserver:

# apachectl configtest
# /etc/rc.d/rc.httpd restart

And the URL to access your library will remain the same, i.e. , only in this case your actual DocumentRoot directory will be empty.

Adding some sense of security

After following the above instructions, you now have an e-book library online whose access is not restricted in any way. If some search engine passes by it will neatly catalog all your books for other people to find. Oops!

You’ll need a basic access restriction at least. Apache offers a ‘Basic Authentication’ setup which will prompt anyone who tries to access your library for a valid account and password.
To achieve this, let’s first create a password file containing the account/password combinations for the people you want to grant access. For the sake of this example, I will grant myself and my wife access by creating account/password combinations for us in a file which we will then use in  our Apache configuration.
The first ‘htpasswd’ command below has an additional ‘-c’ parameter to create the file “/etc/httpd/passwords/htaccess.opds”:

# mkdir -p /etc/httpd/passwords/
# htpasswd -b -c /etc/httpd/passwords/htaccess.opds eric ericspassword
# htpasswd -b /etc/httpd/passwords/htaccess.opds wife wifespassword

The file will then have these contents, you see that the passwords are now MD5 encrypted:


Read “man htpasswd” to find out more about this command and its parameters.

Next you need to change the Apache <Directory></Directory> block which I provided above. It will become like this:

    <Directory "/usr/local/cops-1.1.3/">
        AllowOverride All
        Options +ExecCGI +FollowSymLinks
        AuthBasicAuthoritative off
        AuthUserFile /etc/httpd/passwords/htaccess.opds
        AuthType Basic
        AuthName "OPDS Server"
        Require valid-user
        # Require all granted
    Alias /mybooks/ /usr/local/cops-1.1.3/

Once you made these changes, validate the configuration and restart the webserver:

# apachectl configtest
# /etc/rc.d/rc.httpd restart

Now you will be greeted by an authentication request, next time you access your library. Only those users whose username/password combinations are stored in “/etc/httpd/passwords/htaccess.opds” will be able to get access.

Using encrypted HTTP

You should realize that these passwords will still be transmitted in cleartext if your webserver is not using HTTPS. It is possible for people to sniff the network connection and find your credentials.

I think however that instructions about enabling HTTPS for your Apache belongs in another blog post. Let me know in the comments section below if you have a need for such an article.
Also, let me know if parts of the above instructions are too cryptic and I will update the text where needed.

Good luck! Eric

KDE bugfixes and how to use my modular KDE.SlackBuild

KDE 4.7.2 fixes

In the past week, fixes have been posted to the KDE packagers mailing list, asking us to apply those to our packages. Both fixes are important enough that I updated my kdelibs and kdepim-runtime packages.

There is a fix for kdelibs of which Sebastian Trueg states “Hi packagers, sadly I introduced a serious issue into kdelibs 4.7.2 which was intended to be a fix. This bug prevents any query which does NOT use wide unicode characters to fail. The attached patch provides a workaround for this issue and will make all queries work“. Another patch is for the kdepim-runtime package. It fixes bug 283467Kmail has duplicated folders after migration from previous version

Both updated packages are now available in the KDE 4.7.2 section of my “ktown” repository.

The 32bit packages:

The 64bit packages:

KDE.SlackBuild HOWTO

Some people have asked how to work with the modularized KDE.SlackBuild script. It is not immediately clear to everybody for instance how to apply patches, or how to rebuild individual packages. I will use this  opportunity to explain a bit about the innards of the new framework.

The KDE.SlackBuild concept is loosely based on Patrick’s modular X.Org build. For a user of the script, there are not really that many differences compared to building X.Org. Let me tell you more:

The directory structure

  • KDE.SlackBuild :this is the script which you run to build the complete KDE Software Compilation, or any number of its individual packages.
  • KDE.options : this file contains common options for all packages. For instance, it contains the version of KDE we are compiling, and the overall build number (usually all the packages will get a build number “1”)
  • build/ : If a package needs another build number than defined in KDE.options, you should create a new file in the “build” directory that must carry the name of this package. Iinside the file you write the desired build number.
  • cmake/ : This directory contains the actual compilation script, called “cmake”.. The cmake program is used to configure the source code for Qt/KDE based applications (make will be called afterwards to compile the configured soiurces). If an application needs a non-standard set of cmake/make parameters or commands, you must create a new file in this directory, carrying the name of the application, and inside you add the custom compilation commands. Use the default “cmake” script as your starting point. The KDE.SlackBuild script will then use this custom file instead of the default “cmake” file.
  • docs/ : The KDE.SlackBuild script will add a couple of common documentation files from the source tarball into the resulting package’s “/usr/doc” diretory. Think of files like “AUTHORS* CONTRIBUTING* COPYING* HACKING* INSTALL* MAINTAINERS README* NEWS* TODO*“. If an application’s source tarball contains other documentation files that you want to have added instead, then you should create a new file in the “docs/” directory, containing the application’s name and inside you add the files that the KDE.SlackBuild should add to the package’s “/usr/doc” directory.
  • : To every package a generic “” script will be added. This is the script which is run by “installpkg” and “upgradepkg” after installing the package (for instance to refresh the KDE menu or to register new MIME types). If an application needs its own “” script “” then you add it to the “” directory, the file should carry the name of the application (I am repeating myself a lot but that’s because the concept is identical for all these subdirectories)
  • makepkg/ : Creating the actual package after its compilation has been completed is accomplished by calling the “makepkg” command. If you have a package that needs a custom makepkg commandline you can add that here.
  • modularize : KDE Software Collection is built out of modules (think of modules like “kdelibs”, “kdenetwork”, etc…). These modules used to be distributed as big “monolithic” source tarballs in the past, and we would create one Slackware package for every module. This has changed since KDE 4.7.0 where the sources of these modules were split off into a lot of separate tarballs. The KDE.SlackBuild still builds one package per module if you do not tell it to do otherwise. If you need/want to split up a module into sub-packages, then you edit section in the “modularize” file which applies to this module. Every name you add to the “modularize” file (which must correspond to a source tarball of the same name) will be built as a separate package. for instance, the “kdebase” section contains the following lines, which means that compiling the “kdebase” module will result in the additional packages: konsole, kate, kde-wallpapers, kde-workspace, kde-runtime: These separate programs used to be included in the kdebase package itself previously:

# kdebase:

  • modules/ : This directory contains the KDE modules, one file per module. Inside each file you will find the basenames of the individual source tarballs which make up this module. If a source tarball is listed inside one of these files but is not listed in the “modularize” file (see the previous bullet) then the binaries resulting from compiling this source will be included into the main module package and not be split off into its own separate package.
  • noarch : Most of the KDE packages will be built for a specific machine architecture (i486 or x86_4 for instance). If a package does not contain machine-dependant code then its architecture type should be “noarch“. In that case you should add the name of the package to the “noarch” file.
  • package-blacklist :  The collection of source tarballs is bigger than what we support on the Slackware Linux platform (some of the sources apply to other distros only or to MS Windows, such as the “csharp” tarball for instance). The “package-blacklist” file is where you enter the names of source tarballs to skip compiling  Just the application’s basename – no version.number is needed.
  • patch/ : This directory contains patch scripts for applications (see further down for more detail).
  • post-install/ : A few packages need additional work after the “cmake && make && make install” sequence. If you need that, you can add a file with the name of the application inside the “post-install” directory containing those commands.
  • pre-install/ : A few packages need additional preparation before the “cmake && make && make install” sequence. If you need that, you can add a file with the name of the application inside the “pre-install” directory containing those commands.
  • slack-desc/ : Every package that is going to be created needs a descriptive file (the package’s slack-desc file). They go into the “slack-desc” directory, each carrying the name of their application.
  • src/ : All the KDE sources go in here. It does not matter if you put some of the sources into their own subdirectory, the KDE.SlackBuild script will figure out where they are. For instance, I moved the “extragear” sources (these are the applications which do not belong to the core of KDE SC) into a subdirectory “extragear” but in fact the name can be arbirtrarily chosen.

Compiling one or more single packages

By default, the compilation script “KDE.SlackBuild” will compile all the packages for the KDE Software Compilation. If you want to build only one module, or only a few of a module’s sub-packages, then you have to call the script with the appropriate parameters. If you want to build a sub-package you have to specify to which module it belongs. A module and a sub-package are separated by a colon (:). Multiple sub-packages are separated by a comma (,).

The generic method is:

# ./KDE.SlackBuild [ module[:subpackage1,subpackage2,…] [ module[:subpackage1,subpackage2,…] …] ]

For instance:

  • To compile only the “kdelibs” module, you run:

# ./KDE.SlackBuild kdelibs

  • To compile the “kdelibs” module as well as the kdepim-runtime package which is a component of the “kdepim” module:

# ./KDE.SlackBuild kdelibs kdepim:kdepim-runtime

  • To compile packages for kalgebra, kstars and marble which are all components of the “kdeedu” module, you run:

# ./KDE.SlackBuild kdeedu:kalgebra,kstars,marble

You see that it is actually quite simple, although a bit different from the old method (until KDE 4.6) of building individual packages.

Applying a patch to a KDE package

If you need to patch a package in the KDE Software Compilation, then you must first create a subfolder in the “patch” directory with the name of the package. Then add the patch file into that subdirectory. Finally create a file <packagename>.patch (or edit the file if it already exists) in the “patch” directory, The file “<packagename>.patch” must perform the actual patching, and the patch command must be appended with the following series of commands in order for KDE.SlackBuild to determine if the patch failed or not:

 || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }

And to make the new package name differ from the old version, you have to update its BUILD number. Edit (or create) a file in the “build” directory for the package and write the new BUILD number in that file. Usually the new BUILD number is one higher than the previous if that was an integer value.


Checking if your sources match the build files

Suppose you are not certain if the source tarballs you added to the “src/” directory match the available slack-desc files and module files, you can run the build script with an additional environment variable. If you run the following command, the KDE.SlackBuild script will compare the content of the “src” directory with the content of the “slack-desc” directory and the content of the “modules” directory and will complain if it finds anything amiss (and abort the script):

# PRECHECK=yes ./KDE.SlackBuild


I hope this clears up things a bit for you!

Cheers, Eric

© 2024 Alien Pastures

Theme by Anders NorenUp ↑