Search Results: "rul"

20 May 2009

Martin F. Krafft: Five days to free Aung San Suu Kyi

In Myanmar, Aung San Suu Kyi and 2 000 monks and activists are being detained, as the miltary junta in the country presses new, ridiculous charges against Suu Kyi a few days before the end of her house arrest. Suu Kyi, recipient of the Nobel Peace Prize and proponent of democracy, is leader of the opposition and the greatest threat to the junta s grasp on power. Given the inhumane conditions imposed upon the Burmese, and the ruthless slaughter of those who do not play by the military s rules, it is not hard to imagine that she would win any fair election, as soon as she would get a chance to run. However, if the junta are successful in pushing charges Suu Kyi is accused of breaching the house arrest after an American man sneaked into her house uninvitedly she could be locked up until after the elections in 2010, effectively disarming the threat she poses to the military regime. She is threatened to be kept in the notorious Insein Prison without medical care. As she is suffering from serious illness, this puts her life at risk. I do not usually campaign for political topics, but I ve been to Myanmar and this issue touches me deeply. The people in Myanmar need our support. Even though the 2007 Burmese anti-government protests seriously weakened the military and brought hope to the lives of millions that have been oppressed for years, the events quickly vanished from the media and allowed the junta to regain control. We must not let that happen again. It is of utmost importance to show our support and not look away. One way of doing so is by increasing visibility. If you care, please write to your newspapers, publish on your blog, and do everything else you can to raise awareness. Another way to help the Burmese people is through signing the avaaz.org petition to UN Secretary General Ban Ki-moon. Best to do all of the above! Unfortunately, avaaz.org force-subscribes everyone who signs a petition to their newsletter, which may well not be what you want. However, please do not let it stop you from signing the petition. You can later unsubscribe from the (infrequent) newsletter. I have informed the staff members of this concern. If you would like to voice your opinion too, write to info t avaaz dot org and encourage them to make the newsletter subscription optional. But make sure to also sign the petition, please.

19 May 2009

Martin-Éric Racine: Invandringskonsult

In close to 11 years of living in Europe, I've accomplished plenty beyond working in the high-tech sector: I've also been fairly active in Immigration Policy, especially on aspects that affect migrant labor. Because of this, I keep on getting more and more requests to produce statements or to appear on panels to discuss issues pertaining to migrant labor and to immigrants' integration. The hot topic of last week was Swedish language for immigrants, the crux of the issue being that even though Swedish has an official language status in Finland, in practice, it is pretty much impossibly for immigrants to register their kids at the Swedish language school, to claim public services in Swedish or, even more so, to request labor training in the Swedish language at the Employment Office. The weekly newspaper Helsinki Times, in collaboration with the media think tank Magma, recently conduced a survey of the immigrant population, to find out how much they know about Swedish culture in Finland and about the Swedish language. It was in this context that the Helsinki Times and the national television's Swedish programming (FST) asked for an interview with yours truly, because I have recently visited the Ministry of Employment and Economics with a concrete proposal to facilitate the availability of labor training in the Swedish language. This FST webcast, starting at 16:03 minutes into the show, and the above Helsinki Times article provide more details about the context and about my proposal to the Ministry.

Obey Arthur Liu: PGP/GPG transition 8CA99047 -> 29C0FFEE *

Here comes the new 4096 bit RSA key, replacing the old (2002) 8CA99047 1024 bit DSA key:
pub  4096R/29C0FFEE 2009-05-18
  Key fingerprint = 9590 8AA6 E4F7 BAA7 8BD6  C148 F1A6 9BE4 29C0 FFEE
uid  Obey Arthur Liu <arthur@milliways.fr>
uid  Obey Arthur Liu <obey.liu@ensimag.imag.fr>
uid  Obey Arthur Liu <graffit@graffit.net>
uid  Obey Arthur Liu <obey.liu@lzb.fr>
uid  Obey Arthur Liu <arthur.randolph@gmail.com>
sub  4096R/15D7FD9B 2009-05-18
In other news, I found a great flatshare on Riedmattstrasse in Kreis 3 in Z rich with a fellow Google summer intern. Thanks to all (Jeroen, Martin, Jaroslavs, Giacomo..) who gave me pointers about finding accomodation in Z rich. I m looking forward to a great summer there. coffee * It did involve generating about 40 millions gpg keys on a few tr s badass computing clusters UPDATE: Come on guys. Of course I followed basic key management rules. The clusters which generated the actual final keys were under my direct control and the particular slice which generated this published key is on my desk.

18 May 2009

Marco d'Itri: Supporting unsupported USB devices

Some common classes of USB devices are supported by the same drivers because they share an identical or almost identical hardware design, but since each manufacturer uses its own Vendor and Product IDs the drivers need to be updated for each one. Some popular examples are 3G modems and devices which present a serial interface. As an interim solution until the kernel can be updated, the Linux device model provides a sysfs parameter called new_id which can be used to notify a driver that it should recognize a VID/PID pair as supported. The following example uses udev to add support for the Sheevaplug to ftdi_sio, the driver for the widely used USB to UART chips manufactured by FTDI. First we need a rule to automatically load the driver when the device is plugged in: udev cannot load it by itself since it does not know about the Sheevaplug VID and PID:
# if no driver has claimed the interface yet, load ftdi_sio
ACTION=="add", SUBSYSTEM=="usb", ENV DEVTYPE =="usb_interface", \
        ATTRS idVendor =="9e88", ATTRS idProduct =="9e8f", \
        DRIVER=="", \
        RUN+="/sbin/modprobe -b ftdi_sio"
And then we instruct udev to add the new VID and PID after the driver has been loaded:
# add the sheevaplug VID and PID to the list of devices supported by ftdi_sio
ACTION=="add", SUBSYSTEM=="drivers", \
        ENV DEVPATH =="/bus/usb-serial/drivers/ftdi_sio", \
        ATTR new_id ="9e88 9e8f"
While we are configuring udev we can also make it create a symlink for the console interface, since the FTDI chip in the Sheevaplug provides two serial interfaces: interface 0 is connected the JTAG lines and interface 1 to the serial console:
# create a convenience symlink for the console device
ACTION=="add", KERNEL=="ttyUSB*", \
        ATTRS interface =="SheevaPlug JTAGKey FT2232D B", \
        ATTRS bInterfaceNumber =="01", \
        SYMLINK+="sheevaplug"
This last rule shows an important misfeature of udev: while the keys ending in "S" can match nodes at any level of the devices chain, the matched nodes must be all at the same level. In this case this means that a single rule cannot have keys matching both the interface number and the VID and PID: this would require multiple rules and GOTO directives, so my rule matches the interface node which is available at the same level.

17 May 2009

Holger Levsen: Appropriate talk about porn: it's abuse

Russel, I agree that some porn sites are facing interesting technical challenges, but I wouldn't suggest using them as example for anything, just like a talk about the challenges of torture is always inappropriate in a human society.

Porn is, except for self made porn and some other corner cases, abuse and oppression. Simple as that.

And please, before you try to argue against that simple statement, read the lyrics of no answer for a dancer from one of my favorite bands, consolidated, and think for more than ten minutes. If we were living in really free societies, porn could be fun.

Which reminds me of a quote from Rebecca L. Eisenberg: "A truly radical view of pornography recognizes that we are what we consume -- and if we are going to alter the face of society, and destroy Victorian and religious notions like gender altogether -- as I believe we must -- we must be willing to evaluate and change every aspect of our lives, including the images we feed ourselves as we fuck, as terrifying as it sounds. Like it or not, revolution is a scary concept." The complete text where this quote is from can be found online on her webpage.

