Monday, December 27, 2004

Special Characters and Gmail

Not only does gmail filter out ".", it also chops off everything from the first "+".

This enables using tmda or simply filtering on what address you choose to give. (Similar to how some people give vendors their names with different middle initials, in order to track how their name got onto different lists.)

Monday, December 20, 2004


Java is a little wack. Its selection box gui widgets have items which are either editable or not. The following is the necessarily verbose way to create an uneditable selection box that allows adding a new item with an explicit action. (Contrast with autocompletion in an editable field, which provides a very low barrier to adding new items.)

import java.awt.Component;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.ComboBoxModel;
import java.util.Vector;

* JComboBox for which selecting a particular item allows editing a new item
public class JOtherComboBox extends JComboBox {
int otherIndex;
ActionListener otherItemActionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOtherComboBox widget = JOtherComboBox.this;
if (widget.getSelectedIndex() == otherIndex) {

widget.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) { work(e); }
public void keyPressed(KeyEvent e) { work(e); }
public void keyReleased(KeyEvent e) { work(e); }
public void work(KeyEvent e) {
} else if (widget.getSelectedIndex() >= 0) {

public JOtherComboBox(Object[] arg0) { super(arg0); init(); }
public JOtherComboBox(Vector arg0) { super(arg0); init(); }
public JOtherComboBox(ComboBoxModel arg0) { super(arg0); init(); }
public JOtherComboBox() { super(); init(); }

public void init() {

public int getOtherIndex() {
return otherIndex;

public void setOtherIndex(int arg0) {
otherIndex = arg0;

public static void main(String[] args) {
JFrame frame = new JFrame();
JOtherComboBox comboBox = new JOtherComboBox(new String[] {"one","two","three","four"});


Friday, December 17, 2004

Databases Suck

That is, what we refer to as relational database management systems suck. They're too monothilic. An RDBMS typically has
  • a persistent store
  • a type system
  • indexing features
  • a transaction manager
  • a query language
  • a network protocol
  • usually a full embedded programming language
All this stuff makes them inflexible, and painful to integrate. People like them because they're completely independent of the rest of your code, even to the extent that a human being can often poke at them without application-specific software. They're also standardized-ish.

One Device

Even if single-purpose devices often work better, when it comes to mobile devices, people want one device that does everything. Otherwise, it can get to be a lot to carry around.

So here are the functions that are candidates for integration:
  • telephone
  • camera
  • image browser
  • audio player
  • storage media
  • broadcast radio receiver
  • audio recorder
  • web browser
  • email client
  • organizer
  • video player
  • video camera
Most of these have already been integrated into at least one cell phone product. When will we see it all come together? What a device to have hackable!

These super-devices will change the world. In order to do it, they'll...
  • use good voice recognition as the primary user interface
  • embrace a more end-to-end approach
Cell phone technology is still very far from end-to-end. Carriers will try to prevent the change, because it will completely overturn their businesses.

Thursday, December 16, 2004

Note about Gnome Storage

Not only will Gnome Storage make finding documents easy, remove the need for "Save", and therefore simplify task management, it will also replace a lot of existing interfaces.

Bookmarks, browser history, email indices, song playlists, photo galleries, "personal information management" views: working with these interfaces composes a large part of the time we spend with computers. Once all their info goes in a common storage layer, there'll be no reason to have many different metadata viewer implementations. (Of course, there'll be a mechanism to customize views.)

But that's not all. The desktop'll get many of the advantages of the web. We'll be able to create links to any object, whether it's an email message, a song, or a todo item. Any object may be bookmarked, and we'll get a history of all the objects that we've viewed.

This means big things for the semantic web movement, because it'll create huge amounts of metadata. Not only will we suddenly have easy, standard access to how often we listen to our favorite songs, we'll also know that they're predominantly in the "mp3s from joe" query folder, for example.

Once most applications can store their data in common, we can give them a common implementation of other fun features, versioning and notification, collaboration and localization.

Monday, December 13, 2004

No Password for Local Users

Do you want to relieve local linux users of having to enter passwords? Follow these steps to disable default remote access, which will make it safe for default accounts to have no password.
  1. create a group "remote", and add users to it that may login remotely
  2. add the following lines to your /etc/security/access.conf:
  3. add the following line to your /etc/pam.d/system-auth:
    account     required      /lib/security/$ISA/
  4. add the following line in your /etc/pam.d/su:
    auth       required       /lib/security/$ISA/ use_uid deny group=remote
If you have a local domain, you might have to tinker more with access.conf, because the "LOCAL" source specification is funny; it matches any host or tty name without a ".".

This was tested with Fedora Core 2.

Of course, you could take the converse approach: give everyone a password, and just don't require passwords for local logins to accounts in the "local" group. This approach is probably more robust against configuration changes (e.g. if a service stops including "system-auth" it will allow logging in without a password). The first approach however is nice for granting minimum necessary privilege. Maybe both is best. Presumably the second approach would be done with a line in local service pam.d config:
auth       sufficient item=user sense=allow file=/etc/localusers onerr=fail
and this works for gdm at least. "mingetty" (for text logins) is a problem because it shares the "login" pam config with "in.telnetd" for plain-text remote logins. Of course, you could hack it with pam_access again (and /etc/security/group.conf) , but the extra complexity probably isn't worth it.

My Daughter

My daughter is the coolest. She just turned three. A couple of days ago she was watching the Elmo episode about music. ("Elmo" is a friendly, red furry creature, on a segment of Sesame Street for toddlers. Each Elmo episode has a theme.) Elmo's pet goldfish, Dorothy, had a toy drum in her jar. My daughter observed, "Dorothy can't play the drum because she don't got hands. She also don't got a stick."

Wednesday, December 08, 2004

Gcc on Solaris

If you're getting
/usr/include/sys/termios.h:376: parse error before `uint32_t'
then you should be invoking gcc as:
gcc -I/usr/include

Tuesday, December 07, 2004

Better Spam Protection

In short, it's a combination "disposable addresses" and "challenge/response whitelists"...
  1. Everyone in your addressbook can mail you without qualification
  2. Everyone can respond to one of your private messages
  3. Everyone can respond to one of your public messages within a fixed interval of time
  4. Everyone else can mail you by confirming their first message by email
The "whitelist" refers to #1, and it may also incorporate the address of anyone new that you email. It's insufficient because many people send mail from a different address than they receive mail. #2 solves this problem by embedding a cookie in your return address (e.g. (Many ISPs allow you to receive messages to your account name appended with a plus or minus followed by any string.)

You can embed a hash of the address that you're sending to, plus a hash of that hash. The second hash allows you to check that the embedded cookie is valid. The first hash allows you to create a single return address for each address that you send to. If someone who knows that address ever sends you spam, you can blacklist that generated address only.

When you want to receive responses to a publically posted address, it isn't a question of whether you'll want to eventually blacklist the address, but when. In that case #3, you can embed a cookie which instead contains the date until which you'll accept unconfirmed messages.

Even people who can't use the above methods should be able to reach you #4. All of the those people must undergo the slight annoyance of confirming their first message. Their first message will trigger an automatic response from you explaining the situation. They must respond once to that message, and they'll then be added to your whitelist.

The TMDA program does almost all of the work. #2 requires a two line patch. TMDA out-of-the-box is completely unconfigured, but my configuration looks pretty portable. I'll post it after I've been using it for a bit.