Switching Sound Output between Headset and Speakers

How do you change the sound device a particular application is using for its audio output? I never bothered to think about this question, until the times of the shared home office.

True, in Windows you can change the default sound device, and an application that is started afterwards will use that device. But changing the sound device for a running application? It seems there is no built-in way to do that.

For Windows 7 and higher, I found the SoundSwitch applet (GitHub), which does just that. Located in the notification area, it lets you select the sound device the current application outputs its audio to. Simply click on its icon and select the device, or press a customizable hotkey.

For Ubuntu, I found Sound Switcher Indicator (GitHub, Blog). Upon installation, it can be accessed from the indicator area, and allows the selection of audio input and output devices.

Problems solved 😉

Epilogue

During preparation of this post, I tried to figure out how SoundSwitch actually switches the audio device.

It turns out that it uses the function call SetPersistedDefaultAudioEndpoint() which is also used by an application called EarTrumpet (GitHub) that tags itself as “Volume control for Windows”, but also seems to allow switching audio devices.

A review of this application by Scott Hanselman indicates that the method and its interface are not officially documented:

Internal Audio Interface: IAudioPolicyConfigFactory

Gets them access to new APIs (GetPersistedDefaultAudioEndpoint / SetPersistedDefaultAudioEndpoint) in RS4 that let’s them ‘redirect’ apps to different playback devices. Same API used in modern sound settings.

Code here with no public API yet?

Renaming files after their time stamp in Ubuntu

Downloading data files from certain web sites, the data files usually either are already named after their creation timestamp, or they end with subsequent numbering (1), (2), … in their names.

To rename such numbered files, I found that the date -r command displays a file’s modification timestamp, which can be formated with the +format option:

date -r somefilename.txt +%Y%m%d

To iterate over all downloaded files, I use

for f in file*name*pattern* do

Putting it all together, I came up with the one-liner

for f in pattern*; do mv $f `date -r $f +filename_%Y%m%d`.csv; done

Fixing the –startvm Error Message

After upgrading Ubuntu from 18.04 to 20.04, I noticed that my VM .desktop shortcut throws the error message

–startvm is an option for the VirtualBox VM runner (VirtualBoxVM) application, not the VirtualBox Manager.

Before the upgrade, it simply started the virtual machine referenced as parameter value.

It seems that VirtualBox moved the --startvm parameter from the previous VirtualBox executable to VirtualBoxVM. More infos and links can be found in this VirtualBox ticket.

The (easy) solution was to open the .desktop file in an editor, and change the line

Exec=/usr/lib/virtualbox/VirtualBox ....

to

Exec=/usr/lib/virtualbox/VirtualBoxVM ....

AutoMySQLBackup Warning

When I replaced my original Ubuntu server with the (then) more current Ubuntu 18.04, I also moved MySQL databases and wanted to have them backed up regularly.

I had used the script AutoMySQLBackup which did the job fine, and installed it on the new machine. (When I first found the script, I adapted for PowerShell on Windows it to backup my SQL Server databases)

On the new machine, however, the tool mysqldump issued the warning

[Warning] Using a password on the command line interface can be insecure.

The change seems to have been introduced in MySQL 5.6, and the solution to the warning is documented in the MySQL 5.6 Reference Manual. There are also answers on SO regarding the warning

mysql_config_editor set --login-path=local --host=localhost --user=username --password

mysql --login-path=local -e "statement"

 

I guess I tried to change the .sh script to call mysqldump with –login-path instead of –user/–password.

As the original script is not maintained anymore, I found this fork of AutoMySQLBackup which is still active, and also documents the use of –login-path.

Opening .url Files in Ubuntu

When browsing the web with Chrome for Android, I save the URLs on my Nextcloud server by sharing using the Nextcloud App. Each URL is then stored as a .url file looking like this

[InternetShortcut]
URL=https://devio.wordpress.com/

Today I noticed that those .url files cannot be opened on Ubuntu, i.e. a double-click won’t start a browser with the contained URL.

Instead, I get a an error dialog

Could not display “<HTML page title>.url”.

There is no application installed for “Internet shortcut” files.
Do you want to search for an application to open this file?

No     Yes

Screenshot from 2020-03-22 07-40-58.png

Clicking the Yes button, a toast message appears

mimetype required.png

which you have to click before it disappears, which finally opens the software installer:

unable to find software.png

Not good.

Surprisingly, Firefox does not register itself as an application to handle the .url file extension on Ubuntu. It also does not know that the Windows Firefox would know how to open the file.

More surprisingly, Ubuntu knows that .url files are “Internet shortcut” files, and have the associated MIME type application/x-mswinurl.

So I had to solve two problems:

  • Retrieve the URL stored in a .url file
  • Start Firefox using this URL using Ubuntu’s MIME type handling

Retrieving the URL stored in a .url file

As shown above, a .url file is simply a text file in .ini format. In it’s simplest form, it contains a section [InternetShortcut] with a single Key “URL=”. The key’s value is the URL to navigate to.