P.S: If you hear me playing "the internet is for porn" (this musicalsong) or remember me doing so - can you now see the great irony? I would have hoped you've seen it before. Or at least wondered, what the hell I was doing.

16 May 2009

Marco d'Itri: Installing Debian on the Sheevaplug

This document explains how to use deboostrap --foreign to build from scratch and install a minimal Debian system on the Sheevaplug (but it is equally applicable to many other embedded systems). The only piece missing to be able to install from bare metal is a working kernel and initramfs pair, so this document assumes that you already have a kernel which can mount the root file system from a USB key. For the Sheevaplug, the factory kernel in the internal NAND flash will work fine. The Debian kernel package puts us in a chicken and egg situation: it cannot mount the root without an initramfs (because all drivers are modular), but we cannot build one until we can boot the system. I suppose that, as an exercise of style, somebody could create a minimal initramfs with busybox and the kernel modules needed to mount the root and then mount it manually, but if you really lack a working kernel then it's probably faster to boot the file system image for the first time using qemu and the "versatile" debian-installer target. The first step is to run the first stage of debootstrap on another system (which does not need to be ARM), to build a temporary root file system. I use the --variant and --include options to build the smallest possible system with network support, but they can be omitted.
debootstrap \
         --foreign --arch=armel \
         --variant=minbase \
         --include=linux-image-2.6-kirkwood,module-init-tools,udev,netbase,
                   net-tools,ifupdown,iproute,whiptail,vim-tiny \
         sid ./target/ http://ftp.it.debian.org/debian/
As usual when using debootstrap, some manual configuration is needed:
cd target/
echo bokassa.mi.bofh.it > etc/hostname
vi etc/network/interfaces
vi etc/resolv.conf
echo LANG=C > etc/default/locale
echo '127.0.0.1 localhost' > etc/hosts
cat <<END > etc/fstab
/dev/root / ext3 noatime 0 1
tmpfs /tmp tmpfs defaults 0 0
#/tmp /var/tmp none bind 0 0
END
I took some hints from http://wiki.debian.org/ReadonlyRoot to reduce writes to the flash file system:
# the blkid cache is evil anyway
ln -s /dev/null etc/blkid.tab
# this link will be created anyway by the package
ln -s /var/lib/initscripts/nologin etc/nologin
# it's better to not use a static mtab with modern kernels
ln -s /proc/mounts etc/mtab
# unless you plan to use multiple removable network interfaces, persistent
# interface names are not needed
: > etc/udev/rules.d/75-persistent-net-generator.rules
Two small workarounds are needed:
# if this is not set then the preinst of linux-image-* will die trying
# to ask a debconf question in the debootstrap second stage
echo 'do_initrd = yes' > etc/kernel-img.conf
# a workaround for bug #520742
: > etc/udev/disabled
Now you can format a USB pen drive and copy the root file system on it:
mke2fs /dev/sdb1
tune2fs -i 0 -c 0 /dev/sdb1
mount /dev/sdb1 /mnt/
rsync -aH target/ /mnt/
umount /mnt/
After powering the plug press a key to get to the U-Boot prompt and use the factory kernel to boot from USB:
setenv bootargs console=ttyS0,115200 root=/dev/sda1 rootdelay=10 panic=10 init=/bin/bash
run bootcmd
Then you can run the second stage of debootstrap, finish the bare minimal configuration and start init:
./debootstrap/debootstrap --second-stage
# disable the gettys for /dev/tty[1-6], which do not exist
vi /etc/inittab
# and add one for the serial console
echo 'T0:2345:respawn:/sbin/getty -L ttyS0 115200 linux' >> /etc/inittab
# do not forget to set the root password or you will not be able to login...
vi /etc/shadow
rm /etc/udev/disabled
exec /bin/bash
mount / -o ro,remount
exec /sbin/init
Congratulations, now you can login on the system and start to install the packages you like:
echo 'deb http://ftp.it.debian.org/debian/ unstable main' > /etc/apt/sources.list
echo 'APT   Install-Recommends "false";  ;' > /etc/apt/apt.conf.d/no-recommends
apt-get update
# dash is much faster
apt-get install dash
dpkg-divert --add /bin/sh
ln -sf dash /bin/sh
# I do not like these, YMMV
rm /vmlinuz /initrd.img
rmdir /selinux /srv
# the kernel is able to read the time from the RTC by itself, and this
# will allow using a read only root
echo HWCLOCKACCESS=no >> /etc/default/rcS
# faster boot
echo CONCURRENCY=shell >> /etc/default/rcS
# useless on this platform
mv /etc/rcS.d/S01glibc.sh /etc/rcS.d/K01glibc.sh
dpkg-reconfigure tzdata
apt-get install openssh-server screen iptables wget less
U-Boot requires that the kernel and initramfs have a special header:
apt-get uboot-mkimage
cd /boot/
mkimage -A arm -O linux -T kernel  -C none -a 0x00008000 -e 0x00008000 \
  -n Linux-2.6.29-2 -d vmlinuz-2.6.29-2-kirkwood uImage
mkimage -A arm -O linux -T ramdisk -C gzip -a 0x00000000 -e 0x00000000 \
  -n initramfs -d initrd.img-2.6.29-2-kirkwood uInitrd
Now you can reboot and configure u-boot to boot from the USB device. This is the variables scheme I like and it is not mandatory in any way, so I recommend that you read and understand the existing configuration before modifying it (some lines have been broken for readability):
setenv bootargs_nand $(bootargs)
setenv bootcmd_nand $(bootcmd)
setenv bootargs_root root=/dev/sda1
setenv bootargs_misc 'ro panic=10
  mtdparts=nand_mtd:0x400000@0x100000(uImage),0x1fb00000@0x500000(rootfs)'
setenv bootcmd_usb 'usb start; ext2load usb 0:1 0x00200000 /boot/uImage;
  ext2load usb 0:1 0x01100000 /boot/uInitrd'
setenv bootcmd 'setenv bootargs $(console) $(bootargs_root) $(bootargs_misc)
  $(bootargs_more); run bootcmd_usb; bootm 0x00200000 0x01100000'
Since now you are not using anymore the Marvell kernel tree it is mandatory to set these two variables and reboot:
setenv mainlineLinux yes
setenv arcNumber 2097
saveenv
reset
Installation to SD is identical, but requires an updated version of U-Boot with SD support. Due to a kernel bug which prevents autoloading the driver you will need to add mvsdio and mmc_block to /etc/initramfs-tools/modules and rebuild the initramfs. (Yes, the naming theme I use at home is "african dictators"...)

14 May 2009

Julian Andres Klode: PHP, MySQL, PostgreSQL, etc.


