Let's Make Unix Not Suck
Miguel de Icaza (miguel@helixcode.com)
Helix Code, Inc.



Introduction

The Unix system, designed and constructed in the 70s by people living in a very different world from us, and it has stagnated. Unix has some good qualities, and they have taken us a long way. But the problems in Unix are becoming increasingly clear, and they are holding us back. It is time to take a good hard look at Unix, to recognize what's broken, and to fix it. In this article, I describe some of the problems that we in the free software world must face, and discuss the ways in which the GNOME project is addressing them.

I gave a talk.

My recent presentation at Ottawa Linux Symposium started by stating that Unix sucked. This was a punch line that I found good to introduce the vision we have in the GNOME project to address a number of problems in Unix when it comes to code reuse, consistency and usability. This is the vision of the GNOME project and this was the subject of my talk.

I was addressing the software developers in the free software community that were attending the Ottawa Linux Symposium. My talk was designed to expose a number of flaws in UNIX, and to present a concrete proposal on how some of these problems can be addressed. The idea was to issue a call to developers to help realize this vision.

I was speaking to a live audience, and it was a fun talk to give. I hope the audience had fun listening to it. The talk sadly does not translate well to a mainstream three paragraph summary and much less to the single punch line: "Unix Sucks".

I have received a large amount of mail after the post was sent to Slashdot and to lwn about alternative operating systems that "do not suck". The characterization of my talk was completely inaccurate: sure, Unix is not the best system out there, but we intend to fix this problem. The intention of my talk was to make people realize what was wrong, and convey the unified vision that we have in the GNOME project to address these issues.

The contents of this talk were designed with Nat, while we were considering my presentation for Usenix. I want to thank Nat extensively for his help preparing this talk.

People have suggested a number of operating systems to me that "do not suck": plan9, BeOS, Windows NT, MacOS X. And they have said `If you hate Unix so much, go use those'. The goal of my presentation was to bring into the light the problems of Unix and present concrete solutions to address its problems. I am mostly interested in free Unix systems like GNU/Linux and the BSD family.

When I use the word "free" in this document I am using it in the context used by the Free Software Foundation, you can read more about it here: http://www.gnu.org/philosophy/free-sw.html

Software for the people

As part of the GNU project we are trying to bring free software to people. We are trying to give people a number of freedoms that traditional software companies have not granted you.

The state of GNU and Linux three years ago was something among the lines of `a wonderful free Unix implementation'. We had a system that was as powerful as Unix, and as user friendly as Unix.

The objective of the GNU and GNOME projects is to bring this software and grant freedom to as many people as possible. This means providing software that is easy to use, intuitive, appealing and that feels "right" for end users. End users are important, because they are the vast majority of people.

Do not be confused. The majority of people do not use computers to do programming, nor to learn how to use nroff, nor to run a web server. The majority of people use computers to simplify their lives, to communicate with people, to get work done, or to have fun.

Our work is not about technology for its own sake. It is about bringing free technology to people.

Unix is a very powerful foundation. It is here, and we can build on top of it instead of reinventing a complete new system.





The Unix Problem

Unix was designed in the 70's, and it included a wide range of very interesting conceptual features. At the time it was designed it definitely set a new standard for the ways we thought of operating system. A great accomplishment.

It would be foolish to think that the current abstractions we have deployed in Unix are sufficient and that they are good enough, and that we are doing just fine.

It would be foolish to think that Unix in 10 years will be just fine with what we have now, and that all the infra-structural pieces that were designed over the last 30 years are sufficient and that no work has to be done infra-structurally wise and that only new applications are required.

We have been working on creating a desktop and a suite of productivity applications for this desktop, and during this process we have found that a number of technologies that are available on other systems just do not exist on Unix, and there is no concerted effort to provide these.

Remember Unix three years ago:

  • No innovation was happening.
  • No code reuse was happening.
  • There was a lack of basic facilities for adoption on the desktop.
  • The little innovation that was happening was proprietary.

No code reuse.

We believe that Unix became stagnant because there was little code reuse happening on the larger scale Unix applications, and people were focusing on very small improvements that did not have an architectural impact.

Innovation was proprietary

In the very few cases where major subsystems in Unix were redesigned, those redesigns were kept as proprietary extensions, which again meant nothing if you were looking at the big picture. For instance, consider Display Postscript. No free implementation existed, and even today it is not part of a standard free system. Proprietary innovation means nothing to us.

