CSS selectors support in today and tomorrow browsers

March 27, 2008
Filled under: , ,

I've just discovered this css selectors testsuite, and had every browser I had access to try to pass it.

Here are the results. Green means the browser fully supports the selector, while red means its support is missing, or buggy at best.

Note that, since it's an automated test, some user interaction related selectors are missing (namely :hover, :focus, and :activate).

CSS selectors support in browsers
IE7IE8b1Firefox 2.0Firefox 3b4Safari 3.1Opera 9.26Opera 9.50b1
*
E
.class
#id
E F
E > F
E + F
E[attribute]
E[attribute=value]
E[attribute~=value]
E[attribute|=value]
:first-child
:link
:visited
:lang()
:before
::before
:after
::after
:first-letter
::first-letter
:first-line
::first-line
E[attribute^=value]
E[attribute$=value]
E[attribute*=value]
E ~ F
:root
:last-child
:only-child
:nth-child()
:nth-last-child()
:first-of-type
:last-of-type
:only-of-type
:nth-of-type()
:nth-last-of-type()
:empty
:not()
:target
:enabled
:disabled
:checked

Asynchronously fetching images from Internet in Android

March 19, 2008
Filled under: , , ,

Here is a small class I wrote for Android, for loading pictures from the network in the background.

Not much, but quite handy.

import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class AsyncImageLoader extends Thread {
    interface AsyncImageCallback {
        /** @brief Called by an AsyncImageLoader upon request completion.
          * @param url Same URL as the one passed to the AsyncImageLoader constructor.
          * @param bm A Bitmap object, or null on failure.
          */
        void onImageReceived(String url, Bitmap bm);
    }
    /** @brief Start an asynchronous image fetch operation.
      * @param url The URL of the remote picture.
      * @param cb The AsyncImageCallback object you want to be notified the operation completes.
      */
    public AsyncImageLoader(String url, AsyncImageCallback cb) {
        super();
        mURL=url;
        mCallback=cb;
        start();
    }
    public void run() {
        try {
            HttpURLConnection conn = (HttpURLConnection)(new URL(mURL)).openConnection();
            conn.setDoInput(true);
            conn.connect();
            mCallback.onImageReceived(mURL,BitmapFactory.decodeStream(conn.getInputStream()));
        } catch (IOException e) {
            mCallback.onImageReceived(mURL,null);
        }
    }
    private String mURL;
    private AsyncImageCallback mCallback;
}

Sample usage:

public class MyClass implements AsyncImageLoader.AsyncImageCallback {
    void onImageReceived(String url, Bitmap bm) {
        if (bm==null) {
            System.err.println("Could not load picture '"+url+"'!");
        }
        else if ("http://somewhere.net/foo.png".equals(url)) {
            paintFoo(bm);
        }
    }
    void someFunction() {
        new AsyncImageLoader("http://somewhere.net/foo.png", this);
    }
}

Using a sqlite backend for syslogd

March 09, 2008
Filled under: , , , ,

I wanted to make my server's system logs a bit more structured, in order to mine their data from python scripts, so I switched to a SQL backend.

Now I have a single /var/log/system.db with log rotation support, and can do complex SQL queries on it such as:

sqlite> select distinct(program) from logs;
cron
lighttpd
syslog-ng
sqlite> select msg from logs where program='lighttpd' and date=date('now','localtime') and time>time('now','-1 minutes','localtime');
lighttpd[8369]: 216.240.132.119 - - [09/Mar/2008:18:09:29 +0100] \"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1\" 400 349 \"-\" \"-\"

So, how did I make it work? Here is my syslog-ng.conf:

options { chain_hostnames(off); sync(0); stats(43200); };
source src { unix-stream("/dev/log"); internal(); };
source kernsrc { file("/proc/kmsg"); };
destination system_db {
        program("/usr/bin/sqlite3 /var/log/system.db"
        template("INSERT INTO logs VALUES(NULL,'$HOST','$FACILITY','$PRIORITY','$LEVEL','$TAG','$YEAR-$MONTH-$DAY','$HOUR:$MIN:$SEC','$PROGRAM','$MSG');\n")
        template-escape(yes)
        );
};
destination console_all { file("/dev/tty12"); };
log { source(src); destination(console_all); };
log { source(src); destination(system_db); };

