wxWidgets 2.8 to 3.0 Migration: Converting wxString to Numbers

wxWidgets provides a set of utility methods to converts wxString to various integer types such as ToLong(). While the documentation for those functions remained roughly the same between wxWidgets 2.8 and 3.0 the implementation did change. In wxWidgets 2.8, if the string was empty, using any of the number converstion functions would result in the value 0. But, in wxWidgets 3.0 it’s different as can be learned from the following comment in wxstring.cpp:

// notice that we return false without modifying the output parameter at all if
// nothing could be parsed but we do modify it and return false then if we did
// parse something successfully but not the entire string

This means that if you relied on ToLong() to store 0 to the pointer to long when given empty string, in wxWidgets 3.0 you will get uninitialized value there.

I also noticed when comparing the code of wxString in 2.8 and 3.0, that they implemented the integer conversion functions using C macros, while in 2.8 they used templates. I wonder why it was changed, as it looks more like a regression to me.

C++ : mt19937 Example

C++11 introduces several pseudo-random number generators designed to replace the good-old rand from the C standard library. I’ll show basic usage examples of std::mt19937, which provides a random number generation based on Mersenne Twister algorithm. Using the Mersenne Twister implementation that comes with C++1 has advantage over rand(), among them:

  1. mt19937 has much longer period than that of rand, e.g. it will take its random sequence much longer to repeat itself.
  2. It much better statistical behavior.
  3. Several different random number generator engines can be initiated simultaneously with different seed, compared with the single “global” seed srand() provides.

The downside is that mt19937 is a bit less straight-forward to use. However, I hope this post will help with this point :-).
Continue reading C++ : mt19937 Example

Make Offline Mirror of a Site using `wget`

Sometimes you want to create an offline copy of a site that you can take and view even without internet access. Using wget you can make such copy easily:

wget --mirror --convert-links --adjust-extension --page-requisites 
--no-parent http://example.org

Explanation of the various flags:

  • --mirror – Makes (among other things) the download recursive.
  • --convert-links – convert all the links (also to stuff like CSS stylesheets) to relative, so it will be suitable for offline viewing.
  • --adjust-extension – Adds suitable extensions to filenames (html or css) depending on their content-type.
  • --page-requisites – Download things like CSS style-sheets and images required to properly display the page offline.
  • --no-parent – When recursing do not ascend to the parent directory. It useful for restricting the download to only a portion of the site.

Alternatively, the command above may be shortened:

wget -mkEpnp http://example.org

Note: that the last p is part of np (--no-parent) and hence you see p twice in the flags.

Bootstrap: Combining input-append and input-block-level

If you have a button appended to an input control in Bootstrap, and you want it fill the entire width, it’s not sufficient to add the input-block-level to the input itself but this CSS class also needs to be added to the surrounding .input-append div. For example:

<div class="input-append input-block-level">
	<input type="text" class="search-query input-block-level" name="q" placeholder="Search">
	<button type="submit" class="btn btn-primary">Search</button>
</div>

Applying .input-block-level to only one of the elments (either the div or the input) just doesn’t work.

Restricting SSH Access to rsync

Passphrase-less SSH keys allows one to automate remote tasks by not requiring user intervention to enter a passphrase to decrypt the key. While this is convenient, is posses a security risk as the plain key can be used by anyone who gets hold of it to access the remote server. To this end, the developers of SSH allowed to restrict via the .ssh/authorized_keys the commands that can be executed of specific keys. This works great for simple commands, but as using rsync requires executing remote commands withe different arguments on the remote end, depending on the invocation on the local machine, it gets quite complicated to properly restrict it via .ssh/authorized_keys.

Luckily, the developers of rsync foresaw this problem and wrote a script called rrsync (for restricted rsync) specifically to ease the restricting keys to be used only for rsync via .ssh/authorized_keys. If you have rsync installed, rrsync should have been distributed along side it. In Debian/Ubuntu machines it can be found under /usr/share/doc/rsync/scripts/rrsync.gz. If you can find it there, you can download the script directly from here. On the remote machine, copy the script, unpacking if needed, and make it executable:

user@remote:~$ gunzip /usr/share/doc/rsync/scripts/rrsync.gz -c > ~/bin/rrsync
user@remote:~$ chmod +x ~/bin/rrsync

On the local machine, create a new SSH key and leave the passphrase empty (this will allow you to automate the rsync via cron). Copy the public key to the remote server.

