Utopia in the header file

This is from the top of sqlite3.h, the header file for the SQLite3 library - most source file would have a copyright notice here referring people to read their license, but since SQLite is public domain, the author decided to put this instead:

** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.

I have to admit I find this inspiring. For me, it is a strong reminder that dealing with legal limitations (on software and any other form of “intellectual property”) is at best no more than a necessary evil. That goes for free software licensing as well.

Experimenting with Glista on OS X

I haven’t blogged in a while, probably because I was too busy. I’ve been working, started to take some university classes (Philosophy & Computer Science), and… I’m doing most of my work on Mac OS X now. Don’t worry, I’m still a Linux guy - but mostly for work purposes (and out of curiosity) I decided to ask Zend for a Macbook when my Thinkpad was starting to die.

Unfortunately the negative side effect of this is that I had to put Glista on hold - since I didn’t have a Gtk+ based desktop anymore there wasn’t much point in actively working on it.

However, in the last couple of days (following some patches that came in from ananasik, for whom I immediately gave commit access) my fingers started itching, and I decided to play with porting Glista to OS X - and found this project.

After some hours of tinkering, crashing, building, rebuilding and breaking things again, I now have a somewhat working (albeit ugly, and not so OS X friendly) working Glista.app Application bundle running on my own 32 bit OS X 10.6:

Glista running on native OS X for the first time!

Glista running on native OS X for the first time!


Glista in the Dock!

Glista in the Dock!

If you’re really up for it, you can get a Disk Image here.

You can also build it from source by checking out http://glista.googlecode.com/svn/branches/osx-support and doing the following:

  1. Make sure you have all the nescesary build environment (XCode is usually a good start!)
  2. Install all the gtk-osx tools and libraries including ige-mac-builder and gtk-quartz
  3. cd into the source directory and run (in a jhbuild shell after installing osx-gtk) ./configure –prefix=$PREFIX
  4. Note that some things do not work on OS X yet (or will never work) like libunique integration, gtk-spell, libnotify integration etc. - that’s normal for now
  5. Run ‘make’, don’t (!!) run ‘make install’ (well you can, but there’s no need, you’ll just pollute your system
  6. cd into dist/mac/ and run ‘make dist-mac’. If everything is ok this should create Glista.app in that directory.
  7. Move that .app into /Applications (or anywhere else) and enjoy!

So far, it looks like it’s going to be a long time before Glista will work smoothly on Mac - and most of it is because Gtk+ is not really that portable, and making it use OS-native widgets and rendering seems to be quite a challenge. I also don’t feel I know enough about the internals of Gtk+, Quartz or OS X in general in order to help with that effort - but who knows, maybe I’ll be able to help somehow?

BTW I’m not sure if that binary will work on anything but OS X 10.6 on Intel 32 bit. If you try, let me know!

NetworkManager: Auto-HTTP login to a Wifi network

One of the cafés in my area where I frequently drink / work requires you to pass through an annoying web page forcing you to agree to some terms before allowing you to access the Internet through their Wifi network. It's free - but they still annoy you with this silly HTTP gateway. This is actually a frequent thing in Israel - most cafés offer free Wifi access, but some will require to to log-in nevertheless.

So today I figured out how to get NetworkManager to automatically work around this HTTP gateway for me whenever I connect to Arcaffe's Wifi network. Since it's super cool, and since I bet lots of people are annoyed by these sort of Wifi gateways, here's how to do it:

Apparently, NetworkManager allows you to create special post-connect or post-disconnect scripts that are executed when a network interface is brought up or down. Here is what I did:

I Created the following script and saved it at /etc/NetworkManager/dispatcher.d/100httpgateway.sh:

CODE:
  1. #!/bin/sh
  2.  
  3. IFACE="eth1"
  4.  
  5. if [ "x$1" = "x$IFACE" ] && [ "$2" = "up" ]; then
  6.     # Figure out the wifi SSID
  7.     SSID=$(/sbin/iwconfig $IFACE  | grep ESSID | cut -d: -f2 | sed 's/^\s*"\(.*\)"\s*$/\1/')
  8.  
  9.     case "$SSID" in
  10.         "012-ArCaffe")
  11.            URL='http://captive.012.net.il/user/refresh/home?confirmed=true&submitButton=+OK+&CPURL=http%3A%2F%2Fwww.arcaffe.co.il%2F&t=fsm3j5oe'
  12.            DATA='x=9&y=5&agree=on&username=arcaffe&password=arcaffe012'
  13.            COOKIE='Cookie: JSESSIONID=uc54121j305s; cookies=true'
  14.            REFERER='Referer: http://captive.012.net.il/home?confirmed=true&submitButton=+OK+&CPURL=http%3A%2F%2Fwww.arcaffe.co.il%2F&t=fsm3j5oe'
  15.  
  16.            curl -d "$DATA" -H "$COOKIE" -H "$REFERER" "$URL"> /tmp/arcaffe.last 2> /tmp/arcaffe.last.err
  17.         ;;
  18.     esac
  19. fi