So we believe that innovation in the Unix world can only come if we all work in a common code base: an open source code base. If there are strings attached to the software, then that piece of software will just not get adopted.

No concerted effort

The few free software efforts that were working towards producing new software to keep Unix competitive were not working together and barely had any standards or inter-operability features.

Consider the various window managers and their configuration languages; Consider the various programming languages in Unix; Consider the various killer applications in Unix. Nobody was sharing any code at all.

No policies.

In the UNIX kernel, the tradition is to not implement policy. This approach and philosophy permeates the whole UNIX system.

For instance, even X-Windows[1] avoids establishing policies for anything.

What we have ended up with is the ultimate pluggable system: the ultimate "write your own" operating system.

Developers trying to satisfy every possible user from every possible background, for every possible task end up making everything an optional feature. They end up not standardizing on anything and leaving policy to applications.

The problem is that leaving the policy to individual applications means that each application gets to decide its policy, its user interface, its configuration files, and its own way of doing things.

This leads to a complete lack of consistency on graphical applications. It is not just a matter of toolkit fragmentation: even if you compare Motif applications you will see that they behave radically different when they have to deal with the operating system and with the user preferences and with the environment in general.

Sure, we have the ultimate plug-and-play system, at the expense of having a barely integrated environment.

Unix today is more of a collection of outdated and loosely coupled tools. The result is a remarkably low-quality experience for users.

Code sharing

In the past little code sharing has happened. There are various reasons for this problem:

  • People did not build reusable libraries from existing projects.
  • People did not want to add dependencies to their code (for instance, Lars Wirzenius attempted to develop a library of common C routines that barely saw any adoption due to the dependency issue).
  • Lack of long term plans for the Unix platform.
  • Fear of standardizing.

In the GNOME project, we have taken a different approach. In the GNOME project:

  • We are standardizing the way applications should behave.
  • We are providing policies through our libraries to make applications compliant to the GNOME look and feel while reducing developer pain.
  • We are leveraging the power of existing libraries by reusing them in GNOME.
  • We are building on top of what we have instead of attempting to create collections of tools that are fully "independent" and that are fully "configurable" for every user on the planet and their cousin.

We are creating libraries that address various needs of modern applications, and we encourage developers to use these libraries. By using these libraries, you basically avoid writing code that we already wrote for you. And what is even better is that when we improve the libraries, your application is improved as well.

Unix vs Win/Mac

I have seen many times people defending the greatness of Unix by comparing the good things of Unix against the bad things of other operating systems. I have done this myself in the past.

Here is a common problem: people focus on their strengths and ignore their flaws when it comes to anything that is dear to them. Even worse, when comparing with another competing entity, they focus on their weaknesses and ignore their strengths.

The problem with this approach at looking at things is that eventually the competition will catch up with you. At the time you realize this, they already got your features, and you have none of theirs.

This is why it is very important to keep a self-critical approach and try to improve things before it is too late.

For instance, I remember the glorious days when Linux started: a comparison of Win 3.1 vs Linux 1.0 always came down with Linux winning every time: we had a multi-tasking OS, a sort of reliable system, a good network abstraction, a slowish windowing system (but hey, who used X anyways? we just wanted a text console), we could run web servers out of our boxes and so on. We could do things that Windows would never be able to do: because they did not have a multi-tasking system.

Then Windows95 came along and Windows NT came along. Now those systems were catching up. Of course, they still performed poorly when it came to reliability, but their user interface was nice (which we lacked), and they had the applications (which we also lacked).

And now Windows 2000 has been released. Sure, it still crashes, but it is getting better on every release. And it no longer has such a large impact on users.

Unknown to the untrained eye, a large revamp of the core of those operating systems was happening at the time: their COM component architecture which was originally developed to solve other problems was found to be a very good general solution to many problems: from scalability problems for software development, to code reuse and to consistency[2].

Are we going to be able to deliver a system that is ten times better than the proprietary offering? I think we should.

I do not think free software will succeed in its current shape: a lot of work needs to be done to address the needs of modern users.

Remember, this is software for making people's life easier.

Summary

Software is written to solve people's problems. We should design software in such a way that the software adapts to the needs of people, rather than the other way around.

Unix is a complex system internally despite its simplicity in its design, but it is not a system ready for end users. And this is what the GNOME project is building on top of the existing Unix foundation.