Well, I m currently writing a PHP and SQL application at school, so here are some of my thoughts on the problems I encounter. PHP is crap Many PHP applications are low quality applications. The problem is that PHP makes it hard for developers to write good applications. PHP developers tend to use many global variables, global code, and not many classes or functions. And when writing applications for the web, PHP makes it easy to mix PHP and HTML, in my opinion even too easy. Well-written applications follow some basic rules. First, separate your code into functions and classes, and (2) split your code over multiple files. And there is one rule which is especially important for non-commandline applications: (3) seperate logic and presentation. This means if you write a web application, use a template engine. PHP error and exception handling is also an interesting topic. The problem here lies in the distinction between the both. In my opinion, there should only be one way to handle such stuff: Using exceptions. Exceptions are a very widespread way to program today, and are used in languages like Java and Python for cases where PHP uses errors. The concept of PHP s errors results in code like @do_something or die("blah"); being written in libraries which is a problem as it clearly violates rule (3) I wrote above, because there is no way to catch this die() error. Furthemore, PHP has no clear concept of namespaces in the current stable versions (< 5.3). PHP 5.3 finally gets namespaces, but using a backslash character, which looks really bad and makes everyone think of eithers Windows systems or escape characters. There are even more problems with PHP. From time to time, PHP just crashes with a segmentation fault. MySQL vs. PostgreSQL MySQL seems to have many problems with checking data, which can confuse me. It got better in MySQL 5 with the introduction of the new sql_modes like STRICT_ALL_TABLES and TRADITIONAL. And using storage engines like InnoDB also allows you to take advantage of stuff like foreign keys and transactions. But MySQL is still problematic. For example, in an application I wrote I had multiple entries identified by a numeric id (an INTEGER). One day, I wanted to check whether my error handling was OK and requested an entry with the invalid ID 1X , which resulted in SELECT * from A where id='1X';. Now I expected to get an error or at least no result, but MySQL happily proceeded with the query and returned the entry with the ID 1. I tried the same thing on PostgreSQL and got an error message that 1X is not integer, as I expected it. As another example, when I run the same PHP application using PDO on a MySQL database and a PostgreSQL database, I always get strings from the MySQL database whereas I get integers from PostgreSQL if the columns are integers. Another thing which PostgreSQL does better than MySQL is password encryption. MySQL only provides access to the standard crypt() function and by default only generates DES passwords. It allows other methods to be used (although not all are available everywhere and therefore not documented), but it provides no way to create a salt for them, which makes them not very useful. PostgreSQL in contrast provides less encryption methods but it provides the gen_salt() function which can be used to generate salts for blowfish encryption (gen_salt('bf')). Another problem is that MySQL simply ignores references when they are added to the column definition instead of a separate FOREIGN KEY . Because MySQL gives no errors when a feature like REFERENCES is not supported, developers may think that the feature is supported and write code using this feature just to realize later that what they wrote does not what they want. And you can t write AGPL applications using MySQL client libraries, because MySQL is GPL-2 which is incompatible with the AGPL. You might think that the FOSS License Exception helps here, but this only lists (among others) the GPL-3. Or am I wrong? But PostgreSQL has other problems, at least when it comes to the performance of the information_schema.columns view. This may be related to the fact that PostgreSQL has > 1000 rows whereas MySQL only has 250. And PostgreSQL may be a bit harder to configure. Final words All in all, PHP and MySQL are not the best choices for writing applications. They are to tolerant, and do not treat errors in an acceptable way by aborting the current action. I can get around some problems in PHP by using error handlers which raise exceptions and setting error_reporting to E_ALL, but in fact this should be the default. MySQL problems can be solved to a large extend by setting sql_mode to TRADTIONAL and using InnoDB databases, which should in my opinion be the default and not an option. My recommendation is to use PostgreSQL servers and for the applications: use frameworks (if you are allowed to, which may not be always the case [e.g. when you are learning SQL, using a ORM is clearly the wrong way]), document your code, separate your code into classes and functions, and make sure you are not using to many global variables. And use a SCM to track your changes. Posted in General

10 May 2009

Ond&#345;ej &#268;ert&iacute;k: My experience with running an opensource project

Nir Aides, the author of the excellent winpdb debugger, sent me the following email on September 21, 2008, so I asked him if I can copy his email and reply in form of a blog post (so that other people can comment and join the discussion) and he agreed. It took me almost a year to reply, but I made it. :)

Hi Ondrej,

How are you?

I am about to publish a new free software project, a new simple PHP framework, and I am interested in your advice.

You started SymPy and were able to make other people join you and develop it with you.
How did you do it?
How did it happen?
Did you actively call for other people or they spontaneously showed interest and joined you?
Are the other major contributor people who were your friends before you started the project?
Did you need to create or manage the project in a particular way to make it attractive to other people?
Are there things you are aware of that promote collaboration or demote it?

I was never successful in doing the same with Winpdb, which while it became reasonably popular, no one has ever joined me to develop it, except for a notable tutorial contribution by Chris Lasher which was developed independently.

Now with the new project, I am wondering what are my chances of making other people try it and take it on. On the one hand it is a new and fresh code base in an interesting field, on the other hand, why would anyone bother to spend their energy on this new project when they have Symfony or Drupal?

What do you think?

BTW, Ohloh believes you have a median of 19,000 lines of changed code per month since the start of their log. Can this be true? Is this humanly possible? According to it SymPy has over 1,000,000 lines of code? I can't understand these numbers. Winpdb has about 25,000 lines after 3 years of development. And from my experience 1,000,000 lines of code projects need about 20-50 full time developers to work on for 2-5 years which is about 40-250 man years. And as if this is not enough you are listed as owner in a dozen other projects in Google code and have enough time to become an awarded scientist. How is this possible?

http://www.ohloh.net/p/sympy/contributors/

BTW2, do you still use Winpdb? If you find yourself using it less, can you say what are the reasons, or what it would take to make it more useful?

BTW3, How is SymPy doing?

Cheers,
Nir



So my most honest answer how to run a successful opensource project is: I don't know.

But nevertheless I tried to summarize some of my ideas and experience and some guidelines that I try to follow, maybe it will be useful to you Nir, or anyone else.

First of all, there has to be a public mailinglist (easily accessible), public bug tracker, nice webpage, easy to find downloads, frequent releases (once a month is good, but in the worst case at least 4 times a year) and a set of guidelines to follow in order to contribute. So that's a must, if the project doesn't have the above, it's almost impossible to become successful. However, that is just a start, just a playground. There are still many projects that have the above and yet they totally fail to attract developers.

So I think the most important principle is that I always think how to employ other people in what I do. If I have some plan in my head how to do something, e.g. how to move some things forward, I always create exact steps and put it to issues, or our mailinglist, so that each step can be done by someone who is completely new to sympy. So I try to look at things from other people's perspective and think -- ok, I quite like this SymPy project and I'd like to get this done (for example a new release, or something fixed, or implemented), but I have no idea how to start and what exactly needs to be done.

So what I try to do if someone comes to our list and asks for something, is that I create a new issue for it and think how I would fix it if I had time. Then write the necessary steps in the issue and invite the submitter to fix it and I offer help with explaining anything and guiding. Now there are two things that can happen. Either the submitter has time and a will to go forward and in this case he starts wrestling with it and whenever he has some code or a question, I need to find time, review it and offer some way out. Or the submitter is too busy, in which case the instructions simply rest in the issues and the next time someone asks for the feature, the instructions are already there. I don't have estimates how frequent either case is.

When I am working on something myself, I try not to code privately, but also put up issues first and put the steps needed in the issues, so that it's easy for other people to join in.

In general, the most precious value for me is the fact that someone else had to sit down at his computer and wrote the patch. So I do everything possible to get new (or more) people interested in the development. Some people think that only super programmers can do a decent job and it's useless to invest time in people that may just have started with Python. They are wrong. Among the SymPy developers (around 65 people total have contributed patches so far at the time of writing this post), we have all kinds of people. We have people from high school, we have a retired US army engineer, we have physicists, mathematicians, biologists, engineers, teachers, or just hobbyists, who do it for fun. Unfortunately, we do not have many women (I think no patch that made it into sympy was contributed by a woman, but I may be wrong), so if anyone has any ideas how to get more women involved, let me know (I know we have several women fans, so that's a good start:). We have people whose first open source project they ever contributed to was sympy and people who are new to Python.