I also had to tell lighttpd to use syslog instead of log files, by modifying lighttpd.conf (don't forget to add "mod_accesslog" to the server.modules list!):

server.errorlog-use-syslog = "enable"
accesslog.use-syslog       = "enable"
# you can safely delete the following declarations:
# server.errorlog=
# accesslog.filename=

Then, I created the database file:

sqlite3 -list /var/log/system.db "CREATE TABLE logs (id integer primary key,\
host text default NULL,facility varchar(10) default NULL,\
priority varchar(10) default NULL,level varchar(10) default NULL,\
tag varchar(10) default NULL,date date default CURRENT_DATE,\
time time default CURRENT_TIME,program varchar(15) default NULL,\
msg text);"

..and reloaded both lighttpd and syslog-ng (here for Gentoo Linux):

/etc/init.d/syslog-ng reload
/etc/init.d/lighttpd reload

This is it. Additionally, here is the script called once in a while by cron for rotating logs:

#!/bin/bash

SQLITE=$(which sqlite3)
SYSTEMLOG="/var/log/system.db"
TMPLOG="/var/log/tmp.db"
BACKUP="/var/log/$(date +"%Y%m%d-%H%M%S.sql")"

rm -f "$TMPLOG" >/dev/null 2>&1

"$SQLITE" -list "$TMPLOG" "CREATE TABLE logs (id integer primary key,\
host text default NULL,facility varchar(10) default NULL,\
priority varchar(10) default NULL,level varchar(10) default NULL,\
tag varchar(10) default NULL,date date default CURRENT_DATE,\
time time default CURRENT_TIME,program varchar(15) default NULL,\
msg text);" && chmod 600 "$TMPLOG" && (
        "$SQLITE" -list "$SYSTEMLOG" ".dump" | bzip2 >"${BACKUP}.bz2"
) && mv "$TMPLOG" "$SYSTEMLOG"

# The following is Gentoo Linux specific, you must replace it
# by what is provided in your distro for reloading syslog-ng
/etc/init.d/syslog-ng reload

EDIT:Don't forget to clean things a bit after you're done. First, we can remove lighttpd-specific options passed to logrotate. Do not just delete this file, since a lighttpd update will likely recreate it:

if [ -f /etc/logrotate.d/lighttpd ]; then
echo > /etc/logrotate.d/lighttpd
fi

You may want to uninstall logrotate, but keep in mind that some binary logs are not handled by syslogd (lastlog and wtmp are the most common ones) so logrotate might still be of some use.

After a while, and if you did not feel confident enough to delete them when you switched to your new SQL syslog backend, logrotate will rotate all the now-unused logs. If you find empty files in /var/log, then it means you can safely delete them!

EDIT:I added a chmod 600 in the sql rotation cronjob above since -rw------- was the default access mode for my box's logs.

TrueVision3D SDK 6.5 project wizard for Visual C# 2005

February 29, 2008
Filled under: , , ,

If you're using the wonderful TrueVision3D 3D programming framework with Visual C# 2005 (express or not), you can try the beta of TrueVision3D SDK 6.5 Project Wizard.

It speeds up things when starting a new TV3D project as you won't have to copy the files provided by the SDK (under the templates/csharp folder) and to rename the files/namespaces/classes/... anymore.

Any feedback, positive or not, is appreciated (so that I can post it to the wiki if it works well).

ps:The full source for InnoSetup is available under the source/ folder.

EDIT: Version 1.1 out, with many fixes/improvements. Now always at http://www.julien-cayzac.com/code/tv3d/wizard/latest/.

Wifi Intermediate Driver DLL for Windows Mobile

February 20, 2008

For what it's worth, I have packaged a small "Wifi Intermediate Driver" into a DLL for Windows Mobile 5 (both PocketPC and Smartphone are supported) and 6 (Standard and Professional editions are both supported).

The library allows you to scan for nearby Wifi access points using the provided WifiOpen(), WifiClose() and WifiEnumerate() easy-to-use functions instead of zillions of fastidious and bug-prone DeviceIOControl() calls on a network adapter driver.

It was modeled after the GPS intermediate driver provided by Microsoft, and shares the same KISS approach but applies it to Wifi discovery.

The archive contains the header and source files of the DLL in unmanaged C++, as well as a small managed class in C# for using it from a .Net application.

It is not complete in anyway, as it does only what I need it to do, ie retrieving the HMAC address and the signal strength of currently available infrastructure 802.1x access points. The SSID is not retrieved but that's easy to implement once you understand the rest of the code.

Enumerating Wifi access points on Windows Mobile

February 15, 2008

The other day, I wanted to get the list of all the nearby wireless access points in C++ on a Windows Mobile 6 terminal. After a few hours spent digging on Google, I realized that was trickier that it seemed and not as easy as on other platforms.

Here is what I had to do:

  1. Enumerate all network adapters with GetAdaptersInfo(),
  2. For each adapter, consider only the ones with a MIB_IF_TYPE_ETHERNET type,
  3. Open the NDIS device (UIO1:) and issue a IOCTL_NDISUIO_NIC_STATISTICS ioctl on it, in order to get the physical medium type of the adapter, and consider anly those with a NdisPhysicalMediumWirelessLan medium,
  4. Each time I want to initiate a scan, issue OID_802_11_BSSID_LIST_SCAN and OID_802_11_BSSID_LIST_SCAN ioctls on the UIO1: device.

Here is the code, packaged into a CWifi class:

  • wifi.h header file
  • wifi.cpp source file
  • wifi.txt, with md5, sha1 and sha256 signatures for the above two files.

2008

December 31, 2007
Filled under: ,