When you develop applications, keep the end user in mind.

For the rest of the paper, I look at some specific examples of software problems which Unix currently does not address or addresses very poorly. Then, I show you how the GNOME project is solving those problems.




Components

Brad Cox pushed the concept of Software Integrated Circuits (Software ICs) that are reusable pieces of software. The core of his idea is that the Hardware guys have managed to develop a reusable component mechanism (Integrated Circuits) that enables people to quickly reuse the components in a variety of methods.

Any electronics student equipped with a TTL manual can start reusing components right away and build pretty amazing things.

Brad Cox's proposed solution to the problem was Object Oriented programming and specifically the Objective-C language.

Object Oriented Programming is a great way of reusing code, and it is a great way of plugging pieces together give or take. If objects maintain a contract to the world or "interface", we know that users of that code will be able to use this object as long as the interface remains the same.

There is one practical problem: objects are typically implemented in a OOP-enabled programming language and those objects are exposed to the programming language only (even if they can be exposed to other languages, this is typically not very simple and sometimes never gets actually done):

  • C++ objects live within the C++ universe.
  • Perl objects live within the Perl universe.
  • Java objects live within the Java universe.
  • Python objects live in the Python universe.
  • Object Pascal objects live in the Object Pascal universe.
  • Gtk objects live in the C/Gtk universe.

If you have a nice implementation of say, an HTML parser in Perl, you wont be able to use it directly from Python or C++, or C without doing some professional gymnastics.

Objects are a great programming tool, but they do not solve the entire problem. There is still a lot of code duplication (exercise: search for HTTP handlers; XML parsers for the above languages).

Unix Components: Small is Beautiful

Various people claim that the Unix philosophy is to have little programs that do one thing right, and only that one thing. These individual components can then be combined together and they help create more complex applications.

The idea is that individual components are build independently and then they are connected through pipes, and then textual data is exchanged by these components, creating a richer system.

The interface to these reusable Unix components is fork/exec, command line arguments, settings on the environment variables, an input stream and an output stream.

The Unix filters deal with a stream of untyped data: the tools work either by processing each character, each line, or the entire buffer.

For instance, if you are familiar with XML and HTML, you would know that one of the big advantages of XML over HTML is that you can tag information with context, and that information can be richer: you no longer are dealing with a file that describes formatting commands for the text, but instead you operate at a higher level: you deal with data that has been tagged: tagged data lets you know more about the data.

Also, a pipeline looks like this:

		command | filter1 | filter2

Information flows from command to filter1 and finally to filter2. There is no way for filter2 to communicate with command or with filter1 and interact with it.

So, even when pipes are a very powerful concept in Unix, it is not the end solution for building applications out of components. Here is the proof:

Lets take a look at the most popular Linux applications on the server space: Samba, Apache, NFSD, innd, sendmail, in.named, ftpd and ssh.

If you examine those applications you will notice that they barely "use" any of the Unix "components" to carry their tasks. If they use them is more of an inadvertent side effect.

Even worse than that is the fact that none of those applications share any code besides the UNIX libc. You would think that those daemons would share some code, for instance timeout handling, main loop integration, idle handlers, daemon-ification routines, configuration parsing routines, security libraries, anti-exploit avoiding routines.

But they do not. They share no code at all outside the most basic Unix services. None. Ninguno. Niente. Rien.

Various people like to criticize Microsoft for producing "bloated and monolithic applications". Before we criticize Microsoft, lets take a look at the end user applications that we have on Unix outside of GNOME: Netscape, GhostView, XDVI, Acrobat, Mathematica, Maple, Purify, FrameMaker, Star Office.

The only common denominator on those applications is libc and Xlib. Some share Motif, but that is about the extent that these applications are sharing any code. And of course, the Unix "components" play no role in the equation: they are basically never used (I can only think of the printer spooler daemon being used, and even in this case: it is not even compatible across operating systems).

Now, lets look at Microsoft "bloated and monolithic applications" again: lets consider "Internet Explorer".

Internet Explorer is not a single executable as you might think. Internet Explorer is built of a collection of COM components. These components are developed individually, debugged individually, exported individually, and eventually, all of them create the illusion of an integrated application.

Now, the beauty of this is that these components can be reused outside of Internet Explorer: programmers outside of Microsoft can use those components in their applications: the HTML rendering engine, the XML engine, the JavaScript engine, the toolbars, their scripting engine and so on.

