Download YouTube videos for offline use on old Android phone

I have an old Android phone (ZTE Blade, Android 2.1), that I’m using to watch videos on the go mostly. Videos can be played smoothly only using hardware decoder and its capabilities are limited to max resolution 800×480 and H264 codec with baseline level 3.1 profile (avc1.4d40xx). Unfortunatelly YouTube recently changed minimal H264 profile for most videos to main profile. Only 640×360 (format 18, avc1.42001E) does support H264 baseline profile level 3.0. And of course it would be nice to watch videos with closest to display (800×480) resolution, but not in only available low 640×360. But next higher resolution is 480p. 480p videos usually have width around 854, that is greater than 800 supported by hardware. So down scalling will be necessary.

It’s possible to solve all these problems with youtube-dl. This is very nice tool. It allows download videos from youtube and use ffmpeg/avconv to do some postprocessing. The following command line downloads video with higher than 800 width and does scalling and reencoding into supported by hardware H264 profile is necessary. On my system (Debian Buster) youtube-dl is using ffmpeg.

$ youtube-dl -f ‘bestvideo[ext=mp4][height<=480][width<=900]+bestaudio[ext=m4a]/mp4′ –postprocessor-args “-vf scale=\’min(800,iw)\’:-1 -c:v h264 -profile:v baseline -level 3.1” URL

If you want to have these arguments to be default, then save them in user specific configuration file in ~/.config/youtube-dl/config.

-f ‘bestvideo[ext=mp4][height<=480][width<=900]+bestaudio[ext=m4a]/mp4′ –postprocessor-args “-vf scale=\’min(800,iw)\’:-1 -c:v h264 -profile:v baseline -level 3.1”


Run Cloud.Mail.Ru agent inside firejail

It’s usually not a good idea to run proprietary code on your machine. But if you really want to do so, it’s recommended to run it inside of sandbox to at least minimize the risks. There are a lot of different approaches for that: VMs, LXC, Docker, Firejail … .

Cloud.Mail.Ru is Russian mail provider, that gave in January 2014 1Tb of storage for free for new accounts. I’m running agent only when it’s needed inside of Firejail Security Sandbox.

Below is my profile used for native GNU/Linux cloud agent. Options that may require some changes according to particular user configuration are set to bold. The profile should be saved in ~/.config/firejail/cloud.profile.

# ./cloud (agent for Cloud.Mail.Ru) profile
# Persistent global definitions
include /etc/firejail/globals.local

### basic blacklisting
include /etc/firejail/
include /etc/firejail/
include /etc/firejail/
include /etc/firejail/

# path to executable
# no deb/rpm was installed to avoid running
# unknown install scripts as root on my system
noblacklist ${HOME}/bin/usr/Cloud.Mail.Ru
whitelist ${HOME}/bin/usr/Cloud.Mail.Ru

### home directory whitelisting
whitelist ${HOME}/.config/Mail.Ru
whitelist ${HOME}/.Mail.Ru_Cloud
whitelist ${HOME}/.local/share/Mail.Ru
whitelist ${HOME}/.config/Mail.Ru

# path to data folder
whitelist /media/system/data/user/data/

include /etc/firejail/

### filesystem
private-bin bash,ls
private-etc fonts,passwd,ssl,hosts,drirc,xdg,gtk-3.0,selinux,resolv.conf
blacklist /var

### security filters
caps.drop all

### network
protocol unix,inet,inet6,
# net enp0s31f6

### environment
shell none

noexec ${HOME}
noexec /tmp

To run agent inside of sandbox use command ‘firejail cloud’. You may want to modify accordingly corresponding desktop file to use firejail as well.

Freedombox and native IPv6


Freedombox is very useful and interesting project. It allows people to host cloud services by themselves, so their data are kept private. It can run on any hardware, that supports Debian.  I’m running it on APU2, that has several Ethernet interfaces and therefore it can not only host services for me, but work as a standard router and WiFi AP (using mPCI-E extension card) as well.

DHCPv6-PD and Network Manager

