Ubuntu and a custom build zfs and spl from git

I wanted to try the 0.7.0-rc3 from git. So I cloned from git and changed to the zfs and spl version 0.7.0-rc3 tag.

Since ubuntu ships with a prebuilt zfs and spl my custom packages didn’t work.
It always loaded the prebuilt zfs and spl from the kernel modules directory but not the one I built.
I figured out a way to make it work nonetheless.

– check your currently running zfs module:

# modinfo zfs
filename:       /lib/modules/4.8.0-41-generic/kernel/zfs/zfs/zfs.ko

– remove kernel mods (make sure to have all zfs pools unmounted, otherwise it will fail):

rmmod zfs zunicode zcommon znvpair spl zavl

– remove kernel module from your current running kernel:

rm -r /lib/modules/$(uname -r)/kernel/zfs

– build deb packages for your currently running ubuntu (see their wiki):

cd $where_your_spl_from_git_resides
make clean; ./autogen.sh
cd $where_your_zfs_from_git_resides
make clean; ./autogen.sh
cd $where_your_spl_from_git_resides
./configure; make deb
for file in *.deb; do gdebi -q --non-interactive $file; done
cd $where_your_zfs_from_git_resides
./configure; make deb
for file in *.deb; do gdebi -q --non-interactive $file; done

– do a modprobe:

modprobe zfs

– check again the running zfs module:

# modinfo zfs | head -2
filename:       /lib/modules/4.8.0-41-generic/extra/zfs/zfs/zfs.ko
version:        0.7.0-rc3

After that it worked just well. I guess it has to be done for every new kernel release. If there is another better way instead of deleting modules from the kernel modules directory to make it work, please share.

PulseAudio erlaubt es nicht das Audio Ausgabegerät zu wechseln

Vielleicht liegt es am pavucontrol, dass nicht umgeschaltet werden kann. Nach ein wenig googeln findet man Kommandos, wie man die Audioausgabe über Konsole abändern kann.
pacmd move-sink-input 2 1 ging nicht. Fehler ist „Moved failed.“
Weiterer Details verrät:

hamster@hamsterkaefig:~$ pacmd list-sink-inputs
1 sink input(s) available.
    index: 2
  driver: <protocol-native.c>
  state: RUNNING
  sink: 2 <alsa_output.pci-0000_00_14.2.analog-stereo>
  volume: front-left: 65536 / 100% / 0,00 dB,   front-right: 65536 / 100% / 0,00 dB
          balance 0,00
  muted: no
  current latency: 50,91 ms
  requested latency: 23,22 ms
  sample spec: float32le 2ch 44100Hz
  channel map: front-left,front-right
  resample method: copy
  module: 14
  client: 14 <Tropico5>
    media.role = hex:
    phonon.streamid = hex:
    media.name = "Playback Stream"
    application.name = "Tropico5"
    native-protocol.peer = "UNIX socket client"
    native-protocol.version = "31"
    application.process.id = "30530"
    application.process.user = "hamster"
    application.process.host = "hamsterkaefig"
    application.process.binary = "Tropico5"
    window.x11.display = ":0.0"
    application.language = "de_DE.UTF-8"
    application.process.machine_id = "96177112fcaef6926d04e5b80000002e"
    application.process.session_id = "c2"
    module-stream-restore.id = "sink-input-by-application-name:Tropico5"

Dort steht bei flags: "DONT_MOVE"
Danach gegoogelt findet man die Lösung z.B. hier und hier

Man erstellt eine Datei im eigenen Home namens .alsoftrc mit Inhalt:


Raspberry Pi reset wireless lan to solve problems with no connection

I found a script on http://askubuntu.com/a/593589 which tried to reset the wlan interface in various ways. I modified that script a little with and installed in on cron and let it execute each minute (*/1 * * * * /root/bin/resetWifi.sh)