Don't forget to make the file executable - I did it by running chmox +x /etc/NetworkManager/dispatcher.d/100httpgateway.sh.

Some things you should note:

  • "012-ArCaffe" is the ESSID of the network I'm logging in to. This of course work for ArCaffe in Israel, but you should change that with your network's ESSID.
  • Replace the value of IFACE with the name of your wireless interface
  • $1, the first parametter passed by NetworkManager to the script, is the network interface that was just connected or disconnected
  • $2, the second parameter, is "up" or "down" - the status of the interface.
  • The code I have inside the case block is where the magic happens. In this case, I send an HTTP POST with the correct parameters, Cookie and Referer headers and URL. This causes ArCaffe's gateway to log me in
  • I use curl - but I could have also used wget or any other tool to do the job
  • The -d flag sends the POST data, the -H flags set a header
  • I figured exactly what request to send using LiveHttpHeaders - but you can also use tcpflow or any other packet sniffing or HTTP sniffing tool
  • You can add more options to the 'case' statement for more networks that need that sort of treatment. With a little of bash-fu that should be no problem.

That's it! Man I love Linux today :D

Priceless: “The Issuer Certificate Is Unknown”

Firefox: "mossad.gov.il uses an invalid security certificate"

Another example of the all-so-frightening invalid HTTPS certificate warning in Firefox 3.0. I just found this one to be a bit ironic :)

BTW The Mossad website is mostly for recruiting purposes, they don't really let you search their archives on-line or anything... to bad, that could have been interesting :P

(and one more thing: yes, it's "The Mossad" and not just "Mossad" as it's frequently mis-translated in foreign media. "Mossad" literally means "Institute" or maybe in a less literal translation, "Agency". There are many institutes and agencies, but there is only one "The Institute")

Subversion: Finding the “base” revision of a branch

I use Subversion a lot - but today I've learned something new:

You can easily find the "base" revision of a branch or a tag (i.e. the revision in which the branch or tag was created) by issuing the following command:

CODE:
  1. svn log -v --stop-on-copy \
  2.     http://glista.googlecode.com/svn/branches/feature-reminders