My ISP has native IPv6 support. It gives to every user /64 subnet via DHCPv6-PD. Freedombox uses Network Manager (NM) to handle network connections. NM support prefix deligation (PD) since version 1.6 using ‘shared’ method for IPv6 connections. NM use  DHCPv6 (dhclient, isc-dhcp-client package) for that. For each internal interfaces with ‘shared’ method for IPv6 NM requests separate IPv6 prefix (adds -P to dhclient command line). Sounds good. Unfortunatelly NM requires that DHCPv6 server gives IP address for external uplink interfaces as well. But my ISP only gives a prefix and external interfaces use link-local address to forward IPv6 packets (received using router advertisement). Because NM doesn’t receive IPv6 address for external interface, it decides that DHCP failed and kills dhclient. As a result IPv6 isn’t working after DHCP lease is expired.

To setup native IPv6 I set for external and internal interfaces method ‘auto’ in Network Manager and used this article as a start and took scripts from this repo. But I need some changes to make it working in my case.

Basic idea is here that as NM configures external interface, it calls scripts from /etc/network/if-up.d/ directory. In this directory there is script that starts dhclient with a proper command line parameters. As dhclient receives IPv6 prefix, it calls scripts from /etc/dhcp/dhclient-exit-hooks.d/. This script looks at deligated prefix and updates radvd config in /etc/radvd.conf and restart router advertisement service for internal network.

What changes were necessary for me?

DHCP client identifies itself using DUID (DHCP Unique Identifier). There are different types of it:

  1. Link-layer address plus time (DUID-LLT)
  2. Vendor-assigned unique ID based on Enterprise Number (DUID-EN)
  3. Link-layer address (DUID-LL)

My ISP (as many others ISPs) requires DUID in format DUID-LL. Most routers support this format already. dhclient uses by default DUID-LLT. It was necessary for me to add ‘-D LL’ to 99-ipv6 file.

Second NM calls if-up.d scripts twice for ADDRFAM=inet and ADDRFAM=inet6. I think it’s not necessary to launch dhclient twice. So I’ve added check into 99-ipv6.

if [ “$ADDRFAM” != “inet6” ]; then
exit 0

And finally I commented out reloading firewall rules (/etc/network/ip6tables reload), because Freedombox is using new firewalld service. We come back later to firewall settings.

But this was not enough. I’ve got problem with dhclient. He reported

Can’t bind to dhcp address: Cannot assign requested address
Please make sure there is no other dhcp server running and that there’s no entry for dhcp or bootp in /etc/inetd.conf. Also make sure you are not running HP JetAdmin software, which includes a bootp server.  If you think you have received this message due to a bug rather than a configuration issue please read the section on submitting bugs on either our web page at or in the README file before submitting a bug. These pages explain the proper process and the information we find helpful for debugging..

It looks like already known bug in Debian bug tracker and still exists in Debian Stretch. But most likely it’s fixed in latest Ubuntu. I fixed by applying Ubuntu patch.


Freedombox has enabled by default firewall. But for some reason forwarding for IPv6 is blocked. Add rule to enable it.

$ firewall-cmd –direct –add-rule ipv6 filter FORWARD 0 -i $INT_IFACE \

$ firewall-cmd –persistent –direct –add-rule ipv6 filter FORWARD 0 -i $INT_IFACE \


I love Free Software Day 2016

This is amazing campaign of FSFE

If you want to participate in the campaign, you can order promotion materials on FSFE site for free, but I had no time to do this.

I’m postcrossing user. So I decided to support the campaign with postcards. Unfortunately there is only one type of postcards available on the FSFE site. Therefore I made another four postcards based on other FSFE promotion materials (flyer, posters, sticker). All images are made for the same size 141 mm x 100 mm. This makes possible to place four postcards on standard A4 page.

This slideshow requires JavaScript.

You can download images here:

  1. IloveFS-front-1
  2. IloveFS-front-2
  3. IloveFS-front-3
  4. IloveFS-front-4
  5. IloveFS-front-5
  6. IloveFS-back

All these images are available under the same licence CC0 as original sources.


Using FTDI-based devices with ftd2xx.dll under wine