Microsoft applications reuse pieces of Internet Explorer.

Sure, we have small components, that are small and beautiful, but their usage scope is still limited. My thesis is that we can build small components that can be reused in many more ways than the traditional way.

To sum things up: There is little code reuse in Unix applications. Unix lacks a modern component system for building modern and consistent applications.

The filter-based component system of Unix is incomplete to address the needs of large applications.

The Bonobo Component Architecture: our solution for creating reusable Software ICs.

Bonobo is our proposed solution to create reusable software components in Unix and keeping the spirit of "Small is beautiful". Each component will focus on implementing a complete and correct set of interfaces and features. We

We have chosen CORBA as the foundation for our component architecture. CORBA has a number of interesting features that we are exploiting:

  • Contract programming.
  • Location independence.
  • Language independence.
  • Scripting language support.

Lets look at them individually:

Contracts

    Contracts between components can be expressed in terms of the CORBA Interface Definition Language (CORBA IDL).

    When a service is implemented, the functionality of the service is exposed through this contract in the form of a CORBA IDL. These contracts are called interfaces in CORBA-speak.

    Lets use an example that would mimic a block device driver in an operating system:

    	  	  interface BlockDevice {
    	  		  typedef char Buffer [512];
    
    	  		  void init ();
    
    	  		  void seek (in long block);
    	  		  Buffer read (void);
    	  		  void write (in Block block);
    	  	  };
    

    The interface is pretty simple: a seek method requests the device to go to a specific block, the read method is used to load the data from the current block and write is used to write a block to the current location.

    The interesting part here is that completely different objects can implement the above interface: a tape drive, a hard drive, a frame buffer and a regular file.

    A user that holds a reference to an object implementing the above "BlockDevice" interface does not need to care about the implementation details. And different implementations of the above interface can exist that are completely different.

    Think of CORBA interfaces as the software equivalents of hardware interfaces: for instance, you know that you can attach any of parallel printer into your parallel port because they speak the same protocol and use the same interface. You know you can attach a SCSI hard drive into a SCSI bus because they are compatible.

    This is the same thing CORBA interfaces provides us.

Location independence

    CORBA objects are usually shipped in packages: a package might be a shared library, a separate process or a remote process. For example, a file called "evolution-mail.so" might contain implementations for various evolution related mail objects, and a process called "evolution-calendar" can contain multiple objects that are related for calendar handling in the Evolution mail client.

    CORBA objects can live anywhere and your application does not need to know where they are located, nor where they came from. The Bonobo/CORBA runtime takes care of this part.

    CORBA objects might reside in the same address space, in a separate process on the same computer, or it might reside in a different computer.

    Depending on the needs of your application and your component you will choose to implement your CORBA objects in one of the above different kind of scenarios.

Language independence

    As you might have noticed, the IDL definition of the example above did not contain any implementation details. The IDL just specifies the contract that your object will implement.

    Code invoking methods on a CORBA interface as well as the code that implements the CORBA interfaces can be written in pretty much any programming language. The CORBA standard includes specifications for how a programmer might access a CORBA object or implement a CORBA server/object.

    You can pick pretty much any programming language and use it to invoke CORBA methods or implement a CORBA server. These are typically referred as "CORBA bindings".

    In GNOME we use ORBit for our C bindings. Owen Taylor has written a CORBA implementation for Perl using ORBit, and bindings for Python and C++ also exist.

Bonobo is a component architecture built on top of CORBA. Bonobo consists of a set of CORBA interfaces.

The Bonobo component model defines a set of interfaces that we use through the system. These are the major categories of Bonobo interfaces in Bonobo:

  • Bonobo::Unknown and the Bonobo life cycle management.
  • Bonobo component core interfaces: object persistence, structured storage and monikers
  • Compound document interfaces.
  • Control interfaces.
  • User interface element interfaces.

The Core of Bonobo.

The base interface in Bonobo is called Bonobo::Unknown, and it is the base interface for most of the interfaces used in other pieces in Bonobo.

Bonobo::Unknown is a very simple interface:

		interface Unknown {
			
			Unknown query_interface (in repoid);
			void ref();
			void unref();
		}

This interface is used to manage the life-cycle of an object through reference counting the object and to discover features available in a running object.

Bonobo makes use of the object activation facilities in GNOME for launching and activating components in your system.

