fighting hpdeskjetphobia: printers win!

Ten years ago a printer was bought in our household. It was HP DeskJet 520, black and white mod, and did cost a fortune – over $1000. It was a good one, 300dpi, and was used for 8 years. I used to clean it’s parts with alcohol, used vacuum cleaner several times as well. It may be still there, printing and making lots of noise.

So, it’s cost scared me so much that I got hpdeskjetphobia, I always avoided buying printers. I did see various printing facilities, e.g. a printing room in a bank, where transaction logs were printed on paper by large Kyoceras. Those noisy bastards were all around but not near me. In my previous job printers were outsourced from a company, and nearest one was five or six rooms away. Those were big and looked expensive. All printers looked to me expensive.

Now I decided I need one for my home office. I just went to a nearest shop, and the first one (HP PSC 1510) looked like the one I need. It even has scanner and copying functions! All for 100Eur. I took it home, opened the box, surprise surprise, it had CD for my Mac, with OCR software and some image management tool. All for 100 Eur. I don’t know how much I’ll have to pay for ink yet, but there was some included. For same 100 Eur.

I printed several photos on A4 photopaper and those looked amazing. Sure, now I need a digital camera. There is a story, why I have none yet. See, 8 years ago I was kind of early adopter. I did lots of photo footage for my school’s homepage with a camera, that did cost $1000 and had 640×480 resolution (borrowed, not own one). But I guess I have yet another phobia to kill and find out that now digital cameras are commodity as well. Maybe some pictures will end up in Wikimedia Commons? :)

syslog in mysql function

I experimented with sending UDP messages from MySQL functions, but ended up with simple syslogging UDF

I played a bit with various interaction with outer world ideas in MySQL UDFs and ended up with something what was really really simple – a single libc call. I did shamelessly steal bare bones and simply added a single line of code in it:

#include <mysql.h>
#include <string.h>
#include <syslog.h>

my_bool logger_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
        initid->maybe_null=0;
        return 0;
}

long long logger(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
        if (args->arg_count != 1) {
                strcpy(error, "LOGGER(): needs message");
                return 1;
        }

        if (args->arg_type[0] != STRING_RESULT) {
                strcpy(error, "LOGGER() message should be string");
                return 1;
        }

        syslog(LOG_INFO,"%s",args->args[0]);
        *is_null = 0;
        *error = 0;

        return 0;
}

Of course, I had to compile it:

gcc -I /usr/include/mysql/ -shared -o syslogudf.so syslogudf.c

And later load it:

mysql> create function logger returns integer soname 'syslogudf.so';
Query OK, 0 rows affected (0.00 sec)

One more thing… testing:

mysql> select logger(concat(user()," wishes you ",
    -> if(rand()>0.3,"good","bad")," luck"));
+---------------------------------------------------------------------------+
| logger(concat(user()," wishes you ",if(rand()>0.3,"good","bad")," luck")) |
+---------------------------------------------------------------------------+
|                                                                         0 |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)

So now our systems administrator will see:

$ tail -1 /var/log/messages
Dec 12 01:09:22 flake mysqld-max: root@localhost wishes you bad luck

Oops!

ip address searches in mysql

MySQL does not provide special datatype or operators for IP addresses, but has two functions, that convert IP addresses to and from integers. In order to lookup addresses in a subnet, an efficient index range scan queries could be used.

MySQL does not provide special datatype or operators for IP addresses, but has two functions, that convert IP addresses to and from integers. In order to lookup addresses in a subnet, an efficient index range scan query could be used:

SELECT ip FROM table WHERE ip BETWEEN
	INET_NTOA("213.197.137.0") AND
	INET_NTOA("213.197.137.255")

In order to make it easier, we can have several handy functions, that simplify the task a bit:

SELECT ip FROM table WHERE ip BETWEEN
	inet_aton_net("213.197.137.3/24") AND
	inet_aton_bc("213.197.137.3/24")

I intentionally didn’t create/use function that would check IPs existence in network, as optimizer wouldn’t know it can be converted to efficient range scan, though, some operators like… LIKE are optimized properly.

CREATE FUNCTION inet_aton_net (ip VARCHAR(18))
	RETURNS INTEGER UNSIGNED
	DETERMINISTIC
BEGIN
	DECLARE nm INTEGER UNSIGNED DEFAULT 0;
	SET nm=32-SUBSTRING(ip,LOCATE("/",ip)+1);
RETURN
	-- shift right and left looses host bits
	INET_ATON(LEFT(ip,LOCATE("/",ip)-1)) >> nm << nm;
END
CREATE FUNCTION inet_aton_bc (ip VARCHAR(18))
	RETURNS INTEGER UNSIGNED
	DETERMINISTIC
BEGIN
	DECLARE nm INTEGER UNSIGNED DEFAULT 0;
	SET nm=SUBSTRING(ip,LOCATE("/",ip)+1);
RETURN
	-- ip ORed with inverse netmask provides broadcast address
	INET_ATON(LEFT(ip,LOCATE("/",ip)-1)) | (4294967295>>nm);
END

yet another hype – wordpress

Yet again I couldn’t resist to a hype and ran personal WordPress deployment.

This time I guess I’m running away from LiveJournal, where blogs may be actually read and start my own corner, where I will be safely to spam the net, without obligations to any external hosting provider :)

In order not to make this post absolutely useless, I’ll pay tribute to Jan and his amazing lighty. This is how my web server is configured to handle all rewrite magic:

$HTTP["host"] == "dammit.lt" {
        $HTTP["url"] =~ "^/flow/" {
                server.error-handler-404 = "/flow/index.php?error=404"
        }
}

Too easy, isn’t it? :)

Update: this blog now lives on wordpress.com