I have pretty good USB oscilloscope (, that unfortunately does not come with software for GNU/Linux. I’ve got it working inside of KVM Windows-VM. But it’s not the best solution and performance is worst in this case too.

I’ve seen previously some posts (in English and in Russian) about wine wrapper for ftd2xx.dll. Unfortunately I haven’t much lock with this wrapper. Source seems to be not available anymore. But I liked the idea. I’ve found another much newer wine wrapper on github. Here I’ll try to describe shortly how I’ve built it on Debian Testing (Stretch) x86_64 architecture.

The main problem is that my system is x86_64 and I need to build for i386.

Firstly to  compile source code is used winegcc, that “emulates” mingw compiler under Linux. It’s included in wine64-tools and wine32-tools. For i386 I need wine32-tools package, but I couldn’t install it, because of broken dependencies (perl and some other stuff). I could only install wine64-tools. Additionally I installed gcc-multilib to compile for 32 bit.

Good. Now we have winegcc. Winegcc is not in PATH. To fix that add winegcc to the PATH.

$ export PATH=/usr/lib/x86_64-linux-gnu/wine:$PATH

Another problem is that winegcc64 generates code for x86_64. To fix that in Makefile add ‘-m32’ to all invocation of winegcc (it’s not enough to add ‘-m32’ to CFLAGS only in one place).

Next trouble is, that linker couldn’t find.

ld: Relocatable linking with relocations from format elf64-x86-64 (/usr/lib/x86_64-linux-gnu/wine/libwinecrt0.a(dll_entry.o)) to format elf32-i386 (ftd2xx.Y3kKUq.o) is not supported

To fix that install libwine-development-dev:i386 package and add to LIBS variable in Makefile full path to 32-bit libraries (-L/usr/lib/i386-linux-gnu/wine-development/).

The build succeeded. Now it’s time to install the binaries. Unfortunately install target is broken to with latest wine on Debian, because of moving to the multilib environment. winedllpath from the git-repository doesn’t detect path correct. wine libraries are moved to /usr/lib/i386-linux-gnu/wine. To fix install target I’ve just replace definition of  WINEDLLPATH with ‘/usr/lib/$(ARCH)-linux-gnu/wine’.

I created deb package using checkinstall to manage binaries afterwards.

All was good and fun. Now check all this together. Oscilloscope software started, ftd2xx.dll was replaced with wrapper, but unfortunately segmentation fault happened as soon as the application tried to access FTDI device. I’ve not investigated this problem yet. Maybe later or maybe I’ll just write driver for sigrok / pulseview to support this oscilloscope.

Here there are all modification that I’ve done to build wine wrapper in patch format:

diff –git a/Makefile b/Makefile
index ee3d594..ceb15e7 100644
— a/Makefile
+++ b/Makefile
@@ -1,12 +1,13 @@
#Makefile for wineftd2xx<->ftd2xx shim dll
#Revised: 9/30/14
#WARNING: omitting frame pointer causes crashes
CFLAGS = -g -O0 -Wall
-LIBS=libxftd2xx.a -ldl -lrt -lpthread
+LIBS=-L/usr/lib/i386-linux-gnu/wine-development/ libxftd2xx.a -ldl -lrt -lpthread


-WINEDLLPATH := $(shell ./winedllpath $(ARCH))
+WINEDLLPATH := /usr/lib/$(ARCH)-linux-gnu/wine
ifeq (“$(WINEDLLPATH)”, “”)
$(error Can’t guess WINEDLLPATH — \
specify it with make WINEDLLPATH={ directory})
@@ -49,11 +50,11 @@ xftd2xx.h: $(IDIR)/ftd2xx.h Makefile
sed “s/WINAPI FT_/WINAPI xFT_/g” $(IDIR)/ftd2xx.h >$@

ftd2xx.o: ftd2xx.c xftd2xx.h WinTypes.h
– winegcc -D_REENTRANT -D__WINESRC__ -c $(CFLAGS) \
+ winegcc -m32 -D_REENTRANT -D__WINESRC__ -c $(CFLAGS) \
-I$(IDIR) -fno-omit-frame-pointer -o $@ ftd2xx.c ftd2xx.o ftd2xx.spec libxftd2xx.a
– winegcc $(LIBS) -mwindows -lntdll -lkernel32 \
+ winegcc -m32 $(LIBS) -mwindows -lntdll -lkernel32 \
-o ftd2xx.dll ftd2xx.o libxftd2xx.a -shared ftd2xx.spec

libftd2xx.def: ftd2xx.spec

How to find people for keysigning party using GnuPG / PGP

Hi, I want to list today some places where you can find people to exchange PGP signatures on your kees. In my city not much people use pgp.

  1. Here you can find local pgp user ready for keysigning
  2. Find local linux kernel developers
  3. Find local Debian developer or other debian users who also need a pgp signature
  4. Contact your local LUG and ask for a keysigning party

Build your own gcc compiler

Recently I needed a new c++ compiler with full support of C++11 standard. This support has the latest gcc (4.8.2). Unfortunatelly there is no built gcc 4.8.2 packages for my old Debian Squeeze system. The latest gcc build for Debian is 4.8.1 and it’s available only in testing and unstable. Because I don’t want to upgrade my system to testing or unstable and import of 4.8 package with resolving all of the dependencies is a mess, I decided to build gcc from source.

Actually it is not much different from building other programs from source. The process is pretty automated already. I’ve made a script that hopefully will help somebody to make this process even easier. Here you can find script and prebuilt gcc 4.8.2 (only c and c++ support) for Debian Squeeze.



# enable extra checks in bash script
set -u

function get_latest_version()
    VERSION=$(curl –ftp-pasv ftp://$SERVER/$GCC_PATH/ | grep ‘^drwx.*gcc-‘ | awk ‘{ print $9 }’ | sed ‘s/gcc-//’ | sort -V -r |  head -n 1)
    if [ “$VERSION” == “”  ]; then
        echo ‘Failed to get latest version of gcc’

# ——————————————————————
# set the user version
if [ “$VERSION” == “” ]; then

echo “Build Gnu C and C++ compilers $VERSION”

# ——————————————————————
# prepare directories
if [ ! -d $VERSION ]; then
    mkdir -p $VERSION

if [ ! -d build-$VERSION ]; then
    mkdir -p build-$VERSION

# ——————————————————————
# download gcc source code


if [ ! -e $SRC ]; then
    wget -c ftp://$SERVER/$SRC_PATH/$SRC
    if [ $? -ne 0 ]; then exit 1; fi

if [ ! -e $SRC_SIG ]; then
    wget -c ftp://$SERVER/$SRC_PATH/$SRC_SIG
    if [ $? -ne 0 ]; then exit 1; fi

# check signatures
gpg –verify $SRC_SIG
if [ $? -ne 0 ]; then exit 1; fi

# ——————————————————————
# unpack source code
if [ ! -d $SRCDIR ]; then
    tar -xf $SRC

# ——————————————————————
# download additional libraries needed for compilation
cd ..

# ——————————————————————
#                            configure
# ——————————————————————
cd build-$VERSION

# don’t use option
# –enable-version-specific-runtime-libs
# it seems to be broken for a long time

# –disable-multilib your final package will twice small as with
# multilib support (enabled by default)
CONFIG_OPT=”$CONFIG_OPT –disable-multilib”

# install not in the default /usr/local path
# I don’t want installed libraries to be overwritten (because of
CONFIG_OPT=”$CONFIG_OPT –prefix=/opt/x86_64-unknown-linux-gnu/$VERSION”

# compilers executable will have clearly different names
CONFIG_OPT=”$CONFIG_OPT –program-suffix=-$VERSION”

# build only needed programming languages
CONFIG_OPT=”$CONFIG_OPT –enable-languages=c,c++”
../$SRCDIR/configure $CONFIG_OPT  
if [ $? -ne 0 ]; then exit 1; fi


# ——————————————————————

# build binaries
make disclean

CPU_CORES=$(cat /proc/cpuinfo | grep ‘^processor’ | wc -l)
make -j $(( $CPU_CORES + 1 ))
if [ $? -ne 0 ]; then exit 1; fi

# build debian package

echo “gcc and g++ $VERSION” > description-pak

sudo checkinstall $PACKAGE_INFO –install=yes –default make install

cd ..