There are multiple ways of activating a component:

  • Activating a specific component implementation. Each component is assigned a unique ID that is used to identify the component. Users can launch the component by requesting the run time to activate this object.
  • By letting the Bonobo runtime use factory objects. The runtime takes care of creating new instances of components by using factory components. These components have a unique ID just like instances of components, but they support the Bonobo::GenericFactory interface, which is an interface that can return new instances on demand. It is equivalent to the "new" method in a class in C++.

    Factory components would typically register themselves with the system's name service and hence become the factory for objects of this given type for any application that requires them.

  • By using a moniker for the component.

    Monikers provide a way of activating an instance of an object that might have a complex setup operation and might require a multi-object process for instantiating the object.

    For example, you can activate an object that lives inside a compound document by resolving all the steps that lead to that object.

    You could talk to the "Color" interface of a font that is used in an equation that is embedded in a gnumeric spreadsheet, like this:

			demo.gnumeric!Sheet 1!Equation 1!3:x^2

This object would be resolved against the "Color" interface.

Currently the implementation we have of monikers in Bonobo is sub-optimal, and this is mostly due to a mistake of mine.

I was browsing through the Microsoft documentation for Monikers and kept thinking `Man, these people certainly implemented this in the most complex way they could think of'. It took me a few months to realize why the complexity was there and what were the usage scenarios where it made sense.

But I wont bore you with the details. Suffice it to say that we are revisiting the Moniker interfaces.

There are other facilities in the core of Bonobo that are used to expose in a standard form properties of objects ("Color", "Font", "Orientation"), these are similar to the Delphi properties.

Object persistence and compound object persistent interfaces exist to address common usage patters of component systems as well. Interfaces like `Object, please save all of your state in this stream' or `Object, I know you have been a bad boy, please restore your state from this Stream interface I am handing to you'.

The Visible Bonobo

But Bonobo is a lot more than just a bunch of abstract computer science crap. The Bonobo system also contains functionality to handle the visual side of component-based applications: embedding components in application windows and creating and printing compound documents.

Bonobo does this through a series of visual embedding interfaces, called the control interfaces. So, for example, Bonobo makes it possible for you to:

  • Embed an image in an application.
  • Insert spreadsheet data into a word processing document.
  • Insert a web browsing component into any application.

This may sound really simple, but it leads to something really interesting. Because of the universal nature of Bonobo interfaces, an application needs almost no specific data about the component it is embedding. This results in incredible application-level flexibility, which means real things for users.

For example, Evolution uses Bonobo component embedding to allow you to apply arbitrary pluggable views to your mail data. You can view your mail normally using the folder display component, as a calendar using the calendar display component, or as a set of contacts using the contact display component.

Using the calendar component, you can trace the chronology of your discussions ("Oh, Bob took three days to respond to that first mail, and then Jim jumped in and send 26 mails in 3 hours"). Using the contacts component, you can view a list of the people participating in a given discussion group. And of course, you can view your mail normally, like a pine user.

Lots of interesting possibilities out when you combine simple, universal interfaces with modular code.

Another important advantage of Bonobo's visual embedding capabilities is that it helps us avoid writing monolithic applications. In the past, if you wanted to write a full-featured document editor, that meant that, in addition to core text-editing facilities, you had to implement a rudimentary image editor, an equation editor, a table-building tool, and many other small features that some portion of the user population demands.

With Bonobo, each of the ancillary components only needs to be written once, and then all container applications can use them. If you have an embeddable equation editor component, then it can be used by the word processor, the spreadsheet, the diagram designer, Evolution, the presentation program, the DTP application, you name it. Each of these applications will be slimmer, more modular, and easier to implement. Hackers will be free to focus on what actually matters about their application, since more code will be reused.

Furthermore, this will actually lower the barrier of entry for hacking on an application project. It's not reasonable to ask a weekend hacker to learn the ins and outs of millions of lines of code before he can make a contribution to an application. But he won't mind skimming a couple thousand lines of code to learn how the image viewer component works. It's much easier for someone to start contributing to a small codebase than a big one. That is our goal: many small componentized projects, working together to create a unified, complete desktop experience.

There is more information about Bonobo available in my introductory article to Bonobo.


System Services

The Unix Tradition

Configuring a Unix system traditionally has involved editing a system file, typically on /etc and saving the file. Then either the various programs and processes on the system pick up the changes, or you have to notify the daemons that require to be informed of this change.