# program to check wifi and reset if not running
if [[ ! -z "$(ps waux | grep $0)" ]]; then exit 0; fi
exec 2>&1 1> >(tee -a $HOME/wificheck.log)
IWCONFIG_BIN=$(which iwconfig)
RFKILL_BIN=$(which rfkill)
PING_BIN=$(which ping)
DEVICE=$(iwconfig 2>/dev/null | grep 802 | awk '{print $1}')
function isPingWorking {
        if ${PING_BIN} -c 1 ${GATEWAY} >/dev/null 2>&1 ; then
                exit 0
                echo "didn't work :("
while true; do
        # Failed, try to reset wifi - sometimes works ok
        ifdown ${DEVICE}
        sleep 1
        ifup ${DEVICE}
        sleep 10
        echo "turn wlan stick power off... "
        ${IWCONFIG_BIN} ${DEVICE} txpower off
        sleep 3
        ${IWCONFIG_BIN} ${DEVICE} txpower auto
        echo "use rfkill to reenable wlan stick... "
        ${RFKILL_BIN} list
        ${RFKILL_BIN} block wifi
        sleep 3
        ${RFKILL_BIN} unblock wifi
exit 0

Test if you have rfkill installed. The other bins should be available on most default installations.

download from vitalsource

login and save session cookie:

wget --keep-session-cookies --user-agent=Mozilla/5.0 --save-cookies cookies.txt --post-data 'user%5Bemail%5D=someone%40someplace.com&amp;user%5Bpassword%5D=asdf&amp;return=https%3A%2F%2Fevantage.gilmoreglobal.com%2F%23%2F&amp;failure=https%3A%2F%2Fevantage.gilmoreglobal.com%2F%23%2Fuser%2Fsignin%2Ffailure%2Fsomeone%2540someplace.com&amp;jigsaw_brand=evantage' https://jigsaw.vitalsource.com/login

„print“ the whole page and look for the page with „print“ in it:

This will give you a html with all picture links in it. I saved it as links.txt
LINKS=$(sed -re '/src/!d' -e '/.js/d' -e '/.css/d' -e 's#.*src="(.*?)".*#https://jigsaw.vitalsource.com/\1#' -e 's#800#2048#' -e 's#%20# #' links.txt)
for i in $(echo $LINKS); do
wget --load-cookies cookies.txt ${i} -O "$(printf "%03d" ${counter}).jpg"

If printing isn’t available, it is possible to iterate through the pages and get the image source out of the html. Open the first page and look at the frame source code for something like „https://jigsaw.vitalsource.com/books/HK758SH-00-DATASH-E/pages/348102883/content“. The number 348102883 can be iterated.
You get the image source link with:

wget --header="Accept-Encoding: compress, gzip" --header="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" --user-agent='Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36' --ignore-length --keep-session-cookies --save-cookies cookies.txt --load-cookies cookies.txt 'https://jigsaw.vitalsource.com/books/HK758SH-00-DATASH-E/pages/348102883/content' -O - | gunzip | sed -re '/src/!d' -e '/.js/d' -e 's#.*src="(.*?)".*".*?".*#https://jigsaw.vitalsource.com/\1#' -e 's#800#2000#' -e 's#%20# #'

If there are some numbers missing there is a 302 status code. Run in a loop and first check with

wget --keep-session-cookies --save-cookies cookies.txt --load-cookies cookies.txt -S "https://jigsaw.vitalsource.com/books/HK758SH-00-DATASH-E/pages/348102884/content?create=true" 2&gt;&amp;1 | grep "HTTP/" | awk '{print $2}' | head -n1

if it is 200 or 302. If 200 you can get the correct image source link.

Film aus einzelne Filmsegmente runterladen und zusammenführen von Arte

  • .m3u8 Datei finden und herunterladen
  • überflüssige Informationen entfernen
    sed -i -e '/^#/d' -e '/^$/d' index_1_av.m3u8
  • parallel die Dateien herunterladen
    cat index_1_av.m3u8 | parallel --gnu "wget -c {}"
  • Dateien umbenennen, damit in der richtigen Reihenfolge zusammengefügt wird
    for i in *.ts; do extracted_number=$(sed -re 's/segment([0-9]*)_.*/\1/' <<<"$i"); mv "$i" "segment_$(printf "%04d" ${extracted_number}).ts"; done
  • zu einem Film zusammenfügen
    cat segment_* > film.ts

Adblock for Jolla (SailfishOS)

Since there is no adblock for Jolla in their shop and I was pissed in some apps about too annoying ads I thought about doing an adblock app for Jolla. Long story short, I couldn’t figure out how to do an adblock app but how I could do a systemwide adblock solution via a proxy (privoxy). The bad thing is that you have to manually install that rpm and it just can be stopped via root shell (systemctl stop privoxy). On the other hand I tried to make it as independent as possible for need of user action. It searches for new adlbock lists if your Jolla is connected to WLAN and otherwise it just hangs in there and waits for it. There is no more to do than installing and sometimes being in a WLAN to get adblock lists updated.

If you want to try, go ahead: privoxy-3.0.23-1.noarch
sha256: 23ed9c50e9c88531318ed12bee68da033def73f41749e55eeceba9853c22b85c

Here the scripts for building: https://github.com/hamsterbacke/SailBlock

PowerShell Outlook Scripting

This small PowerShell example opens my Outlook and searches for a inbox folder called „Planungen“.
It’s going through all mail and processes them if they have special keywords in them like Planung and KAR. If there are keywords like NB or Nachberechnung it’s not processed. Then it saves the attachment to a temporary Directory and uses pscp to copy it over to a linux machine. It uses my Windows kerberos key to authenticate via GSSAPI so I don’t need a RSA Key or password. It’s executed each day as a scheduled job. Neat, isn’t it?

$filepath = "C:\temp\"
$date = get-date -format d
$time = get-date -format h-mm
$log = "C:\Temp\Logs\parameterpflege_" + $date + "_" + $time + ".log"

$olFolderInbox = 6 
$outlook = new-object -com outlook.application; 
$ns = $outlook.GetNameSpace("MAPI");
$inbox = $ns.GetDefaultFolder($olFolderInbox)
$planungsordner=$inbox.Folders | where-object { $_.name -eq "Planungen" }
$messages = $planungsordner.items 

foreach($message in $messages){
  If ($message.subject -match ".*Planung.*" -And $message.subject -match ".*KAR.*" -And $message.UnRead -eq "$true" -And (!($message.subject -match ".*NB.*" -Or $message.subject -match ".*Nachberechnung.*"))) {
    Start-Transcript -Force -Path $log
    write-host "bearbeite Mail ""$subject"""
    # save attachment
    $message.attachments|foreach {
      $attachmentname = $_.filename
      If ($attachmentname.Contains("doc")) {
        Write-Host "save $attachmentname to $filepath"
        $_.saveasfile((Join-Path $filepath $attachmentname)) 
    # mark as read so it's not gonna processed again
    $message.UnRead = $false
    $docfile = "$filepath" + $attachmentname
    Write-Host "kopiere $docfile nach $linux_user@$linux_path"
    &$pscp_path $docfile $linux_user@$linux_path

convert Powerpoint to JPG or PNG or whatever

I had to find an easy solution for my colleaugue to convert Powerpoint files to e.g. JPGs.
They have a big screen where they want to do slideshows and the people do Powerpoint files for easy changes.
Instead of doing all manually with save as and such it should be an automatic conversion.

Here is the batch convertPowerpoint2JPG.bat I came up with:

@echo off
SET imagemagickpath=%~dp0
set filepath=%~dp1
set extension=%~x1
set filename=%~n1
echo convert Powerpoint to PDF
if exist "%filepath%%filename%.pdf" del "%filepath%%filename%.pdf"
CSCRIPT "%imagemagickpath%ppt2pdf.vbs" "%filepath%%filename%%extension%" "%filepath%%filename%.pdf"
if not exist "%filepath%%filename%" mkdir "%filepath%%filename%"
echo convert PDF to JPGs
"%imagemagickpath%convert.exe" -monitor -quality 100 -unsharp 0x1 -density 400 "%filepath%%filename%.pdf" -resize 60%% "%filepath%%filename%\%filename%.jpg"
exit /b

It uses a vbs Skript to invoke Powerpoint for pdf saving and then converts the PDF with ImageMagick (actually the embedded portable GhostScript) to JPG.

The code for ppt2pdf.vbs is:

Option Explicit

Sub WriteLine ( strLine )
    WScript.Stdout.WriteLine strLine
End Sub

' http://msdn.microsoft.com/en-us/library/office/aa432714(v=office.12).aspx
Const msoFalse = 0   ' False.
Const msoTrue = -1   ' True.

' http://msdn.microsoft.com/en-us/library/office/bb265636(v=office.12).aspx
Const ppFixedFormatIntentScreen = 1 ' Intent is to view exported file on screen.
Const ppFixedFormatIntentPrint = 2  ' Intent is to print exported file.

' http://msdn.microsoft.com/en-us/library/office/ff746754.aspx
Const ppFixedFormatTypeXPS = 1  ' XPS format
Const ppFixedFormatTypePDF = 2  ' PDF format

' http://msdn.microsoft.com/en-us/library/office/ff744564.aspx
Const ppPrintHandoutVerticalFirst = 1   ' Slides are ordered vertically, with the first slide in the upper-left corner and the second slide below it.
Const ppPrintHandoutHorizontalFirst = 2 ' Slides are ordered horizontally, with the first slide in the upper-left corner and the second slide to the right of it.

' http://msdn.microsoft.com/en-us/library/office/ff744185.aspx
Const ppPrintOutputSlides = 1               ' Slides
Const ppPrintOutputTwoSlideHandouts = 2     ' Two Slide Handouts
Const ppPrintOutputThreeSlideHandouts = 3   ' Three Slide Handouts
Const ppPrintOutputSixSlideHandouts = 4     ' Six Slide Handouts
Const ppPrintOutputNotesPages = 5           ' Notes Pages
Const ppPrintOutputOutline = 6              ' Outline
Const ppPrintOutputBuildSlides = 7          ' Build Slides
Const ppPrintOutputFourSlideHandouts = 8    ' Four Slide Handouts
Const ppPrintOutputNineSlideHandouts = 9    ' Nine Slide Handouts
Const ppPrintOutputOneSlideHandouts = 10    ' Single Slide Handouts

' http://msdn.microsoft.com/en-us/library/office/ff745585.aspx
Const ppPrintAll = 1            ' Print all slides in the presentation.
Const ppPrintSelection = 2      ' Print a selection of slides.
Const ppPrintCurrent = 3        ' Print the current slide from the presentation.
Const ppPrintSlideRange = 4     ' Print a range of slides.
Const ppPrintNamedSlideShow = 5 ' Print a named slideshow.

' http://msdn.microsoft.com/en-us/library/office/ff744228.aspx
Const ppShowAll = 1             ' Show all.
Const ppShowNamedSlideShow = 3  ' Show named slideshow.
Const ppShowSlideRange = 2      ' Show slide range.

' This is the actual script

Dim inputFile
Dim outputFile
Dim objPPT
Dim objPresentation
Dim objPrintOptions
Dim objFso

If WScript.Arguments.Count <> 2 Then
    WriteLine "You need to specify input and output files."
End If

inputFile = WScript.Arguments(0)
outputFile = WScript.Arguments(1)

Set objFso = CreateObject("Scripting.FileSystemObject")

If Not objFso.FileExists( inputFile ) Then
    WriteLine "Unable to find your input file " & inputFile
End If

If objFso.FileExists( outputFile ) Then
    WriteLine "Your output file (" & outputFile & ") already exists!"
End If

WriteLine "Input File:  " & inputFile
WriteLine "Output File: " & outputFile

Set objPPT = CreateObject( "PowerPoint.Application" )

objPPT.Visible = True
objPPT.Presentations.Open inputFile

Set objPresentation = objPPT.ActivePresentation
Set objPrintOptions = objPresentation.PrintOptions

objPrintOptions.Ranges.Add 1,objPresentation.Slides.Count
objPrintOptions.RangeType = ppShowAll

' Reference for this at http://msdn.microsoft.com/en-us/library/office/ff746080.aspx
objPresentation.ExportAsFixedFormat outputFile, ppFixedFormatTypePDF, ppFixedFormatIntentScreen, msoTrue, ppPrintHandoutHorizontalFirst, ppPrintOutputSlides, msoFalse, objPrintOptions.Ranges(1), ppPrintAll, "Slideshow Name", False, False, False, False, False


Sorry, I forgot the source. If you know it, let me know.

I used a portable version of ImageMagick and a portable version of GhostScript. You have to integrate GhostScript into ImageMagick in the file delegates.xml. Place GhostScript in ImageMagick folder and replace all appearances of gswin32c.exe with Ghostscript\bin\gswin32c.exe (if that is the path of your portable GhostScript).

Now just drag a ppt(x) file onto convertPowerpoint2JPG.bat and it creates a folder in the same directory where your ppt(x) resides and puts numbered JPGs in that folder.

You can download my example for trying it out yourself (Windows x64 version).