With a little help from askubuntu, I figured out the command to extract the URL value

grep -Po 'URL=\K[^ ]+' *.url

Using the result of the grep operation as argument for firefox would look something like this:

firefox `grep -Po 'URL=\K[^ ]+' "$1"`

After a bit of digging, I found how you can manually add MIME type handlers in Ubuntu. Following those instructions, I created a file

/usr/share/applications/mswinurl.desktop

(you need sudo in this directory) with the following content (spoiler: don’t copy this yet!):

[Desktop Entry]
Name=Firefox Shortcut
GenericName=Firefox Shortcut

Type=Application
Exec=firefox `grep -Po 'URL=\K[^ ]+' %U`
TryExec=firefox
MimeType=application/x-mswinurl;
Icon=firefox

However, this did not work as intended, as I got an error message complaining about the backtick `. So, if I cannot have shell operations in the .desktop file, let’s create a batch file

/usr/local/bin/runurl

and place the shell magic there:

firefox `grep -Po 'URL=\K[^ ]+' "$1"` &

Don’t forget to make the batch file executable using

sudo chmod 755 runurl

and reference the runurl script rather than Firefox in /usr/share/applications/mswinurl.desktop:

[Desktop Entry]
Name=Firefox Shortcut
GenericName=Firefox Shortcut

Type=Application
Exec=runurl %U
TryExec=firefox
MimeType=application/x-mswinurl;
Icon=firefox

After creating the file, run

 sudo update-desktop-database

to register the new .desktop file.

Double-clicking a .url file now opens the URL in a new Firefox tab.

Anki crashes on Ubuntu

As I browsed through Ubuntu Software, I wanted to install Anki (build number 2.1.0+dfsg~b36-1) on my Ubuntu 18.04 machine.

Launching the application did not open a new window, but rather opened a Crash Report window after some time.

Fortunately, the solution to the problem was just a couple of comments down the application page:

sudo apt-get install python3-distutils

Running this command from terminal lets you start the application.

I had a look at the Ubuntu package definition, and indeed this dependency is missing there. Less encouraging is the fact that this very issue has been reported one and a half years ago.

Moving and Upgrading Bugzilla

I had to migrate and upgrade a Bugzilla installation to a newer machine with Ubuntu LTS installed. Fortunately, Bugzilla has documented the steps in Moving Bugzilla Between Machines, but unfortunately the documentation does not seem to be uptodate.

First I had to make sure the latest update to the LTS was installed:

sudo apt update
sudo apt upgrade
sudo apt dist-upgrade

This resulted in

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.4 LTS
Release: 16.04
Codename: xenial

Next, I following the Quick Start installation guide

$ sudo apt-get install git
[sudo] password for herbert:
Reading package lists... Done
Building dependency tree
Reading state information... Done
git is already the newest version (1:2.7.4-0ubuntu1.3).

The next recommended step brought up the error message

Package apache2-mpm-prefork is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package ‘apache2-mpm-prefork’ has no installation candidate

and I had to remove the package apache2-mpm-prefork from the command

sudo apt-get install apache2 mysql-server libappconfig-perl libdate-calc-perl libtemplate-perl libmime-perl build-essential libdatetime-timezone-perl libdatetime-perl libemail-sender-perl libemail-mime-perl libemail-mime-modifier-perl libdbi-perl libdbd-mysql-perl libcgi-pm-perl libmath-random-isaac-perl libmath-random-isaac-xs-perl libapache2-mod-perl2 libapache2-mod-perl2-dev libchart-perl libxml-perl libxml-twig-perl perlmagick libgd-graph-perl libtemplate-plugin-gd-perl libsoap-lite-perl libhtml-scrubber-perl libjson-rpc-perl libdaemon-generic-perl libtheschwartz-perl libtest-taint-perl libauthen-radius-perl libfile-slurp-perl libencode-detect-perl libmodule-build-perl libnet-ldap-perl libauthen-sasl-perl libtemplate-perl-doc libfile-mimeinfo-perl libhtml-formattext-withlinks-perl libfile-which-perl libgd-dev libmysqlclient-dev lynx-cur graphviz python-sphinx rst2pdf

I cloned Bugzilla into /var/www using git

/var/www$ sudo git clone --branch release-5.0-stable https://github.com/bugzilla/bugzilla bugzilla

and edited the MySql config files as recommended

/etc/mysql/mysql.conf.d$ sudo nano mysqld.cnf

max_allowed_packet = 100M
ft_min_word_len = 2

Create a bugs user account and run mysql "GRANT ALL PRIVILEGES ...." to create the bugs database

Next, I created a backup of the original Bugzilla database, and proceded according to the Moving… documentation.

/var/www/bugzilla$ sudo ./checksetup.pl

Check setup brought up warnings about missing Perl modules.

/var/www/bugzilla$ sudo /usr/bin/perl install-module.pl --all
ERROR: Using install-module.pl requires that you install "make".

Solve this error by installing make:

$ sudo apt-get install make

The next run of Check Setup raised another error message:

/var/www/bugzilla$ sudo ./checksetup.pl

DBD::mysql::db do failed: Cannot change column 'setter_id': used in a foreign key constraint 'fk_flags_setter_id_profiles_userid' [for Statement "ALTER TABLE flags CHANGE COLUMN
setter_id setter_id mediumint NOT NULL"] at Bugzilla/DB.pm line 742.
Bugzilla::DB::bz_alter_column_raw(Bugzilla::DB::Mysql=HASH(0xc89c6dc), "flags", "setter_id", HASH(0xca65fc0), HASH(0xe69a248), undef) called at Bugzilla/DB.pm line 701
Bugzilla::DB::bz_alter_column(Bugzilla::DB::Mysql=HASH(0xc89c6dc), "flags", "setter_id", HASH(0xca65fc0)) called at Bugzilla/Install/DB.pm line 626
Bugzilla::Install::DB::update_table_definitions(HASH(0x97e6884)) called at ./checksetup.pl line 172

I found a couple of forums regarding this error (Mozilla Support, SO), and the problems seems to be caused by newer MySql versions refusing to change or delete a column which is referenced by a foreign key constraint.
I removed the constraint directly from the mysql prompt:

use bugs;
alter table `flags` drop foreign key `fk_flags_setter_id_profiles_userid` ;

After this, the Check Setup script completed without errors.

 

Recovering a Corrupted Mailman Installation

One day a Mailman installation that I maintain became corrupted.

Instead of presenting the typical web interface, it only showed the directory listing or returned 404’s, just as if the Python handler could not be found to process the requests.

Anxious to lose the configuration and content of several mail lists, I followed two tutorials to backup the Mailman data:

After completing the backups, I gave it a try and re-installed Mailman. However, the first uninstall statement

apt-get remove mailman

stopped with a message that some directories still contained data, so I had to manually delete the “bounces” directory under /var/lib/mailman/qfiles.

Finally, the statements

apt-get remove mailman
apt-get install mailman

were executed successfully, and Mailman was up and running again (without restoring any of the backups).

Recovering Ubuntu 8.04 LTS from Failed Harddisk

You may have noticed that the web server hosting my homepage and download site has been down since the weekend. I noticed problems when the sites responded to request with MySQL errors.

Running fsck returned the message “Bad magic number in super-block” which means that e2fsck cannot completely repair the disk. It turned out that the partition table had been destroyed, but mke2fs -n still found some superblocks.

Started up the PC with a Knoppix Live CD to repair the broken disk.

In couple of forums I found the utility TestDisk which re-creates lost partitions, and it both recovered the boot and the swap partition. However, e2fsck still failed with the messages:

Attempt to read block from filesystem resulted in short read
Attempt to read block from filesystem resulted in short read
reading journal superblock
Attempt to read block from filesystem resulted in short read
while checking ext3 journal

It was now clear that the harddisk could not be repaired, so I got a new one and copied the original harddisk with a program called Ddrescue.

Ddrescue is a great tool (documentation), as it copies one device onto another, displaying the number of read errors and the size of the erroneous blocks. The amazing thing (if you don’t know how it works) is that the error size *reduces* after the first full scan of the source disk. The initial 2.5GB of unreadable disk finally reduced to about 15MB.

After ddrescue was finished, I ran another fsck on the new disk, this time successfully. Time to reboot.

Reboot brought a black screen, with “1234F” the only thing displayed. It turned out that that was the remainder of the TestDisk MBR which could not find a bootable partition. Need to get GRUB back.

The Knoppix disk would not help me now (disks are named /dev/hda instead of /dev/sda), but fortunately I had a Ubuntu 8.10 Desktop disk already which also offers a Live functionality.

Booted Ubuntu CD, and restored GRUB as sketched in this forum thread:

sudo grub
find /boot/grub/stage1
root (hd0,0)
setup (hd0)

Now at least GRUB was booting, but it also served me the next error message:

Kernel panic: VFS: Unable to mount root fs on unknown-block(0,0)

If tried to understand GRUB and the disk UUIDs mentioned in menu.lst, when I guessed that the problem was caused by a broken initrd.img.

I backed up the original initrd.img-2.6.24-16-server and copied the initrd.img-2.6.24-16-server.bak to the original name. And it worked!

As far as I can tell, the machine is back online and fully functioning again. But it was quite a trip 😉

Extending default validity for self-generated SSL certificates

When I installed GForge recently, I had to generate an SSL certificate as part of the installation since GForge runs on https. However, the make-ssl-cert tool does not provide a way to customize the validity of the generated certificate, which is 30 days by default.

As it turns out, this problem is known for 3 years, and it is still not fixed in Ubuntu 8.04.

The easiest workaround is to edit the make-ssl-cert script using

whereis make-ssl-cert
sudo nano [path-to/]make-ssl-cert

and replace the line

openssl req -config $TMPFILE -new -x509 -nodes -out $output
    -keyout $output

with

openssl req -config $TMPFILE -new -x509 -days 365 -nodes 
    -out $output -keyout $output

That’s it.