This is not really an ideal situation, because those files are easily corrupted by human error. And depending on the tool, you need a different way of editing the file.

For example, consider /etc/passwd, to edit this file you need to use the vipw command, which will do some basic checking on the integrity of the file before you save it (as well as locking), but there are no equivalent commands to "lock", edit, and verify other system files.

So depending on each tool, a user/administrator needs to:

  1. Read the man page, and figure out what the correct procedure is for a specific piece to be edited. This is obviously not always documented.
  2. Edit the file.
  3. Now, depending on the kind of file you edited, you need to figure out how to notify the proper service that a change has happened.
  4. Depending on the service, either hope that the settings are properly reloaded, or that some error is going to creep in, or that something will be said in some of the system logs.
  5. For the system logs case, examine /etc/syslog.conf to locate the place where error messages are logged. Then make sure you tail -f the file, restart the service, scan for errors.
  6. Hopefully you do not have a busy web server, or the error is going to be lost in the noise (or hopefully you edited /etc/syslog.conf, restarted syslog)

Let's look at some examples of Unix beauty:

    /etc/inittab: use telinit q to reload settings.

    Error handling of human errors is sad, as found on the man page that comes with my Red Hat 6.1:

    "If init finds that it is continuously re-spawning an entry more than 10 times in 2 minutes, it will assume that there is an error in the command string, generate an error message on the system console, and refuse to re-spawn this entry until either 5 minutes has elapsed or it receives a signal. This prevents it from eating up system resources when someone makes a typographical error in the /etc/inittab file or the program for the entry is removed."

    I see this and I can only think "sad".

    /etc/group: Changes are loaded automatically by the system. Just pray for the file to not have errors or things are going to start to behave funny.

    Some testing and some ls-ing in /home is a good strategy to find if things are not too odd.

    Pathetic again.

    httpd.conf: Depending on your system, you can use any of the following commands:

    1. killall -HUP httpd
    2. kill -HUP `cat /var/run/httpd.pid`
    3. Find the PID of httpd yourself, kill -HUP each process.

    Using GNOME and CORBA to address the system configuration problem.

    Here is the plan. This has not been implemented, but we believe this approach is sane enough and good enough that we can address the above problem, and at the same time provide a nicer

    We want to make UNIX system services be available through CORBA interfaces that can be accessed at any time.

    For example, the user administration subsystem we could have sample code that looks like this:

    	add_guest_user (void)
    	{
    		User user;
    		uid_t uid;
    
    		user = System_Admin_Users_add ("guest", -1, -1,
                                                   "Guest user", "/home/guest",
                                                   "/bin/bash", &ev);
    		if (ev._major != CORBA_NO_EXCEPTION){
    			if (error_is (ev, ex_System_Admin_Users_name_exists){
    				error ("User already exists");
    			if (error_is (ev, ex_System_Admin_Users_invalid_shell){
    				error ("Invalid shell");
    			error ("default error handler");
    		}
    
    		uid = System_Admin_User_get_uid (user, &ev);
    		...
    
    		System_Admin_User_set_password (user, "PowChickaPowWow", &ev);
    
    		printf ("User guest was added, and its uid is: %d\n", uid);
    	}
    

For example, this interface snippet shows a possible option for the printer subsystem:

	module System {
		interface PrinterQueue {
			JobList get_job_list (void);
	
			void    pause_job    (in JobID id);
			void    abort_job    (in JobID id);
			void    resume_job   (in JobID id);

			void    submit_file  (in string file);
			void    submit_input (in Stream stream);

			PrinterStatus get_status ();
			string get_status_as_string (in string locale);
			...			
		}

		interface PrinterQueues {
			PrinterQueueList get_list_of_queues ();
			void add_printer_queue (in QueueDefinition queue);
			...
		}
	}

Another snippet, this one for configuring your local mail delivery agent:

	
	module System {
		module MailDeliveryAgent {
			interface Relay {
				void enable_relay ();
				void disable_relay ();
				void add_relay_host (in string host_match);
				void remove_relay_host (in string host_match);
				RelayList get_relay_list ();
				...
			}

			interface Config {
				void set_masquerade (in string domain);
				void set_use_mailhub (in string mail_hub);
				...
			}
			...
		}
	}

A name server:

	module System {
		module DNS_Server {
			interface Domain {
				void set_timeout (in long timeout);
				void get_timeout ();
				...
			}

			interface DomainHandler {
				Domain get_domain (in string domainname);
				Domain add_domain (in string domainname);
				void   remove_domain (in string domainname);
				...
			}
			...
		}
	}

And so on. These are just examples, and we obviously want to have these supported on the long run.

These can be deployed in multiple steps:

  1. Getting existing system services to start adopting CORBA interfaces and activation features.
  2. Making new applications support CORBA interfaces that would enable other applications.

Configuring your System

At Helix Code we are developing some tools that will simplify system administration in various ways for end users. We are working on the "Helix Setup Tools" and these tools will incorporate the ideas mentioned before.

These tools were developed under various constraints and we tried to come up with a good mix:

  1. The tools will operate with existing systems. They will parse, manipulate and in-place edit the same files that the system uses. We will not super-impose a new configuration system on top of the existing system.
  2. Simplicity: The tools should be targeted to end users. It is more important to simplify things for the sake of an end-user than adding support for the most advanced features.
  3. Given constraint (1) we know that power users will always be empowered because they can use the shell and do things on their own.
  4. Each Setup tool is actually split in two pieces: a backend which is typically implemented in Perl, and a front-end.
  5. Each one of these tools is licensed under the terms of the GNU GPL.

The backend of each one of these tools is responsible for detecting the operating system or distribution, loading values, editing the files as changes are requested by the front-end and exposing a CORBA interface to manipulate these values.

Each backend in turn can dump its state in XML format and can restore the system state from an XML file. The restoration will do an in-place editing of your system configuration settings.

We chose Perl for the backend as this allows Perl hackers that need not know anything about Gtk+ or GNOME or anything else to modify, extend, improve, maintain and bug fix the backends (which do actually carry out the core of the work). Perl as a backend is also attractive, as Owen Taylor's Perl bindings for CORBA are a joy to use (making CORBA aware applications is just sweet).

The front end is where all the user interface loving happens and this is typically implemented as a C program. The idea here is that we will use the same front-end for a multitude of operating systems. It will not matter what kind of Unix you are using: Linux-based distros, the BSDs, Solaris and others.

A number of interesting features are possible now:

  • Rollback, revision control: the setup manager will keep a historic log of all the changes made to the system and it is possible to roll back the configuration to a known state in the past by using a scrollbar (or some other GUI tool).

    For example, consider the energetic son in law that comes home, changes the computer setup to use his ISP, and leaves the machine in a broken state that your aunt cant fix: so we provide a slider bar that lets you rollback the configuration to the state it was N hours or N days ago.

  • Location manager: Laptop users will be able to change a number of configuration properties of the computer depending on their location.

    For instance, the default printer queue will be different depending on your actual location: if you are working at home, /dev/lp is your printer; While at the office you want to use the big Postscript printer by the Boss' office. And while you are on the computer science lab, you are stuck using that dot matrix printer.

    Same with networking options: depending on where you are located you want to use different networking setups: at home you want to use your Airport and DHCP, at the office you use a static IP and the ethernet network and while you are traveling you are using your modem.

    Either through auto-detection or through manually choosing your location on the panel, all those settings take place for you.

  • Cluster management: Once you have the above infrastructure for selectively applying configuration changes based on a root configuration, it is very simple to configure multiple hosts at the same time.

    A single host will let you manage all of your desktop computers on your local computer science lab network.

And of course, a web-based backend to the above is also possible.

Bonobos

The Bonobos are also known as the "Pigmey Chimpanzees", and they live in the Congo, but they are in danger of becoming extinct, I encourage you to visit http://www.gsu.edu/~wwwbpf/bpf/ for more information on them and in ways in which you can help save them.



Conclusion

You can help us make a change in the future of free software. Every person can make a difference, each day is a gift.

We need your help! Move move move! Lock and load! Let's go! Put the cow in the barn! Nat! I am talking to you! Leave that sheep alone!

[1] Yes, I know the correct name is "X Window System", I just like calling it more X-Windows.

[2] I remember a friend showed me what was possible with COM Automation some time ago and I thought "wow, that is neat, wonder when Unix will get that". Little did I know at the time about how they implemented automation.

Another friend told me "Unix needs COM, why do not you work on something like that", while trying to figure it out, another friend said "you do not need COM. COM Is just a system for calling procedures with pointers to pointers".