Many times the first patch that a new potential developer submits is not perfect, usually it's faster for me to write it myself, than to help with the first patch, however my rule is to always help the submitter do that. Sometimes he sends a second patch, or a third, and usually it needs less and less work on my side and it already pays off, because he is then able to fix things himself, if he discovers a bug and sympy has just won a one more contributor.

So I came to the conclusion that all that is needed is an enthusiasm. You don't even have to know Python (as you can learn all these things on the way) and you can still do useful things for us and really spare our time.

To answer another question from Nir's email, SymPy has about 130000 lines of code and another about 20000 lines of tests, so I think those stats are wrong. Also the changed lines of code is in my opinion wrong, we usually have about 250 new patches per release (this depends how often we release and other things).

Yes, I am involved in couple other projects, e.g. Debian, Sage, ipython, scipy, hpfem.org (and couple more), basically everything that has to do with numeric simulation and Python, but my activity there varies. The most time consuming thing in the last couple years was definitely school, I was finishing my master in Theoretical Physics in Prague and then moved to the Nevada/Reno and I just finished my first semester here at PhD in Chemical Physics, and sometimes it was just crazy, e.g. I finished teaching at 7pm and instead of going home and sleep, I stayed in my office, fixed 10 sympy issues that were holding off a release, finished at 1am, went home (by bike, since I don't have a car yet), slept couple hours and then did just school again for a week, other people reviewed the issues in the meantime, and then I made the release (instead of sleeping again). In the last semester it was not unusual that I got home at 1am every week day, then slept most of Saturday to catch up, on Sunday I did some laundry and shopping, and the rest of time I did grading and homeworks for all my classes and teaching, no time for anything else (e.g. no friends, no girls, no rest, no hobby, no opensource stuff, nothing). So sometimes one has to work pretty hard to get through it, but fortunately it's behind me finally, if all goes well, I should be just doing research from now on and have a real life too. Also I am sorry I didn't manage to reply sooner. :)

To answer the other questions:
Are the other major contributor people who were your friends before you started the project?
No, not a single major contributor was my friend before I started the project. Every single one of them become a developer using the procedure I described above, e.g. first showed on the list or in the issues, and maybe even the very first patch was not a high quality one (and if I was stupid and arrogant, or didn't see the big potential, I would just ignore them). But when given a chance, they became extremely good developers and sympy would simply just not be here without them.

Did you actively call for other people or they spontaneously showed interest and joined you?
I very much encourage everyone to contribute, but the initial interest must be in them, e.g. they at least have to show around the mailinglist/issues, so that I know about them. But once I know they are interested in some issue, yes, I try to invite them to fix it, with my help.

One observation I made is that I have to always think in the spirit "how to earn new money, not how to spare the money I already have", e.g. when applied to sympy, how to get new developers, how to develop the new great things etc. Even if I am super busy as I was, I still have to think this way. Once I start thinking how to conserve and preserve what we already have, I am done, finished and that's the road to hell.

If I am open, positive, full of energy, I can see people joining me and we can do great things together. It probably sounds obvious, but it was not for me, when for example some people I worked with, started their own projects, when I got busy, and started to compete, instead of helping sympy out. And I felt betrayed, after so much work that I invested into it and started to become protective. And then I realised that's wrong. I can never stop other people do what they want to do. If they want to have their own project, they will have it. If they don't want to help sympy out, they won't (and what is more important, there is nothing wrong with either of that). It's that simple and being protective only makes things worse.

There is also a question of the license that you use for the project, e.g. one should basically only choose between BSD (maybe also MIT or Apache), LGPL and GPL (there are also several versions of the GPL licenses). Unfortunately the fact is, that there are people who will never contribute a code under a permissive BSD license (because it's not protecting their work enough) and there are also other people who really want to code to be BSD (or other permissive license) so they can sell it and they don't need to consult with lawyers what they are or aren't allowed to do and also so that they can combine it with any other code (opensource or not). It also depends if one wants to combine (and distribute) other codes together. So choosing a license is also important. I believe that for sympy BSD is the best and for other projects (like Sage) GPL is the best and one has to decide on a case by case basis. For Winpdb, I would make it BSD too, since you can get more people using it.

To conclude, SymPy is a little more than 2 years old, and it has been a great ride so far and more things are coming, e.g. this summer we have 5 Google Summer of Code students and people are starting it to use in their research and we plan to use it in our codes at our group here in Reno too, so things look promising. I am really glad, we managed to build such a community, so that when I am busy, as I was the last semester, other people help out with patches, reviews and other things, so that the project doesn't stall and when I got rid of my school duties now, we can move things forward a lot.

So maybe you can get inspired by some of the ideas above. I am also interested in any discussion about this (feel free to post a comment below, or send me an email, or just write to a sympy list about what you think).

Marc 'Zugschlus' Haber: Pushing a packet back and forth between Linux subsystems

Linux policy routing is still incredibly painful if one wants to have more sophisticated routing than just take source and destination IP address for the routing decision . The mechanisms that have been in use seven years ago still work though, and I didn t find any possibility to do it any easier. In this article, I ll try to explain the old mechanisms and hope that somebody from lazyweb will comment and say it can be done so much easier . This is a translation of the Usenet article <gu48cs$rul$1@news1.tnib.de> in de.comp.os.unix.networking.misc in the hope that the english-speaking blogosphere can give additional insights. Given a Linux-based router with one internal network (int0), one perimeter network (per0) and two Internet connections (ext0, ext1) with one IP address each. We need to do source NAT to deliver Internet to the internal and perimeter networks. The internet connection on ext0 will be used for http and https, while all other traffic needs to go out on ext1. The perimeter network is reachable from the outside via destination NAT.
1: ext0:  mtu 1500 qdisc noqueue
    inet 10.81.221.145/29 brd 10.1.221.151 scope global ext0
2: ext1:  mtu 1500 qdisc noqueue
    inet 10.82.83.225/29 brd 10.82.83.231 scope global ext1
3: per0:  mtu 1500 qdisc noqueue
    inet 172.16.1.254/24 brd 172.16.1.255 scope global per0
4: int0:  mtu 1500 qdisc noqueue
    inet 192.168.8.254/24 brd 192.168.8.255 scope global int0
We have the following routing rules:
0:      from all lookup 255
10:     from all lookup main
32:     from all fwmark 0x12e lookup to_ext0
32:     from all fwmark 0x12f lookup to_ext1
32000:  from all lookup defaultroute
32000:  from all lookup defaultroute
32766:  from all lookup main
32767:  from all lookup default
Table main contains all rules for the directly connected networks, but no default route. Both to_ tables have one default route each, pointing to the respective ISP, and the table defaultroute has once more a default gateway pointing to ext1 s gateway. The PREROUTING chain of the mangle table has these rules:
iptables --protocol tcp --dport 80 --in-int int+ --set-mark 0x12e
iptables --protocol tcp --dport 443 --in-int int+ --set-mark 0x12e
iptables --in-int int+ --set-mark 0x12f
and the POSTROUTING chain of the nat table has these:
iptables --match mark --mark 0x12e --out-int ext0 --jump SNAT --to-source 10.81.221.145
iptables --match mark --mark 0x12f --out-int ext1 --jump SNAT --to-source 10.82.83.225
If now somebody from the internal network accesses a web server on the Internet. The outgoig packet will first be marked in the PREROUTING chain, then the routing rules will use the firewall mark to consult the correct routing table and pass the packet back to the packet filter, where the POSTROUTING chain will use the outgoing interface and the firewall mark to SNAT the packet to the correct source IP so that the answer will actually reach us. Has a less ugly way available way to do this become available in the last five years? Or is it still necessary to have the different parts of the networking subsystems play ping-pong with the packet? I particularly dislike that someone not familiar with policy routing will not see any default route in the routing table printed by route or ip route , which will probably be very confusing. Is there any possibility to interact with the routing code without firewall marks, maybe by directly setting a gateway from a firewall rule?

9 May 2009

Rapha&#235;l Hertzog: Quilt patch management with debhelper 7

Since quilt 0.46-7 (see #527255) you can automatically apply/unapply a quilt patch serie with debhelper s dh command. It s very practical in tiny rules files:
%:
	dh --with quilt $@
There s also dh_quilt_patch and dh_quilt_unpatch for those who don t use tiny rules files. Enjoy ! Partagez cet article / Share This

7 May 2009

Robert Collins: 7 May 2009

My desktop machine blew up, so I got a lovely fresh install of Jaunty. And, X and Gnome still disagreed by default about my actual screeen size... it was unreadably small with the default fonts. I've posted the following instructions before - these are basically unchanged except that the location of the fonts dialog has moved. Tip for folk that would like X to show fonts (i.e. the GDM log in screen) in the correct size: Teach X about the dpi setting! Step 1: run xdpyinfo and look for the dimensions: line. There will be something like this: dimensions: 1280x768 pixels (266x161 millimeters) resolution: 122x121 dots per inch Grab a ruler and measure the screen you have. If it matches the millimeters reported by X, then skip step 2. Step 2: edit /etc/X11/xorg.conf, and locate your Monitor section: Section "Monitor" Identifier "Generic Monitor" Option "DPMS" DisplaySize 265 160 EndSection Add in a DisplaySize like I have there. Now logout of your GUI and restart X - you can run /etc/init.d/ g,k dm restart from the console, or do what I do - just hit ctrl-alt-bkspace so it restarts. Your login screen should change appearance slightly - either the fonts and regions will get bigger if your dpi was set too low, or vice verca. Step 3: (For KDE users, someone please tell me what it should be, for GNOME read on)... Run xdpyinfo again and find the Resolution: line. Ignore the fact that it may not be square, grab one of the two numbers ( I suggest the higher).. Go to System, Preferences, Appearance, and the Font tab. Select 'Details'. There is a Resolution field there. Put in the single number you chose. Changes should take effect immediately. Applications I know of which benefit from having this set correctly: xpdf, gnome-* (panels are readable etc etc), firefox.

6 May 2009

Jan Hauke Rahm: irssi rulez

It s done all messages are now running through my fancy IRC client named irssi. What messages you ask? Well, there is all IRC traffic obviously, then all jabber contacts, and all ICQ/AIM contacts and woohoo thanks to twirssi I now even have my identi.ca (or Twitter if you re brave enough) feeds in an irssi window (from which I can also update my identi.ca stuff, of course). Isn t that great?

5 May 2009

Jan Hauke Rahm: Avelsieve 1.9.8

Today the SquirrelMail plugin avelsieve happened to be released with version 1.9.8. Thanks and kudos to Alexandros who after so long time still was in the mood to put things together. The new features promise to be amazing: a new user interface, much code rewriting, and an entirely new SPAM handling. Unfortunately after installing it my SquirrelMail installation went badly down somehow. While everything alse is delivered properly by apache2, SquirrelMail now runs into one timeout after another. I need to figure out what s actually going on there. The error.log is quiet so far Anyways, for all you people who are looking forward to see this new fancy and shiny version in sid, I have to ask for patience. I think the package is ready but before testing no uploading! Until then you can (if you re brave) test the package by installing it from http://downloads.jhr-online.de/avelsieve_1.9.8-1_all.deb And all you others just have a look at the changelog that s probably (hopefully) hitting sid in a few days:
  * New upstream release
     + A large part of the code has been rewritten.
     + A new-style SPAM rule has been implemented.
     + A new, global Whitelist rule has been implemented, for
       the SPAM rules to take advantage of.
     + New, "Custom Sieve Code" rule has been implemented; this allows users
       to enter directly Sieve code snippets as a rule. (experimental)
     + Miscellaneous code movement and restructuring.
     + UI: The "Add New Rule" buttons are now links, and are displayed
       both at the top and at the bottom of the rule table.
     + UI: Major rework in the UI of both the Rules Table and the Add New
       Rule / Edit Rule pages.
     + UI: If a vacation rule is active, then display a notice in the
       rules table page and upon logging in to Squirrelmail, that reminds
       the user.
     + UI: Vacation options have been aligned properly; text has been
       changed accordingly.
     + Sieve: Vacation Subject is now supported.
     + New functionality: "Insert New Rule Here"
     + New functionality: "Move Rule to Position" (requires Javascript)
     + Avelsieve now highly recommends the use of javascript_libs plugin
       for some visual effects / UI improvements.
     + UI: Added new icons and used different ones, to improve usability.
       Icons are provided by Mark James' famfamfam.com.
     + UI: Added new icon "theme" based also on famfamfam.com. This theme
       is the default from now on.
     + UI: Removed unnecessary text / clutter from rules table page.
     + UI: The notify action options have been aligned in a table.
     + Added an LDAP Sieve storage backend, compatible with Sun Messaging
       Server's Sieve features.
     + The DO_Sieve_* backends should have a separate retrieve() method
       for retrieving the raw Sieve script. Currently, only the Managesieve
       backend has it.

Luca Bruno: Inkscape 0.47 (tentative) release plan and about-screen contest


Time has come again for a new shiny release of Inkscape, namely 0.47
So Scislac recently published a raw release plan, and we ve already entered the soft freeze period. The stable release is currently due for middle of June, but right now it s a too early stage to fix it on a calendar Meanwhile, we re running the usual about-screen contest, hosted once again at DeviantArt. The contest will be running till May 25th so start working on your sumission right now and have the opportunity to let your signature on this marvelous release! Be sure to check the rules for it first Still a lot of work has to be done, so if you re a bug-hunter (win and and OSX much appreciated), a translator or a documentation writer, feel free to get in touch with the inkscape community and help us make another great release.

4 May 2009

Steve Kemp: A lot of people drink mineral water

dmonitor now has a webpage. I've been running it for a night now, watching alerts come and go via manual firewall rules so I'm pretty confident it works reliably and in a way that avoids transient failures. The only obvious failure case is if each monitoring node loses the links to each of the others. (Solution there is to have a sufficiently large number of them! Hence the reason the configuration is file/directory based. rsync for the win!) Still I will leave it there for now. The only things missing are better instructions, and more service checking plugins.. Now to go paint some more ... adding new wall decorations has inspired me a little! ObFilm: Heathers

2 May 2009

Dirk Eddelbuettel: Brad Mehldau at the CSO

Just got home from a wonderful concert by Brad Mehldau at the CSO. This was long overdue as I kept reading about Mehldau. And even though he performs quite regularly around here, I had never seen him. Big mistake. The first set was performed as a (strictly acoustic) trio with Larry Grenadier on bass and Jeff Ballard on drums. After several compositions by Mehldau and a brazilian samba piece, the first set closed with a rendition of 'Holland' from Sufjan Stevens' album Michigan which was truly beautiful. The second set had Mehldau performing solo, again with several compositions of his own as well as one from Neil Young's classic 'The Needle and the Damage Done' leading two two pieces from the Sound of Music including an amazing, yet really different 'My favourite things' that just hushed a piece of the central melody along with a strond rhythmic element. Lovely. And then to cap it all off, four encores. Highly recommended.

1 May 2009

Simon McVittie: Implementing D-Bus clients with telepathy-glib (and telepathy-qt4)

(The much-delayed part 2 in an ongoing series: shiny things in telepathy-glib) Over a year ago I explained my first major round of work on telepathy-glib, with which it could be used to implement D-Bus services. I started to write this post shortly after, but then got distracted by a bee or something; recent discussion about having a D-Bus binding in GLib has finally prompted me to finish it. The second major round of work on telepathy-glib dealt with implementing client code, and went sufficiently well that telepathy-qt4 (currently under development) uses essentially the same model. Again, while telepathy-glib is intended for Telepathy implementors, I think TpProxy's ideas are generically useful, particularly for "large" D-Bus APIs.

Some background: dbus-glib and libtelepathy
GObject-CRITICAL: Assertion failed: proxy->convenient
The life-cycle of a DBusGProxy (PD clipart credit: karderio and Andy)
The API provided by dbus-glib for client code is, er, rather less than ideal. The basic object is DBusGProxy, which has a few problems. There's one per interface, rather than one per object; this leads to a maze of twisty GObjects, all suspiciously similar. Our old client library, libtelepathy, got round this by subclassing DBusGProxy to make helper objects called TpChan, TpConn etc., which were simultaneously the proxy for the "main" interface (Channel, Connection etc.), and a factory for proxies for the other interfaces (like Channel.Type.Text and Channel.Interface.Password). This still wasn't ideal, but it was a start. If you use a DBusGProxy in any way after it has emitted the destroy signal, this is considered to be invalid use of the API, and dbus-glib asserts all over the place. We'd rather it didn't do that - remote objects becoming invalid is a fact of life, and if you don't immediately discard all your references to those objects, remote operations on them should just give you a runtime error. You have to be prepared to handle such runtime errors already, because any IPC call can fail at any time. The main API for calling methods uses varargs and is rather subtle. Notably, the calling convention for variant parameters (of D-Bus signature 'v') is not consistent with the calling convention for any other container. For any other container, for instance a GPtrArray *, you pass in a GPtrArray ** pointing to a GPtrArray * variable containing NULL; on success, a pointer to a new GPtrArray is written into that variable. For variant parameters, though, you must pass in a GValue * pointing to a zero-filled GValue, and the result will be written into that GValue. dbus-binding-tool generates thin wrappers around this method-calling API which provide type-safety, although they can't directly specify a non-default timeout. As for signals, before binding to a signal, you have to tell dbus-glib about its signature. This tells dbus-glib how it should push the signal arguments onto the C stack (in GObject terminology: how it should marshal them), to match the signature of the signal-handler function. The documentation claims that this isn't necessary for objects supporting the Introspect method, but that's untrue - on the other hand, if the documented behaviour actually happened, I would consider this to be a critical bug in dbus-glib, since it would enable remote objects to crash dbus-glib clients (by causing signal arguments to be pushed onto the stack in a way that does not match the signature of the signal handler). Of course, the signal-adding function takes varargs, and has to be called exactly once per signal per object. If you don't, dbus-glib asserts when you connect to the signal; if you call it twice, dbus-glib asserts anyway.

TpProxy TpProxy is a GObject subclass vaguely inspired by Python's dbus.proxy.ProxyObject. It isn't a subclass of DBusGProxy, which lets us encapsulate dbus-glib almost completely - in fact, all the references to DBusGProxy are in a separate header, proxy-subclass.h, only used by subclasses of TpProxy (as opposed to normal library API users). TpProxy instances are per-remote-object (per-object-path) like in dbus-python, rather than per-interface like in dbus-glib or QtDBus. As explained below, I believe that this is the most natural object mapping for D-Bus interfaces; in practice it tends to lead to clearer code for us, since one remote object often maps nicely to one UI element (of course, if your objects only have one interface, this approach is no better or worse than dbus-glib's). TpProxy provides support for the following common D-Bus things:
  • Calling methods
  • Connecting to signals
  • Objects becoming invalid
  • Objects with optional interfaces
  • Extensibility
It doesn't currently provide any particular help with Properties - the Properties interface is just another interface as far as we're concerned. We find that, in practice, that's not a problem (even though we use D-Bus properties extensively). In telepathy-qt4 we basically reinvented TpProxy in C++, as Tp::DBusProxy. I've put in some comments below illustrating how the general ideas we used in TpProxy translate into a different object mapping.

Calling methods Method calls on TpProxy are done through auto-generated wrapper functions, much like DBusGProxy. These look something like this:
typedef void (*tp_cli_channel_callback_for_close) (TpChannel *proxy,
    /* any 'out' arguments would go here - Close() doesn't have any */
    const GError *error, gpointer user_data,
    GObject *weak_object);
TpProxyPendingCall *tp_cli_channel_call_close (TpChannel *proxy,
    gint timeout_ms,
    /* any 'in' arguments would go here - Close() doesn't have any */
    tp_cli_channel_callback_for_close callback,
    gpointer user_data,
    GDestroyNotify destroy,
    GObject *weak_object);
Methods for some interfaces, like DBus.Properties, are available on TpProxy itself; others, like Telepathy's Channel.anything, are only available on a particular subclass, like TpChannel. Things to note here:
  • It's an asynchronous call with a callback. General design principle: "this is IPC, get over it". We don't try to hide the fact that IPC is taking place by doing pseudo-blocking calls.
  • The timeout is explicit (although you can always pass -1 to let libdbus pick a "reasonable" default for you). This is because the remote service might not respond, and API users should be at least vaguely aware of this: "this is IPC, get over it".
  • The callback isn't a GCallback; it has an explicit signature, for some semblance of type-safety (it's not much, but it's better than nothing).
  • The callback takes a GError, because any IPC call can fail for any reason.
  • A TpProxyPendingCall * is returned. This is a pointer to an object that only exists until just after the callback is called (so you can ignore it if you don't want it), with a method you can call to cancel the method call (with hindsight this is not ideal, and if I was writing this API now, I'd use gio's GCancellable). "Cancel" is perhaps slightly misleading: the method call still takes place (it was already in libdbus's outgoing queue) but the result gets ignored and the callback isn't called. This is mostly so you an object can forget all the calls it was busy making at the time that the results become irrelevant (e.g. the object is destroyed).
  • There is an extra weak_object argument, which is weakly referenced and is passed to the callback: in practice, most users of telepathy-glib use this as well as or instead of user_data. If the weak_object runs out of references, the callback is automatically cancelled, which means that in practice, explicit cancellation is almost never needed.
  • The generated code has as its first argument a suitable subclass of TpProxy, in this case TpChannel (we tell the code generator about subclasses).
  • You can't see it in the API, but the TpProxy gains an extra ref while a method call is in progress, so you never have to worry about what happens if the proxy gets unreffed during a method call.
  • There's an explicit destructor for the user_data, which is called even if you "cancel" the method call.
In telepathy-qt4, these methods are on small generated helper classes similar to dbus-python's dbus.Interface, one per interface (we provide accessors for them on the non-generated DBusProxy subclass). Instead of using callbacks, we return a temporary QObject per call, which emits a Qt signal on success or failure (that's how all async calls in QtDBus work).

Connecting to signals Similarly, signals have some generated functions:
typedef void (*tp_cli_channel_signal_callback_closed) (TpChannel *proxy,
    /* any arguments would go here - Closed doesn't have any */
    gpointer user_data, GObject *weak_object);
TpProxySignalConnection *tp_cli_channel_connect_to_closed (TpChannel *proxy,
    tp_cli_channel_signal_callback_closed callback,
    gpointer user_data,
    GDestroyNotify destroy,
    GObject *weak_object,
    GError **error);
API notes for these:
  • The callback doesn't take a GError any more, because signals can't fail; the weak_object and the user_data are the same as for method calls
  • This isn't actually a GObject signal at all: those aren't particularly typesafe, and lack namespacing. This might not be very binding-friendly, we haven't tried doing that yet... it might be worth introducing a signal with details, like in dbus-glib, for which these functions are "C bindings".
  • The returned TpProxySignalConnection lets you disconnect from the signal, just like the TpProxyPendingCall above; it can safely be ignored
  • Similarly, if the weak_object dies, then the signal automatically disconnects
  • It is possible for connecting to a signal to fail: this happens if the proxy doesn't actually have the requested interface. If this happens, it's graceful, not a crash. In practice, the flow of code is almost always such that error can safely be NULL because the interfaces are already known.
In telepathy-qt4 the per-interface generated helper classes emit Qt signals. In many cases, we end up proxying these signals by responding to them in the hand-written Tp::DBusProxy subclass by emitting a different signal, in order to give them a nicer representation.

Becoming invalid This is IPC, and any error can happen to you at any time. We found that it was useful to have a general concept of "this object is no longer useful", so we introduced the concept of an object becoming invalidated. The invalidation reason is stored on the object as a GError. If this GError is NULL (as it is initially), then the object is still expected to be valid; if it's non-NULL, the remote object has vanished and the local proxy no longer works. There are several ways a TpProxy can become invalid:
  • its bus name falls off the bus (the process exited or crashed)
  • application-specific reasons (usually triggered by a D-Bus signal in a subclass, like the Telepathy Channel's Closed signal)
  • the GObject gets disposed
Method calls on an invalidated object always fail, with the invalidation reason as the error. This means that calling a method on a TpProxy should never crash your process. The method's callback has to be prepared to handle an error in any case, because this is Sparta^WIPC, so there's no loss in giving it another error. Connecting to signals on an invalidated object always fails, and any existing signal connections are disconnected when it becomes invalidated. This means that if a new remote object appears, and it happens to have the same object path, bus name etc. as the old one, you won't get its signals. A TpProxy can either be bound to a unique bus name or a well-known bus name. In the equivalent code in telepathy-qt4, we call this "stateful" or "stateless" - these names don't capture the intention perfectly, but they're the best we could come up with. A proxy for a stateful API like Telepathy's Channel should always bind to a unique name - when the unique name falls off the bus, the TpProxy becomes invalidated automatically, representing the fact that the Channel you had no longer exists, and nothing can be a perfect replacement for it (the VoIP call has already been terminated, you've already left the chatroom, or whatever - if you make another Channel, that's e.g. a distinct VoIP call). A proxy for a stateless API like Telepathy's ConnectionManager, where an exiting process can disappear, be service-activated again, and still have exactly the same API, should bind to the well-known name. Proxies for well-known names aren't invalidated when the process exits. Qt doesn't have a natural equivalent for GError, so the invalidation reasons in telepathy-qt4 are just a pair of strings, the namespaced name and the message - basically a libdbus DBusError. The principle is the same, though.

Optional interfaces As mentioned above, TpProxy instances are per-remote-object (per-object-path) like in dbus-python, rather than per-interface like in dbus-glib or QtDBus. I believe that this is the most natural object mapping for the D-Bus object model, because the D-Bus interfaces on a remote object can behave like any of these:
  • classes and subclasses (Telepathy.Channel.Type.Text is a Telepathy.Channel)
  • shared interfaces (some Telepathy.Channel objects, of many Types, implement Telepathy.Channel.Interface.Group; any D-Bus object can implement DBus.Properties)
  • optional features (some Telepathy.Channel.Type.Text objects implement Telepathy.Channel.Interface.ChatStates, some do not)
  • discoverable extensions (some Telepathy.Channel.Type.Text objects implement Telepathy.Channel.Interface.Messages, which is more or less Text 2.0)
The way in which interfaces are discovered is also variable. The "classic" D-Bus way to discover interfaces would be to call Introspect. Telepathy services still support that style of introspection, but we don't use it for anything beyond d-feet:
  • Introspect returns a blob of XML, which you have to parse into something useful; if it was in a D-Bus data structure, you'd already have some sensible data structure.
  • Finding out more information about the supported interfaces than their names isn't very useful: in a static language like C you already need to know the methods, signals, properties and their signatures in order to write and compile your code, and in a dynamic language like Python consumers of Introspect end up being remotely crashable by services with unexpected method signatures (this is one of dbus-python's big mistakes in my opinion).
  • If a method that you want to call turns out to be missing, the worst that can happen (in a competently written service) is that it fails with a D-Bus error - and you have to handle D-Bus errors anyway, because this is IPC and anything could fail.
  • Static bindings like dbus-glib have poor support for removing interfaces for which C code exists at runtime, whereas Telepathy needs features like an IM connection that might or might not support avatars (we don't get to find out until we've successfully connected to the server).
Instead, our older interfaces have a method on the "base class" (Channel, Connection etc.) called GetInterfaces, which just returns an array of strings. Newer interfaces (like Account), and older interfaces that have been ported (like Channel), have a property called Interfaces which is, again, an array of strings - this lets us combine the download of the interfaces list with downloading other basic information in a GetAll call. To cater for all these ways to use interfaces, the TpProxy base class has very basic support for interface discovery - you can ask it whether it supports an interface, and you can tell it that it does, in fact, support an interface. Asking which interfaces are supported is directly useful for library users; it's also used as a check by the generated method-call and signal-connection stubs, which return a canned error (Telepathy.Error.NotImplemented in Telepathy's case) if the object isn't known to have the interface. Telling TpProxy that it does support an interface is intended for use by subclasses, and might have been protected if we were writing C++: what happens in practice is that a concrete subclass like TpChannel knows how to discover the fully supported interfaces for this particular object, does so, and calls methods on the TpProxy to tell it which interfaces can work.

Extensibility The API stubs used by TpProxy to call methods and bind to signals are generated from XML documents containing an augmented form of D-Bus introspection data. These XML documents contain various Telepathy-specific extensions, but none of the extensions are language-specific - telepathy-glib, telepathy-python and telepathy-qt4 all operate from exactly the same XML specification. telepathy-qt4's different object-mapping did require us to tighten up some rules that were previously only conventions, but even so, the format is the same. I think this is vitally important - it just doesn't scale to have one set of language-specific annotations in a D-Bus API for each language that will have bindings. One thing that we make heavy use of is what I call "Ugly_Case", which is camel-case with underscores at word boundaries. This gives us a simple, unambiguous and foolproof rule to use in code generators whenever we generate any of the popular conventions for identifiers:
  • CamelCase: delete underscores
  • javaCamelCase: force everything before the first underscore to lower case, then delete underscores
  • lower_case: force everything to lower case, retain underscores
  • UPPER_CASE: force everything to upper case, retain underscores
dbus-glib, by contrast, applies a complex and subtly buggy algorithm to the CamelCase D-Bus names, which results in our SendDTMF method being mapped into GLib as send_dt_mf, and requires that telepathy-glib's Python reimplementation of dbus-binding-tool uses a bug-for-bug compatible implementation (we ended up reimplementing dbus-binding-tool in order to generate the TpProxy-based bindings). Our code generation tools are still rather ad-hoc, because so is our spec format, but for draft interfaces it's possible to copy them into individual projects and use them to generate additional methods for TpProxy or any subclass. This is how we implement unfinished APIs like geolocation in Empathy, for instance. The Interfaces or GetInterfaces hook described above is entirely usable for these extension interfaces, and in fact that's how they're set up. In telepathy-qt4, the generated method stubs are genuine C++ methods, so we can't just append methods to an existing class: this is why we have one helper class per interface, so individual clients can generate a helper class for their particular version of an unfinished API, and instantiate an object of this class attached to a particular Tp::DBusProxy. When an interface becomes stable, it can be added to the set of interfaces for which code is generated in telepathy-glib or telepathy-qt4, at which point any client or service that was already using the final draft of that interface can easily be ported to the library version using sed (the API remains the same).

Becoming ready The concept of being "ready" does not directly exist in TpProxy, but is implemented in TpChannel, TpConnection and TpConnectionManager. The idea is that a freshly created proxy object isn't really fully usable yet - you have to connect to basic signals and recover the initial state of the remote object, as well as checking which extension interfaces are supported. In many well-designed D-Bus APIs you can do this initial setup with a few signal connections and a DBus.Properties.GetAll call. After doing that initial setup (which has to be done asynchronously, because it's IPC), the TpProxy subclass has a local cache of the remote object's state (not necessarily in the same format as the representation on the bus), which can be accessed synchronously at any time, and will be updated in response to change-notification signals. TpChannel and subclasses like it have explicit support for checking for readiness, and having a callback called when the object is ready or invalidated (whichever happens first). The "ready" property also supports the GObject notify signal. telepathy-qt4 took this concept and ran with it - there is library support for objects that can become ready, including a mixin. If I had as much time to work on telepathy-glib as I wish I had, this would be one of the first telepathy-qt4 features to be added to telepathy-glib.

Features becoming ready Going beyond that, in an extensible framework like Telepathy it's probable that not every client understands (or wants to understand) every feature of every object, so it's highly inefficient for every proxy object to subscribe to all the change notification signals and cache all the remote state on the off-chance that the library user wants them. In the API for TpContact (which is not actually a TpProxy for various reasons) we introduced the concept of optional features; telepathy-qt4 extended this idea throughout the library. The idea is that each library user knows which of the optional features are "interesting" to it, and makes a single asynchronous call (which expands into a series of D-Bus calls inside the library) to download the state for core functionality plus all of the selected features, and subscribe to change notification for all of those. This is another telepathy-qt4 thing that telepathy-glib still needs to catch up with; until someone works out how to make the clone() syscall apply to programmers, I fear all libraries are doomed to lag behind how their designers want them to look :-) (license: CC-BY-3.0 / LGPL-2.1+)

30 April 2009

Biella Coleman: On Chasing Plastic

Anyone who knew me prior to 2000, knew me as a fanatic Ultimate Frisbee player. I was (mostly) all about chasing a plastic disc on lush green fields. Ultimate Frisbee, which took my attention and soul my first year of college, commanded my attention, time, and body for years. The New York Times just ran a nice short piece piece about Ultimate Frisbee, which apparently has skyrocketed in popularity since 2003. One section of the article caught my attention:
It may be a non-contact sport according to its rules, but Ultimate is hardly free of injuries. The quick cutting and sprinting have made anterior cruciate ligament tears among women players especially common. JOY CHEN, a 33-year-old software developer in Alameda, Calif., considers herself lucky that herniated disks, a rotator cuff tear and ankle sprains have been the extent of her Ultimate injuries. We hit each other and the ground pretty hard, said Ms. Chen, who discovered Ultimate in college after years as a soccer and tennis player. She played with Stanford University s Superfly, which went on a three-year run as undefeated women s national collegiate champions.
Injury goes with the sport as hand and glove and young players tend to wear these injuries as a badge of pride. As much as I adore the sport and there are days I get pretty bummed that I no longer play I think that the UPA and older players should seriously skool the younger generation on the danger of injuries. It is an extreme sport that requires extreme care. Tournaments are usually composed of 4-7 games over the course of 2 days. If that is not demanding enough, the body gets pretty intimate with the the ground while laying out and then there are there all those sprained ankles and broken bones and ligaments from collisions. Today I suffer from bouts of knarly neck pain, for example, which is due in part from playing without taking proper precautions. One of my best friends, who was a stellar player in college, also suffers from pretty devastating back pain. It is an extreme sport that requires extreme care. I say toss out the pride in pain/injuries and in place, instill a healthy sense of fear of the injuries so that people get proper long term and sustained care for their injuries so that they can keep on playing the world s best sport. PS For those that don t know, UF also revolves around an ethical philosophy Spirit of the Game, which unfortunately the article makes no mention of, despite its centrality to the sport.

28 April 2009

Erich Schubert: Supporting Internet Exploder

Quoting MSDN on the CSS "clip" property:
As of Internet Explorer 8, the required syntax of the clip attribute is identical to that specified in the Cascading Style Sheets (CSS), Level 2 Revision 1 (CSS2.1) specification; that is, commas are now required between the parameters of the rect() value.
...
In Internet Explorer 7 and earlier (and in Internet Explorer 8 or later in IE7 mode, EmulateIE7 mode, or IE5 mode), the commas should be omitted.
... and if you want to support both?I see a few options:

22 April 2009

Gunnar Wolf: Rodrigo denying evasions and religion

Umh, is today the quote your neighbour day? No? Thought so... Still, for the second time in a couple of minutes, I'm quoting/translating here. This time, I'm quoting a short text posted by fellow Mexican Debian guy Rodrigo Gallardo: Deceptions (hmm... Not in the let you down sense, but in the deceiving sense. Sometimes it is hard to translate a single word without twisting it around). My translation is far from perfect - Read it in Spanish, you will enjoy it more. Rodrigo says:
Things and actions are what they are, and the consequences of them will be what they will be; why then should we desire to be deceived? Joseph Butler
I was in Colima, sitting on a slide in a city park, that day I understood why somebody might want to be drunk. Several years later, this time in Tlalpan, I understood why somebody would want to believe in a god. And sometimes I am truly sorry not to be able to embrace neither of both longings. The idea of letting go the facts, to believe they have an inner order, although covered in mistery, or they are just far away, blurry. But where others see destiny, I see things falling naturally in their place. Where others see beauty in the mistery, I see a challenge. And even more beauty in an elegant explanation, in understanding. Motivation, not in the promise of future welfare but in the certainty of this limited but tangible present welfare. Freedom in the absence of a purpose, and inmortality in the little pebble I am in the great human building. I suppose that if Revernd Butler knew his phrase inspired this divagation, it would not make him precisely happy. But, things are what they are, and his argument says what it says.

Next.

Previous.