The last revision you see in the log (in this case from one of my own Glista project's branches) is the revision the svn copy command was issued on, i.e. the branch was made.

This can then be used when merging the same branch back into trunk.

Neat!

Notify me when emerge is done

As a Gentoo user, I frequently install new software or update existing packages using emerge. Unlike binary package managers, building packages from source using emerge takes time, and I prefer running it inside a detached screen session, because (a) if I close the session it continues in the background and (b) it actually runs faster when it doesn't need to show all the compilation output in an X terminal.

This has an annoying side effect: I sometimes start a long update process and forget I did it. If things fail (or even if they succeed) I don't know about it.

Today, I solved this problem using notify-send, the libnotify binary client. I've created a short shell script wrapper to emerge which sends me a notification once emerge finishes, along with the original command line arguments and exit status code (0 = ok, failure otherwise):

CODE:
  1. #!/bin/sh
  2.  
  3. ARGS=$@
  4.  
  5. /usr/bin/emerge "$ARGS"
  6. STATUS=$?
  7. if [ "$STATUS" = "0" ]
  8. then
  9.         LEVEL="normal"
  10. else
  11.         LEVEL="critical"
  12. fi
  13.  
  14. /usr/bin/notify-send --expire-time=0 --urgency=$LEVEL "emerge finished" "Exit Code: $STATUS
  15. Emerge args: $ARGS"

If you save this code in a file named emerge-notify (and of course remember to chmod +x this file) you could then do this (from a GNOME terminal or any other X terminal):

CODE:
  1. $ ./emerge-notify -puD world

And you'll get a nice notification when it's done:

"emerge finished" notification

Of course, you need libnotify the notify-send binary and dbus for this.

PHP Error Reporting Levels - WTF is 6134?

In PHP, the error reporting level (whether errors go to the log or to the screen or whatever) is determinded by the error_reporting INI directive (or at runtime using the error_reporting() function). Both take an integer as their value - and usually this integer is represented by error level constants like E_ALL, E_STRICT or E_USER_WARNING.

So in order to set the error reporting to anything but notices and strict errors, you would set something like this in php.ini:

CODE:
  1. error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

(actually, E_ALL does not really include E_STRICT but I put it here just to be more explicit)

This is actually great - one of the more easy to use and understand APIs in my opinion (yeah, I really like bitwise operations).

However, what I really hate is that sometimes I need to work with the integer value of the error reporting level (like 1 for E_ERROR or 84 for E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR) and it's very hard for me to remember what arbitrary numbers like 6134 mean.

So, today I wrote this tiny CLI script that helps me understand what an arbitrary error_reporting level integer might mean:

CODE:
  1. <?php
  2.  
  3. $errorLevels = array(
  4.         'E_COMPILE_ERROR'     => E_COMPILE_ERROR,
  5.         'E_COMPILE_WARNING'   => E_COMPILE_WARNING,
  6.         'E_CORE_ERROR'        => E_CORE_ERROR,
  7.         'E_CORE_WARNING'      => E_CORE_WARNING,
  8.         'E_ERROR'             => E_ERROR,
  9.         'E_NOTICE'            => E_NOTICE,
  10.         'E_PARSE'             => E_PARSE,
  11.         'E_RECOVERABLE_ERROR' => E_RECOVERABLE_ERROR,
  12.         'E_STRICT'            => E_STRICT,
  13.         'E_USER_ERROR'        => E_USER_ERROR,
  14.         'E_USER_NOTICE'       => E_USER_NOTICE,
  15.         'E_USER_WARNING'      => E_USER_WARNING,
  16.         'E_WARNING'           => E_WARNING,
  17. );
  18.  
  19. if (! isset($_SERVER['argv'][1])) {
  20.         fprintf(STDERR, "Usage: {$_SERVER['argv'][0]} <error_level>\n" .
  21.                         "  Where <error_level> is a PHP error reporting level\n");
  22.         exit(1);
  23. }
  24.  
  25. $level = $_SERVER['argv'][1];
  26.  
  27. echo "Error level $level includes:\n";
  28. foreach ($errorLevels as $k => $v) {
  29.         if ($level & $v) echo "\t $k \n";
  30. }
  31.  
  32. echo "\n";

To use, just run the script with a single value parameter, like so:

CODE:
  1. shahar.e@wintergreen ~ $ php error_level.php 6134
  2. Error level 6134 includes:
  3.      E_COMPILE_ERROR
  4.      E_COMPILE_WARNING
  5.      E_CORE_ERROR
  6.      E_CORE_WARNING
  7.      E_PARSE
  8.      E_RECOVERABLE_ERROR
  9.      E_USER_ERROR
  10.      E_USER_NOTICE
  11.      E_USER_WARNING
  12.      E_WARNING

Enjoy!

Glista 0.3 Released

Thanks to the very good holiday layout this year*, I finally got to release the next preview release of Glista - my super simple Gtk+ based to-do list manager for your desktop.

The major improvement in this release is category support. For a while, I didn't want to add any features that will make the UI more complex than it is. Then I noticed that I tend to add ad-hoc categories to my tasks in order to sort them - that is instead of typing "Fix ZF bug #1234" I type "ZF: Fix bug #1234". This is a very natural way to organize your tasks for me, and I assume that it is for most people. So I decided to add category support by recognizing this colon-separated syntax and breaking any item typed in this way into a "cateogry: item" structure.
[more...]

ZendCon 2008 Slides

Well, ZendCon is over and it was much fun! I got home today (well, does 4:30 am count as "today" ?) and am still very tired - I had to stay around after the conference for some meetings (yes, the title "manager" causes some PITA even if you do not really manage anyone) which was a bit exhausting but fruitful never the less.

I gave this presentation about Zend Platform:

It's the first time ever I'm giving a presentation about proprietary Zend technology in an open-source conference so I was a bit nervous - but to my surprise I got a full room (I estimate some ~100 people were there, and only a few Zenders) and there seemed to be a lot of interest. In general this ZendCon felt a bit more "business-oriented" than usual, but still had a good mix of community and hacker-spirit to it.

Another thing is that Siddhartha - our VP of Sales for North America actually HUGGED me after the talk. He was sitting in the room and the guy knows a lot about selling Zend Platform - but I suppose that hearing the value of the different features and some good example use cases for Zend Platform from a technical perspective gave him and the rest of the sales team some good insight into what customers are looking for in such a product.

Anyway enjoy the slides and if you have questions just post a comment. I will probably post some more about the previous week - if only I will be able to get my hands off my new iPod Touch ;)

Reminder: Open-source is great!

From time to time I get reminders to why I love open source so much, and why I see it as having little to do with software and a lot to do with promoting a culture of sharing and of openness.

A few days ago I released my first C open source app - Glista. It was a little tool I wrote to scratch an itch and to sharpen my hardly-existing C skills. Deciding to release it was natural, but I didn't expect much attention from such a simple tool competing in a category where many alternatives exist.

However, it did get noticed and I had several people e-mailing suggestions, reporting bugs and generally commenting on it, giving mostly positive and useful feedback. I was able to fix several bugs in the last few days and I did learn a few things on creating better build scripts, which I was clueless about before.

And the best thing is that at less than a week after it's initial release, Glista was ported to run on an iPaq PDA using the OpenEmbedded cross-compiler. I even got some screenshots to show off:

Glista on iPaq     Glista on iPaq

How cool is that?

This is done using the unstable branch of OpenEmbedded so there are no official builds yet - but the author, Dmitry, has attached a recipe file to this bug report in the OpenEmbedded tracker if you want to try it.