user@local:~$ ssh-keygen -f ~/.ssh/id_remote_backup -C "Automated remote backup"
user@local:~$ scp ~/.ssh/id_remote_backup.pub user@remote:~/

Once the public key is on the remote server edit ~/.ssh/authorized_keys and append the public key.

user@remote:~$ vim ~/.ssh/authorized_keys

(Vim tip: Use :r! cat id_remote_backup.pub to directly insert the contents of id_remote_backup.pub into a new line). Now prepend to the newly added line

command="$HOME/bin/rrsync -ro ~/backups/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding

The command="..." restricts access of that public key by executing the given command and disallowing others. All the other no-* stuff further restrict what can be done with that particular public key. As the SSH daemon will not start the default shell when accessing the server using this public key, the $PATH environment variable will be pretty empty (similar to cron), hence you should specify the full path to the rrsync script. The two arguments to rrsync are -ro which restricts modifying the directory (drop it if you want to upload stuff to the remote directory) and the path to the directory you want to enable remote access to (in my example ~/backups/).

The result should look something like:

command="$HOME/bin/rrsync -ro ~/backups/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAA...vp Automated remote backup

After saving the file, you should be able to rsync files from the remote server to the local machine, without being prompted to for a password.

user@local:~$ rsync -e "ssh -i $HOME/.ssh/id_remote_backup" -av user@remote: etc2/

To things are needed to be noted:

  1. You need to specify the passphrase-less key in the rsync command (the -e "ssh -i $HOME/.ssh/id_remote_backup" part).
  2. The remote directory is always relative to the directory given to rrsync in the ~/.ssh/authorized_keys file.

Enabling C++11 (C++0x) in CMake

Going over some CMakeLists.txt files I’ve written, I came across the following snippet:

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

Various compiler versions of gcc and clang use different flags to specify C++11 support, namely older ones accept -std=c++0x and newer one -std=c++11. The above snippets detects which is the right one for the compiler being used and adds the flag to the CXX_FLAGS.

View man Pages Properly in gVim

Vim’s ability to display man pages easily using the K mapping often comes handy. It been bothering me for a while, that the same thing doesn’t work properly in gVim, which I use more. The reason is that Vim’s ability to display man pages depends on having a terminal emulator, which just isn’t true for gVim, hence the garbled display of man pages one sees if he tries viewing a man page in gVim.

Today, I found a way around this limitation. It turns out, Vim comes with support for displaying man pages in a split window, and does it perfectly – colors, links and all the necessary stuff. The first line, enables this feature which includes by default the K mapping to open the man page in a new split. The second part, which I find very convenient, makes the regular K do the same in gVim. And unlike the original mapping, it also accepts a count before, so pressing 3K will search the 3 man section of the keyword under the cursor.

" Properly display man pages
" ==========================
runtime ftplugin/man.vim
if has("gui_running")
	nnoremap K :<C-U>exe "Man" v:count "<C-R><C-W>"<CR>
endif

Creating Self-Signed ECDSA SSL Certificate using OpenSSL

Before generating a private key, you’ll need to decide which elliptic curve to use. To list the supported curves run:

openssl ecparam -list_curves

The list is quite long and unless you know what you’re doing you’ll be better off choosing one of the sect* or secp*. For this tutorial I choose secp521r1 (a curve over 521bit prime).

Generating the certificate is done in two steps: First we create the private key, and then we create the self-signed X509 certificate:

openssl ecparam -name secp521r1 -genkey -param_enc explicit -out private-key.pem
openssl req -new -x509 -key private-key.pem -out server.pem -days 730

The newly created server.pem and private-key.pem are the certificate and the private key, respectively. The -param_enc explicit tells openssl to embed the full parameters of the curve in the key, as opposed to just its name. This allows clients that are not aware of the specific curve name to work with it, at the cost of slightly increasing the size of the key (and the certificate).

You can examine the key and the certificate using

openssl ecparam -in private-key.pem -text -noout
openssl x509 -in server.pem -text -noout

Most webservers expect the private-key to be chained to the certificate in the same file. So run:

cat private-key.pem server.pem > server-private.pem

And install server-private.pem as your certificate. If you don’t concatenate the private key to the certificate, at least Lighttpd will complain with the following error:

SSL: Private key does not match the certificate public key, reason: error:0906D06C:PEM routines:PEM_read_bio:no start line