Search Results: "claus"

26 September 2009

Martin F. Krafft: Voting denied, enter pirates

This coming Sunday, Germany is voting its parliament for the next four years. I wanted to participate remotely, but they didn t let me. The letter, inviting me to order the voting forms, was sent too late. Instead of ordering and waiting for the voting forms, hoping for them to arrive back in Germany before the municipal agency stops all their work at 16:59 on Friday afternoon, I filled in the fields in a way to give my mother full authority to submit my vote. On the document, it only said that she would need a notary procuration, which she has. When my mother tried to vote in my name, they refused her: the vote has to be confidential, and proxies may only vote for disabled people, or those who cannot read. I can understand half of the motivation behind this it guards against abuse but the bottom line is that I am now unable to cast a vote. Democracy stabbed by bureaucracy. Well, democracy to the limited degree that we have it in Germany. I do not mean to criticise at this time that voting in Germany means to place trust into people you d rather not trust, but once they get majority, they can do whatever they want for four years. The specific shortcoming in our democracy on which I would like to focus is the five percent clause , which states that a party needs to reach 5% of votes before they can enter the parliament; if those 5% are not reached, all votes for the party are basically lost. I suspect that this clause is what s keeping back a lot of people from electing Germany s pirate party, which focuses on the importance of freedom in today s media-centric and interconnected world. It seems doubtful that the Piratenpartei will reach the limit this round, but given all the attention they recently received, as well as their plain cause, I would not be surprised if they did. I think it is important for people to vote the party they want, without letting the 5% limit discourage them. Anything else would be undemocratic. Let s return to the pirates: it s paramount for the government to consider freedom and related issues, and to put clueful people on the job. The Piratenpartei is the only party that approaches the issue properly, all the others are just too happy to succomb to castration of personal freedom for such lofty goals as anti-terrorism, or the containment of child pornography. I don t like terrorists, and I think child pornography is among the most horrific ways to abuse defenceless humans in irrevocable ways that I can imagine. But I also don t like losing my deodorant to airport security, cameras tracking my every move, (diletantic) censorship on the Internet, and lack of control over my own data. Time to put an end to that, and to solve problems without castrating freedom. Benjamin Franklin is credited with saying: they that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety. The Piratenpartei is probably not capable of leadership at this point, for they are young. But they can help the leading party maintain a bearing. That s what the Greens did, successfully albeit slowly, and I appreciate that the pirates are approaching the matter before it will be too late. The media have not missed a chance to try to stomp over them in recent months, but at the end of the day, after all the slander and some obvious mistakes on the side of the party, I still see a group of people prepared to fight for freedom with an open and honest approach. The run-ins with the media are hardly about content, it seems more that the Piratenpartei is simply unable to become part of the sensationalist mash which is our media-politician ensemble. And I think that s good. I appreciate a party communicating not via their PR office, but with new media, like blogs, or e-mail. I appreciate that their people maintain the personality of a human trying to do politics, not a politician trying to come across as human. If my municipality had let me vote, I would have selected the pirates. They may not make the 5% this year, but I would not let that be a reason against them. If one believes in democracy, then it s important to do it right.

2 April 2009

Marc 'Zugschlus' Haber: LV naming, UUIDs, file systems labels

In the last few weeks, I spent quite some time wondering about how to arrange the hard disk layout of my productive systems in the future. This article outlines my thoughts and would like to ask the lazyweb for comments. I try to keep my Debian servers as identically as possible, making it possible to talk non-linux persons remotely through the system without having to worry about this particular box configuration. I have been especially worrying about: On my current systems, I usually have the root file system on /dev/hda1, with /dev/hda2 being a PV which is the only PV of a VG vg0, which in turn has LVs named home, var and usr. This setup has a bunch of disadvantages. Thankfully, there is a number of possible solutions: I am pondering about a solution, but suspect that this is totally overengineered. Did I miss something? Is this a realistic solution? How do you handle this issue? Comments to this article will be open for quite a while.

1 April 2009

Stefano Zacchiroli: ocaml autoconf 1.0

1st release of ocaml-autoconf A couple of months ago, I joined an effort by Richard Jones to give a decent shape to autoconf macros for OCaml. The situation was a tad annoying before, because we had unofficial ocaml.m4 files floating around, which have diverged one from another, with unclear licensing terms, incompatible features, ecc. So we started a project on the ocamlforge to coordinate all this, injected the best we could find around, add docs, polish features, and contacted copyright owner to uniform licensing terms (to a 3-clause BSD). Yesterday we finally released ocaml-autoconf 1.0. Rich's blog post on the subject contains a nice how to to kick start your OCaml project using autotools up to automake. A brief feature overview is in order: Enjoy, and give us feedback (bug reports, feature requests, ...) using our tracker.

28 March 2009

Matthew Garrett

"Open"Solaris. Especially ironic given that there's a 2-clause BSD implementation out there already.

18 February 2009

Russell Coker: Red Hat, Microsoft, and Virtualisation Support

Red Hat has just announced a deal with MS for support of RHEL virtual machines on Windows Server and Windows virtual machines on RHEL [1]. It seems that this deal won t deliver anything before calendar H2 2009 so nothing will immediately happen - but the amount of testing to get these things working correctly is significant. Red Hat has stated that the agreements contain no patent or open source licensing components and the agreements contain no financial clauses, other than industry-standard certification/validation testing fees so it seems that there is nothing controversial in this. Of course that hasn t stopped some people from getting worked up about it. I think that this deal is a good thing. I have some clients who run CentOS and RHEL servers (that I installed and manage) as well as some Windows servers. Some of these clients have made decisions about the Windows servers that concern me (such as not using ECC RAM, RAID, or backups). It seems to me that if I was to use slightly more powerful hardware for the Linux servers I could run Windows virtual machines for those clients, manage all the backups at the block device level (without bothering the Windows sysadmins). This also has the potential to save the client some costs in terms of purchasing hardware and managing it. When this deal with MS produces some results (maybe in 6 months time) I will recommend that some of my clients convert CentOS machines to RHEL to take advantage of it. If my clients take my advice in this regard then it will result in a small increase in revenue and market share for RHEL. So Red Hat s action in this regard seems to be a good business decision for them. If my clients take my advice and allow me to use virtualisation to better protect their critical data that is on Windows servers then it will be a significant benefit for the users.

31 December 2008

Joachim Breitner: Handling explicit and implicit recusion in Haskell data

For a while I have been pondering over a problem that arises when your functionally written program has some state with cross references for example a list of users, each of which uses a number of computers, and a list of computers, each having an owner. Implicit referencing For doing queries on such data, it would be convenient if every reference is just the referenced object itself. Although we would visualize this as a graph, semantically, it is more like an infinite tree. This is possible in Haskell, due to laziness, and if you create the data structure cleverly, it even uses constant memory, no matter how deep you enter this infinite tree (a recent post of mine talks about this). A possible data definition would be:
data User = User  
userName :: String,
uses :: [Computer]

data Computer = Computer
computerName :: String,
owner :: User -- references the Users

data State = State [User] [Computer]

testState = let user = User "Conrad" [computer]
computer = Computer "Z3" user
in State [user] [computer]
Explicit referencing But such a representation is very unsuitable for updates (at least I can t think if a nice way of updating such a graph without breaking the internal cross-references) and serialization, which is a must for a HAppS based application. So what one would probably start with is this data structure:
data User = User  
userId :: Int,
userName :: String,
uses :: [Int] -- references the Computers

data Computer = Computer
computerId :: Int,
computerName :: String,
owner :: Int -- references the Users

data State = State [User] [Computer]

testState = State
[User 0 "Conrad" [1]]
[Computer 1 "Z3" 0]
I think the semantics of this are clear. Note that the referencing is currently not type-safe, but this can be provided by phantom types. Maybe I ll write more about that later. Now imaging you want to display the information about the first computer with your web application. You extract the information with let State _ cs = testState in head cs and pass that to your templating engine. But what if your template wants to display the name of the owner? It only has access to his userId. You would either need to know what information the template will ever need, extract that from the state beforehand and pass it along, or give the template access to the whole state. In that case, though, there has to be lookup-logic in your output code, which is also not nice. Woudln t it be nice if you could, in your application logic, work with the explicit references, which are easy to modify and store, but somehow turn that into the implicit referencing? Duplicated representation One way would be to have two unrelated sets of data structures, ExplicitState, ExplicitUser, ExplicitComputer, which use explicit identifiers to reference each other, and ImplicitState,... which are defined as the first representation of our state. It is then mostly trivial to write a function that converts ExplicitState to ImplicitState. The big disadvantage of this is that you have to maintain these two different hierarchies. It also means that every function on the state has to be defined twice, which often almost identical code. Clearly, this is not desirable. Annotated representation It would be more elegant if the state is stored in one data type that, controlled by a type parameter, comes in the one or the other representation. To do that, we need two types: One that contains a value, and one that contains just a reference:
newtype Id v = Id v deriving (Show, Typeable, Data)
newtype Ref v = Ref Int deriving (Show, Typeable, Data)
Then we need to adjust our data definitions, to make use of these. (I ll leave out the names, to keep the code smaller)
data User ref = User  
userId :: Int,
uses :: [ref (Computer ref)]

data Computer ref = Computer
computerId :: Int,
owner :: ref (User ref)

data State ref = State [User ref] [Computer ref]
Here we introduce a type parameter ref , which will later be either Id or Ref. Note that now a reference also states the object it is a reference for, which greatly increases type safety. Functions on these data types that don t work with the references will be polymorphic in the ref type parameter, so only need to be written once. A User Id is a complete user with all related data, while User Ref is a user with only references. And a Ref (User Ref) is reference to a user, which contains references... Not so kind kinds Did you notice the lack of a deriving clause? Our data structures have the relatively peculiar kind ((* -> *) -> *), which makes it hard for the compiler to derive instances for things like Show. But we already know that we will only use Id or Ref for the type variable, so we can use ghc s StandaloneDeriving language extension and have these instances created:
deriving instance Show (User Id)
deriving instance Show (User Ref)
deriving instance Show (Computer Id)
deriving instance Show (Computer Ref)
deriving instance Show (State Id)
deriving instance Show (State Ref)
Toggling a type parameter The next step is to write the conversion function. It will have type
unrefState :: State Ref -> State Id
For that, and for later, we need lookup functions:
unrefUserRef :: State Id -> Ref (User Ref) -> Id (User Id)
unrefUserRef (State l _) (Ref i) = Id $ fromJust $
find (\u@(User i' _) -> i == i') l
unrefComputerRef :: State Id -> Ref (Computer Ref) -> Id (Computer Id)
unrefComputerRef (State _ l) (Ref i) = Id $ fromJust $
find (\u@(Computer i' _) -> i == i') l
These expect a State (with implicit referencing) and a reference, and look up this reference. The function unrefState then looks like this:
unrefState :: State Ref -> State Id
unrefState (State us cs) =
let unrefState = State (map (unrefUser unrefState) us)
(map (unrefComp unrefState) cs)
in unrefState
where unrefUser :: State Id -> User Ref -> User Id
unrefUser s (User i refs) = User i (map (unrefComputerRef s) refs)

unrefComp :: State Id -> Computer Ref -> Computer Id
unrefComp s (Computer i ref) = Computer i (unrefUserRef s ref)
Note how we tie the knot in the let expression. This is the trick that ensures constant memory consumption, because every reference points back to the same place in memory. Satisfied already? So what do we have? We have no duplication of data types, we can write general functions, and we can resolve the explicit referencing. We can also easily write functions like unrefUser :: State Ref -> User Ref -> User Id, which transform just a part of the state. But writing unrefState is very tedious when the State becomes more complex. Each of the other unrefSomething functions are very similar, but need to be written anyways. This is unsatisfactory. What we want, is a generic function, something like
gunref :: State Ref -> a Ref -> a Id
which, given a state with explicit references, replaces all explicit references in the first argument (which could be State Ref or User Ref or anything like that) with implicit ones. This function can not exist, because we would not know anything about a and b. But maybe we can do this:
gunref :: (Data (a Id), Data (a Ref)) =>  State Ref -> a Ref -> a Id
Typeable and Data Before being able to do so, we need to derive Data for our types. We can start with
deriving instance Data (User Id)
deriving instance Data (User Ref)
deriving instance Data (Computer Id)
deriving instance Data (Computer Ref)
deriving instance Data (State Id)
deriving instance Data (State Ref
but that will complain about missing Typeable instances. Unfortunately, ghc s deriver for Typeable (even the stand-alone-one), does not handle our peculiar kind, so we need to do it by hand. With some help from quicksilver on #haskell, I got it to work:
instance Typeable1 ref => Typeable (User ref) where
typeOf _ = mkTyConApp (mkTyCon "User") [typeOf1 (undefined :: ref ())]
instance Typeable1 ref => Typeable (Computer ref) where
typeOf _ = mkTyConApp (mkTyCon "Computer") [typeOf1 (undefined :: ref ())]
instance Typeable1 ref => Typeable (State ref) where
typeOf _ = mkTyConApp (mkTyCon "State") [typeOf1 (undefined :: ref ())]
everywhere is not enough Turning to the documentation of Data.Generics, I notice with some disappointment that there is no function that is able to change a type they all seem to replace a value by another value of the same type. But the functions gfoldl and gunfold sounded like they could be used for this. Warning: What comes now is a very non-haskellish hack that subverts the type system, just to get the job done. Please read it with a healthy portion of distrust. If you know of a cleaner way of doing that, please tell me! Wrapped Data I want to do some heavy type hackery, so I need to disable haskell s type system. There is Data.Dynamic, but not even that is enough, as we need to carry a type s Data instance around as well. So let s wrap that up:
data AData where AData :: Data a => a -> AData
instance Show AData where show (AData a) = "<" ++ show (typeOf a) ++ ">"

fromADataE :: forall b. Data b => AData -> b
fromADataE (AData d) = case cast d of
Just v -> v
Nothing -> error $ "Type error, trying to convert " ++
show (typeOf d) ++ " to " ++
show (typeOf (undefined :: b)) ++ "."
There is also a function that converts an AData back to a normal type, if possible. If it s not possible, then there is a bug in our code, so we give an informative error message. AData transformers Similar to everywhere, we want to have transformers that combinable. They need to have the change to convert an arbitrary value, but also signal that they could not convert something (and this something has to be recursed into). I came up with this:
type ADataT = AData -> Maybe AData

extADT :: forall a b. (Data a, Data b) => ADataT -> (a -> b) -> ADataT
extADT at t a@(AData v) = case cast v of
Just x -> Just (AData (t x))
Nothing -> at a

doNothing :: ADataT
doNothing = const Nothing
ADataT is the type for such a transformer. doNothing will not transform anything, and extADT can be used to add any function to the list of tried transformers, in the spirit of extT. The ugly part To apply such a transformer, I want to use this function, which I ll describe in the code comments:
everywhereADT :: forall a b. (Data a, Data b) => ADataT -> a -> b

-- first check if we can transform this value already
everywhereADT f v = case f (AData v) of
-- if so, coerce it to the users requested type, which hopefully goes well
Just r -> fromADataE r
-- if not, we need to recurse into the data structure
Nothing -> recursed

-- for that, we first need to figure out the arguments to the
-- constructor. We store them in the untyped list
where args :: [AData]
(Const args) = gfoldl k z v
-- gfoldl lets us have a look at each argument. We wrap it in AData
-- and append it to the list
k (Const args) arg = Const (AData arg : args)
z start = Const []

-- We need the data constructor of the input data type. If the user did not want
-- it to be transformed, it will be the same
c = toConstr v

-- To give better error messages, we make sure that the outmost type constructor
-- of the requested type actually has the data constructor we were given. Otherwise
-- gunfold will complain in a non-helpful way
input_type = dataTypeRep (constrType c)
output_type = dataTypeRep (dataTypeOf (undefined :: b))

recursed = if input_type /= output_type
then error $ "Can not convert <" ++ show input_type ++ ">"++
" to <" ++ show output_type ++ ">."
-- the types match, so we assemble the output type, using gunfold
else snd (gunfold k' z' c)
k' :: forall b r . Data b => ([AData], b -> r) -> ([AData],r)

-- we start by reversing the input list
z' start = (reverse args,start)

-- then we call us recursively on the argument and feed the result
-- to the output constructor
k' ((AData a) : args, append) = (args, append (everywhereADT f a))

-- Used for folding (we don t need to retain the original constructor)
data Const a b = Const a
What a beast! But surprisingly, it works. Here are some examples. Note that I always have to specify the requested output type:
bool2Int :: Bool -> Int
bool2Int False = 0
bool2Int True = 1

*Main> everywhereADT (doNothing extADT bool2Int) True :: Int
1
*Main> everywhereADT (doNothing extADT bool2Int) True :: ()
*** Exception: Type error, trying to convert Int to ().
*Main> everywhereADT (doNothing extADT bool2Int) (True,False) :: (Int,Int)
(1,0)
*Main> everywhereADT (doNothing extADT bool2Int) ([True,False],True,()) :: ([Int],Int,())
([1,0],1,())
*Main> everywhereADT (doNothing extADT bool2Int) ([True,False],True,()) :: [()]
*** Exception: Can not convert to .
*Main> everywhereADT (doNothing extADT bool2Int) [True] :: [Bool]
[*** Exception: Type error, trying to convert Int to Bool.
I hope this code does not inflict too much pain on any Haskell-loving reader. I know I violated the language, but I didn t know how to do it better (at least not without using Template Haskell). I also know that this is not very good performance wide: Every single value in the input will be deconstructed, type-compared several times and re-assembled. If that is an issue, then this function should only be used for prototyping. Almost done To apply this to our state, we only need to glue it to our lookup functions from above:
gunref :: (Data (a Id), Data (a Ref)) =>  State Ref -> a Ref -> a Id
gunref s w = let unrefState = gunref' unrefState s
in gunref' unrefState w

gunref' :: (Data (a Id), Data (a Ref)) => State Id -> a Ref -> a Id
gunref' unrefState = everywhereADT unref'
where unref' = doNothing extADT
unrefUserRef unrefState extADT
unrefComputerRef unrefState
Now we have a generic unreferencer. I set the type a bit more specific than necessary, to make it safe to use (under the assumption that the list of lookup functions is complete and will not leave any Ref in the output).
*Main> testState 
State [User userId = 0, uses = [Ref 1] ] [Computer computerId = 1, owner = Ref 0 ]
*Main> gunref testState testState
State [User userId = 0, uses = [Id (Computer computerId = 1, owner = Id (User userId = 0,
uses = [Id (Computer computerId = 1, owner = Id (User userId = 0, uses = ..
Oh, and by the way, if you want to test this code, you ll need at least:
 -# LANGUAGE DeriveDataTypeable, FlexibleInstances, GADTs,
FlexibleContexts, StandaloneDeriving, ScopedTypeVariables #-

28 December 2008

Theodore Ts'o: Debian, Philosophy, and People

Given the recent brouhaha in Debian, and General Resolution regarding Lenny s Release policy as it relates to Firmware and Debian s Social Contract, which has led to the resignation of Manoj Srivastava from the position of Secretary for the Debian Project, I m reminded of the following passage from Gordon Dickson s Tactics of Mistakes (part of Dickson s Childe Cycle, in which he tells the story of the rise of the Dorsai):
No, said Cletus. I m trying to explain to you why I d never make an Exotic. In your calmness in the face of possible torture and the need to kill yourself, you were showing a particular form of ruthlessness. It was ruthlessness toward yourself but that s only the back side of the coin. You Exotics are essentially ruthless toward all men, because you re philosophers, and by and large, philosophers are ruthless people. Cletus! Mondar shook his head. Do you realize what you re saying? Of course, said Cletus, quietly. And you realize it as well as I do. The immediate teaching of philosophers may be gentle, but the theory behind their teaching is without compunction and that s why so much bloodshed and misery has always attended the paths of their followers, who claim to live by those teachings. More blood s been spilled by the militant adherents of prophets of change than by any other group of people down through the history of man.
The conflict between idealism and pragmatism is a very old one in the Free and Open Source Software Movement. At one end of the spectrum stands Richard Stallman, who has never compromised on issues regarding his vision of Software Freedom. Standing at various distances from this idealistic pole are various members of the Open Source Community. For example, in the mid-1990 s, I used to give presentations about Linux using Microsoft Powerpoint. There were those in the audience that would give me grief about using a non-free program such as MS Powerpoint, but my response was that I saw no difference between driving a car which had non-free firmware and using a non-free slide presentation program. I would prefer to use free office suite, but at the time, nothing approached the usability of Powerpoint, and while dual-booting into Windows was a pain, I could do a better job using Powerpoint than other tools, and I refused to handcap myself just to salve the sensibilities of those who felt very strongly about Free Software and who viewed the use of all non-Free Software as an ultimate evil that must be stamped out at all costs. It is the notion of Free Software as a philosophy, with no compromises, which has been the source of many of the disputes inside Debian. Consider, if you will, the first clause of the Debian Social Contract:
Debian will remain 100% free We provide the guidelines that we use to determine if a work is free in the document entitled The Debian Free Software Guidelines. We promise that the Debian system and all its components will be free according to these guidelines. We will support people who create or use both free and non-free works on Debian. We will never make the system require the use of a non-free component.
This clause has in it no room for compromise. Note the use of words such as 100% free and never make the system require the use of a non-free component (emphasis mine). In addition, the Debian Social Contract tends to be interpreted by Computer Programmers, who view such imperatives as constraints that must never be violated, under any circumstances. Unfortunately, the real world is rarely so cut-and-dried. Even the most basic injunctions, such as Thou shalt not kill have exceptions. Few people might agree with claims made by the U.S. Republican Party that the war in Iraq qualified as a Just War as defined by Thomas Aquinas, but rather more people might agree that the July 20, 1944 plot to assassinate Hitler would be considered justifiable. And most people would probably agree most of the actions undertaken by the Allied Soldiers on World War II battlefields that involved killing other soldiers would be considered a valid exception to the moral (and for those in the Judeo-Christian tradition, biblical) injunction, Thou shalt not kill . As another example, consider the novel and musical Les Mis rables, by Victor Hugo. One of the key themes of this story is whether or not Thou shalt not steal is an absolute or not. Ultimately, the police inspector Javert, who lived his whole life asserting that law (untempered by mercy, or any other human considerations) was more important than all else, drowns himself in the Seine when he realizes that his life s fundamental organizing principle was at odds with what was ultimately the Right Thing To Do. So if even the sixth and eighth commandments admit to exceptions, why is it that some Debian developers approach the first clause of the Debian Social Contract with a take-no-prisoners, no-exceptions policy? Especially given the fourth clause of the Debian Social contract:
Our priorities are our users and free software We will be guided by the needs of our users and the free software community. We will place their interests first in our priorities. We will support the needs of our users for operation in many different kinds of computing environments. We will not object to non-free works that are intended to be used on Debian systems, or attempt to charge a fee to people who create or use such works. We will allow others to create distributions containing both the Debian system and other works, without any fee from us. In furtherance of these goals, we will provide an integrated system of high-quality materials with no legal restrictions that would prevent such uses of the system.
This clause does not have the same sort of absolutist words as the first clause, so many Debian Developers have held that the needs of the users is defined by 100% free software . Others have not agreed with this interpretation but regardless of how needs of the users should be interpreted, the fact of the matter is, injuctions such as Thou shalt not kill are just as absolute and yet in the real world, we recognize that there are exceptions to such absolutes, apparently unyielding claims on our behavior. I personally believe that 100% free software is a wonderful aspirational goal, but in particular with regards to standards documents and firmware, there are other considerations that should be taken into account. People of good will may disagree about what those exceptions should be, but I think one thing that we should consider as even higher priority and with a greater claim on how we behave is the needs of our users and fellow developers as people. For those who claim Christianity as their religious tradition, Jesus once stated,
Thou shalt love the Lord thy God with all thy heart, and with all thy soul, and with all thy mind. This is the first and great commandment. And the second is like unto it: Thou shalt love thy neighbour as thyself. On these two commandments hang all the law and the prophets.
Even for those who do not claim Christianity as their religious tradition, most moral and ethical frameworks have some variant on the Golden Rule: Do unto others as you would have them do unto you . I would consider, for example, that the Golden Rule is at least a high priority claim on my behavior as the notion of free speech, and in many cases, it would be a higher priority claim. The recent controversy surrounding Josselin Mouette was started precisely because Joss has taken a something which is a good thing, namely Free Speech, and relegated it to a principle more important than all else, and claiming that any restraint on such a notion was equivalent to censorship. I think the same thing is true for free software, although it is a subtler trap. Philosophical claims than 100% free software as most important consideration is dangerously close to treating Free Software as the Object of Ultimate Concern or in religious terms, idolotry. For those who are religious, it s clear why this is a bad thing; for those who aren t if you are unwilling to worship a supernatural being, you may want to very carefully consider whether you are willing to take a philosophical construct and raise it to a position of commanding your highest allegiance to all else, including how you treat other people. Ultimately, I consider people to be more important than computers, hardware or software. So over time, while I may have had some disagreements with how Mark Shuttleworth has run Canonical Software and Ubuntu (but hey, he s the multimillionaire, and I m not), I have to give him props for Ubuntu s Code of Conduct. If Debian Developer took the some kind of Code of Conduct at least as seriously as the Social Contract, I think interactions between Debian Developers would be far more efficient, and in the end the project would be far more successful. This may, however, require lessening the importance of philosophical constructs such as Free Speech and Free Software, and perhaps becoming more pragmatic and more considerate towards one another.

15 September 2008

Miriam Ruiz: Is freedom only about software licenses?

A couple of years ago Debian had to change the name of Firefox to Iceweasel because Mozilla Corp. was using their trademark to impose conditions on the software that were not restricted by the license. Now the problem is brought again to life for Ubuntu, with Mozilla forcing them to show an EULA before letting users start Firefox. Jeff Licquia explains the situation quite well, in any case. At first glance, having to add an EULA seems a small price to pay, but underneath the obvious there might be something really serious happening. Software licenses seems to be just one of the possible ways of restricting users’ freedom. We’ve already seen some companies trying to use different methods to restrict it: via software patents, tivoization, etc. It seems we might want to add the usage of trademarks to the list. According to the Free Software Definition, there are four types of freedom that users need to have to consider a program as Free Software: In any case, nowhere is said that those freedoms must be given just to end users. Distributions and such must also have these freedoms, including the freedom to modify the program and adapt it to their needs, and their users’ needs. While it makes sense that you cannot call a program Firefox just because it includes 10 lines from its source code, it also doesn’t seem tolerable to try to use trademark to prevent you from adapting the program to your needs and keep calling it free. Is it valid that an organization or company tries to restrict that freedom for you by using their trademark rights? Should a clause preventing that be added to GPL4? In any case, the final reason for the discussion seems to be much ado about nothing, as the EULA does not, and cannot, add any restriction to the usage of the program. First freedom (to run the program, for any purpose), remember?

Sylvain Le Gall: Distributing OCaml libraries: common problems for packager and how upstream author can help solving it

Having already done some Debian packages of OCaml libraries, I wish to share my experience on what are the most common problems. The intent is to help people releasing OCaml libraries to have a good interaction with (Debian) packager. I think most of the tips should also apply to other distributions as well. I consider the use of findlib mandatory for this task as described in the Debian OCaml packaging policy. Problems listed here are common, and I have encountered them for my libraries... In fact, most of the time when I finished building a personnal OCaml library I package it for my own and to test that everything is fine. Being a packager and an upstream author is really a different job. "Upstream author" is used for people developing and releasing OCaml libraries and "packager" for people doing packages for a distribution. Here is the list of the most common problems and their solutions:


Libraries are linked statically in OCaml. It is an advantage and a problem. But upstream author should remember that the LGPL license doesn't support static link directly. If you link an executable with the library statically, the executable is contaminated by the license. This error is probably the most problematic, because it requires to go through the whole project fixing license header for explaining that there is an exception to the LGPL.
There is no way for a packager to fix this problem. Packager are not allowed to change the license. Library having this problem can be still packaged but complicate the legal aspect of building application using this library.
Good example of this can be found in OCaml LICENSE itself :
As a special exception to the GNU Library General Public License, you
may link, statically or dynamically, a "work that uses the Library"
with a publicly distributed version of the Library to produce an
executable file containing portions of the Library, and distribute
that executable file under terms of your choice, without any of the
additional requirements listed in clause 6 of the GNU Library General
Public License.  By "a publicly distributed version of the Library",
we mean either the unmodified Library as distributed by INRIA, or a
modified version of the Library that is distributed under the
conditions defined in clause 2 of the GNU Library General Public
License.  This exception does not however invalidate any other reasons
why the executable file might be covered by the GNU Library General
Public License.
Followed by the text of the LGPL. Each file header looks like:
This file is distributed under the terms of the GNU Library General
Public License, with the special exception on linking described in 
file ../LICENSE.
By far this is the most common error I have seen. Upstream author consider that you are able to build a native and byte version of their library. Unfortunately this is not the case for most architectures. This error is pretty simple to fix by separating byte and opt targets in Makefile. The ultimate test is to rename /usr/bin/ocamlopt and /usr/bin/ocamlopt.opt to something different and try to rebuild the library from scratch. META file is the base of everything in findlib. This is very important to provide good META file because it helps other people to easily build thing over OCaml library. Each library should provide its own META file. Until now, Debian packager was used to write this missing META file and contribute it to upstream author. I think that now findlib has become a standard in OCaml developement, so upstream should take into consideration this file. A good test for META file is to install it and:
~$ ocaml
        Objective Caml version 3.10.1
# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;      to load a package
  #list;;                   to list the available packages
  #camlp4o;;                to load camlp4 (standard syntax)
  #camlp4r;;                to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();;         to force that packages will be reloaded
  #thread;;                 to enable threads
- : unit = ()
# #require "ZZZ";;
If you are able to load your library in ocaml toplevel, this is a good point. ocamlfind allow to install library. Using it is the best way to install your ocaml library. Moreovoer, you should use the most simple way to install. For pure OCaml library this is straightforward and allow Debian packager to override destination directory by using environment variable OCAMLFIND_DESTDIR.
install:
      ocamlfind install toto META toto.mli toto.cmi toto.cmxa toto.cma toto.cmx
For non-pure library, you could add a OCAMLFINDFLAGS variable to allow Debian packager add "-ldconf ignore":
install:
      ocamlfind install $(OCAMLFINDFLAGS) toto META toto.mli toto.cmi toto.cmxa toto.cma toto.cmx
".mli" files is the human-readable interface to the library. Even if most OCaml programmers use the ocamldoc HTML API of the library, it is best to distribute these files. In particular, Debian packager use it to automatically generate up-to-date HTML API documentation directly. ".cmx" files contain more informations than ".cmxa". Distributing these files allow application based on the library to be more optimized. This one comes from my "Windows experiment". Most of the time upstream author doesn't forget about "*.a" but doesn't add "*.lib" (yes is this windows counterpart of ".a" file). This one is not very OCaml specific. In Makefile and sh you have the same wildcard "*.mli". But if the wildcard is not expanded into sh, it just stay as is. It will make the executable called looked for a file "*.mli" literally. Mixing Makefile wildcard and sh is the best option here:
install:
     ocamlfind install $(OCAMLFINDFLAGS) toto META $(wildcard *.mli *.cmi toto.cmxa toto.cma *.cmx)
This way you test and expand to only existing files. This is more or less a problem. In fact, if everything is fine, there is no problem and you should just forget about this point. If the custom build system is complex and if there is an error in it: it becomes a big problem. I must confess that I have myself done this kind of mistake a lot of time. But looking back, I think that most of the time I should have used directly OCamlMakefile. I think relying on ocamlfind for library installation, simple Makefile, OCamlMakefile, OMake or ocamlbuild, is just enough. This point is a problem for upstream author and communication with packagers (from Debian and other distributions). A bug tracking system is a way to publish, comment, work on and find solution of bugs. If you have a single problem in a library having the bug public helps people to show you what is wrong. Of course, Debian (and Fedora, FreeBSD...) has its own bug tracking system and upstream author can use it directly. This is less work for upstream but tends to make the bug "distribution specific". Having an upstream author BTS helps to track the bug across distributions. If upstream author doesn't like maintaining their own BTS, he/she should consider hosting part of the project on a forge like OCamlCore.org. Even if they don't host the source code, this is still a good idea. That's all. If you have other common problems, feel free to comment, i will add it to the list.

4 September 2008

Daniel Baumann: Re: Debian not complying to licenses

Alexander Reichle-Schmehl has replied to my blog post about Debian not complying to licenses. Dear Alexander, Debian is still not complying to licenses. And please don't cite me without the necessary context, thanks. First, debian-cd (and also debimg) must contain the sources for syslinux, not to fulfil the GPL, but to fulfil the Debian policy. Read what I wrote here and here. Second, even if debian-cd would go for source distribution under GPL clause 3b), both the current debian-cd version available in unstable (version 3.0.4) and current svn head (revision 1686, dated 2008-09-04) do not contain a written offer to obtain the sources for the embedded syslinux binary and are therefore, still, violating the GNU General Public License.

16 April 2008

Russell Coker: Motivation and Perspective

Patrick Winnertz writes about the demotivating effect of unreasonable delays on joining the Debian project [1]. While I agree that things need to be improved in terms of getting people in the project in a timely manner (the suggestion of providing assistants seems good), I don’t think that anyone has a good reason for being demotivated because of this. I first applied to join Debian in late 1998 or some time in 1999. At the time part of the process of joining was to receive a phone call. At the time I was living in a hotel and they refused to call me on such a line. I could have easily camped out in the hallway of a hotel (the cheap London hotels often had a pay-phone in the hall and no phones in the rooms) and pretended that it was my own phone with an unlisted number. Unless they refused to allow people with unlisted numbers to join (which seems unlikely) then I could have joined then. So it seems that at the time I could only join Debian if I was prepared to lie about my ownership of a phone line. I wasn’t overly bothered by this - there has never been a shortage of free software projects that need contributions of code. By late 2000 the rules had changed and I joined without needing a phone call. In the mean time I had forked the Bonnie storage benchmark program to form my own project Bonnie++ [2], created Postal - mail server benchmark suite [3] and worked on many other things as well. I have sympathy for the people who apply to become Debian Developers and who have to wait a long time, I’ve been in the same situation myself. But there are plenty of things that you can do in the mean time. Some of the things that you can do are upstream development work, filing bug reports, submiting patches that fix bugs, and writing documentation (all forms including blog posts). Also when projects aren’t yet in Debian it often happens that someone creates unofficial packages, the person who does this doesn’t need to be a DD. Producing back-ported packages for new versions of programs that are in a stable release can also be done by people who are not DDs. Unofficial and back-ported packages provide less benefit for the project as a whole but considerable benefit for the people who want to use them. There is a lot of work that can be done to fulfill clause 4 of the Debian Social Contract [4] (Our priorities are our users and free software) which doesn’t require being a Debian developer. It seems to me that if you have the right approach to this and maintain the perspective that Debian is one part of the free software community (and not necessarily the biggest or most significant) then a delay in your application to become a DD won’t be particularly demotivating.

8 April 2008

Erich Schubert: Licensing software

If you are writing free software, choose your license appropriately. This can make a big difference with respect to adoption of your software.I'll just show you an excerpt from a Debian changelog:
* DFSG version of Mono 1.9
  + Deleted the mcs/class/System.Web.Extensions/ directory as
    mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JSON/*.cs
    is licensed under Creative Commons Attribution 2.5 which is not
    DFSG-free.
Debian policy doesn't allow us to include Creative Commons Attribution 2.5 in the main Debian archive, since that license doesn't meet the Debian Free Software Guidelines, which are part of our social contract. Therefore we must and will remove such code.debian-legal summary for "main" Creative Commons licensesCreative Commons is aware of these issues:
Creative Commons recommends and uses free and open source licenses for software.
And then they suggest to use GPL. While there is a link in the right side menu to the Creative Commons page on licensing Software, they IMHO don't make this obvious enough. Their license chooser should include a central link "if you intend to license software, read this".Creative Commons even includes "wrappers" for common licenses: CC GPL, CC LGPL, CC BSDSo if you like Creative Commons because of this pretty "commons deed" human-understandable version of the license they offer, just use these wrappers. The "legal code" links will actually take you to the GNU or Opensource.org license pages.I'm not aware of a good reason to use an opensource license other than GPL, LGPL or 3-clause BSD, depending on how you want to allow your opensource code to be used in combination with non-free software. If you are contributing to a bigger project, choosing the same license as the main project is although a very good idea.

4 April 2008

Bdale Garbee: sdcc and git

I've been using git for a while, like it a lot, and finally decided it's time to move all my Debian packaging work over from CVS. After a frustrating few hours trying, I gave up on trying to use git-cvsimport. It generates mangled repositories even for simple packages like sudo. The git-import-dsc tool in the git-buildpackage package works fine as far it goes, but I'd really like to preserve my history. So, after some consultation on IRC, I took a look at parsecvs. It didn't quite work out of the box, either, but looks promising, and the author showed an immediate interest in the problems I'm having and offered to help. So, perhaps I'll be able to use it before long... In the meantime, a while back I offered to help Gudjon I. Gudjonsson restructure the sdcc packages so that a DFSG compliant version can return to main with a full version under a different package name going in non-free. This is all necessary because some of the assemblers provided in the package have a non-commercial use clause in the license, and there are also license issues with the HTML documentation. I care about this because sdcc is a build dependency for gnuradio, which I maintain for Debian (it uses the 8051 toolchain to build downloadable code for the USRP, etc). While waiting for parsecvs to get some love and attention, I sat down this evening to restructure sdcc and move it to git. I'm pretty happy with my progress so far, though there's a bit left to do before uploads happen. Gudjon and I decided to use the collab-maint facilities on alioth.debian.org for collaboration, which took me a little head-scratching to figure out, but looks like a perfect fit for our needs. I updated the wiki page about Git on Alioth with a few of my learnings as I went through the process. Using git branching to handle non-DFSG-compliant upstream sources is pretty obvious, the notes in the git-buildpackage documentation helped. Using pristine-tar to capture the deltas required to regenerate orig.tar.gz files from the git repo is amazingly cool. It's hard to believe how much friendlier the world seems when you don't have to drag a bunch of tarballs around with you to do useful work! And git-buildpackage has suitable options to make using it pretty automatic. Great stuff! It's likely to be a few days before I can get back to this, finish up, and upload the results of this restructuring work. In the meantime, I'm writing this entry largely to offer my compliments to everyone involved in making git-buildpackage, alioth, and collab-maint work so well. Special thanks to Joey Hess, whose pristine-tar package is another in a long line of absolutely brilliant tools that contribute to making my life easier! I'm going to end up using it a lot.

21 March 2008

Vincent Fourmond: Improvements for the machine-readable debian/copyright emacs mode

Since the last post, I have significantly improved debian-mr-copyright-mode, that now provides an interactive function, debian-mr-copyright-scan-files that shows which files are covered by which clause of the debian/copyright file. I've also significantly improved my understanding of font lock and emacs lisp in general... As a demonstration, the attached picture represents the results of debian-mr-copyright-scan-files on the monsterz source package (Sam's original example). The output clearly shows that some files are not covered yet... You can get the emacs mode there. Its is starting to be good, but of course, many more improvements are still planned - in particular, quotes for files probably don't work yet. By the way, imenu now works. A debian package should probably come soon.

19 February 2008

John Goerzen: Registrar Dynadot Conspires to Help Take Down Wikileaks?

Yesterday, Wired ran a story on the Cayman Islands bank that got Wikileaks.org blocked. This story said, in part:

When the bank's lawyers indicated they would be filing a suit, she asked them to tell her where so that Wikileaks could find an attorney in the appropriate jurisdiction to represent it. She says the lawyers refused to tell her. Two and a half weeks later, the bank filed a restraining order against Dynadot and Wikileaks in San Francisco. Wikileaks received notice only a few hours before the case went to a judge who accepted the agreement between Dynadot and the bank.


(emphasis mine)

Now, Dynadot and this Cayman Islands bank apparently had an agreement to block wikileaks.org already. Not only did Dynadot effectively take wikileaks.org down, but also they "lock(ed) the wikileaks.org domain name to prevent transfer of the domain name to a different domain registrar." The U.S. Disctrict Court for Northern California issued this injunction without ever giving Wikileaks a chance to respond. The bank only filed the request against Dynadot. Apparently Wikileaks received notification that this was going to happen only 6 hours before the hearing (an incredibly short time in legal terms), nowhere near enough time to prepare a case.

Now, the reason I post this is because I have looked at Dynadot as a registrar before. They have good prices and a whois privacy service that makes sense: where you remain the owner of record, making it easier if you need to transfer the domain or prove your ownership of it.

But before signing up, I read their AUP carefully. Among many alarming things, I noticed this paragraph:

You further agree that Dynadot, in its sole discretion and without liability to You for any resulting loss or damages, may take immediate corrective action, including, but not limited to, removal of all or a portion of Your domain services and/or deletion, suspension, cancellation, termination, or other interruption of domain services or Your customer account with Dynadot, at any time during the term of this Agreement, in the event of notice of any possible violation of this Agreement by You or Your end users, or if such service or account is used in association with morally objectionable activities, or for any reason whatsoever. In such cases, any and all fees paid to Dynadot will be non-refundable and ineligible for account credit.


So, I thought I would write to them about it. Here is an excerpt from their response:

We always conduct an investigation before taking action against a domain. We will give you a chance to respond to the complaints.


From Wired's story, it doesn't look like that really happened. The US Government has already issued advisories about Cayman Islands banks, and it is unclear (to me at least) what law Wikileaks broke, or how Dynadot could find their actions of exposing fraud "morally objectionable". What's more, collaborating with the bank to get a takedown order written, but not talking to Wikileaks, seems to go against their statements to me (assuming again that the Wired story is accurate).
Here is my entire mail. You may also find archive.org's copy of the AUP from last July to be helpful. (I wrote the email in November, and they've added some sections since then, so the section numbers don't necessarily match up)

Subject: Re: SITE: Questions about your AUP
From: Dynadot Info <info@dynadot.com>
Date: Sat, 3 Nov 2007 13:42 -0800
To: jgoerzen@complete.org

Hello,
Thank you for your email. Responses are below.
Best Regards,
Dynadot Staff
--------------------------------------------------
DYNADOT... $8.99 domain names... $1/mo. web hosting
http://www.dynadot.com
Hi,
I currently have several domains being hosted with Gandi.  I have long been looking for someone that can provide a level of privacy for my whois data in a sane way.  I think Dynadot is the first I've seen that looks like it can do that and still be affordable.
In preparation to transfer over a first test domain, I read your AUP and frankly am quite troubled by what I saw.  I hope that you can allay my fears.
In section 4 of part 2, the last paragraph states that Dynadot "for any reason whatsoever" may delete, cancel, or terminate my domain services or customer account.  It also lists "notice of possible violation" as a justification for that.  That makes me even more nervous -- any random person could send you an email claiming something nefarious is happing with my domain name, and I'm agreeing to just let you delete it because of that?

We always conduct an investigation before taking action against a domain. We will give you a chance to respond to the complaints. 
A very similar clause appears in section 7 of part 1 ("cancellation of services").  It goes on to cast a very broad net around objectionable material and says that Dynadot decides what's objectionable.  Now, if you go to my website at www.complete.org or blog at changelog.complete.org, you'll see I'm an upstanding netizen.  But the AUP says that things that "are designed to or effectively... embarrass" third parties could get my domain cancelled.  So if I post a review of Vista that says I think Microsoft did a poor job of engineering, would my account be yanked if one of their engineers complained?  What if I (legally!) linked to a Comedy Central sketch using real TV footage to mock George W. Bush or Hillary Clinton?

The cases you described above would never happen with us. Complaining about Microsoft or making fun of George Bush are protected free speech. The service agreement is designed to give us some flexibility in dealing with customers that break the law. 
I'm particularly concerned about this because apparently DynaDot felt it worthwhile to try to take down the website of someone that found a security hole: http://www.jhuskisson.com/friends/dynadot-fights-back-bans-nick-from-everything
While I wouldn't condone step-by-step cracking instructions in most cases, this is concerning to me.

He was posting a step by step guide to hacking our website, which is illegal. The hack did not work, but we noticed an upsurge in strange activity in our logs, so we requested the hacking guide be taken down. 
Finally, item (i) under the Domain Privacy Service section says that you could immediately reveal all my information upon the receipt of merely a *claim* (not even a court order), even if it's invalid.  But I thought that NOT doing this was what you were saying made your service better, over at http://www.dynadot.com/resource/article/qa.html?aid=0

Once again we need to build some flexibility into our service agreement to deal with people who use their domains for criminal activity. Otherwise we could be liable for the damages that they cause to others. So far, we have never dropped anyones privacy except in the few cases we were forced to by a FBI subpoena.
I know this is a long message, and I appreciate your time.  I really do want to use your service, but -- no offense intended -- I want to make sure I'm not dealing with scammers first, and from reading the AUP, I'm not so sure!

No offence taken. I will email our counsel to see if we can tighten up the agreement a bit. 
-- John Goerzen

17 February 2008

Russell Coker: Laptop vs Book Weight

Matt Bottrell wrote an interesting and informative post about laptops for school kids [1]. His conclusion is that based on technical features the OLPC machine is best suited for primary school children and one of the ASUS EeePC, the Intel Classmate, and the Everex Cloudbook would be best suited for high-school students. The Asus EeePC [2] is a good option, it runs a variant of Debian and the Debian Eeepc Team are active in getting full Debian support for it [3]. The Intel Classmate [4] has a choice of Windows XP, Mandriva, and Metasys Classmate. The web page says that it’s designed “for primary students (ages 5-14)“, so I think that Matt made a mistake in listing this as a possibility for high-schools, of course when running Mandriva it could have software installed for any age group but the hardware design may be better suited to younger children. The Everex Cloudbook [5] runs the GOS Rocket [6] OS which seems to be an Ubuntu variant with an Enlightenment based GUI and a configuration aimed at using Google services (blogger, gmail, etc). Configuring Ubuntu to suit your needs is easy enough (it’s based on Debian). Note that Matt did not mention where one might purchase a Cloudbook in Australia and I don’t recall seeing one on any of my many window-shopping expeditions to Australian consumer electronics stores, while the EeePC is widely available (except when sold out). But I’m sure that if the government wanted to place an order for a couple of million units then Everex would ramp up production quickly enough. Matt made one statement that I strongly disagree with, he wrote “A traditional notebook is far too heavy for high-school kids to lug around“. To test this theory I searched for some high-school text books and a set of scales. A year 11 Maths A text book from ~1988 weighed 600g and the pair of year 12 Maths A and Maths B texts weighed 1.6Kg. When I was at high-school the day was divided into seven “periods”, some classes took two periods so four different classes which required text books (or other books) was typical. Carrying 3Kg of books to school would not be uncommon for year 12 students. The Lenovo T series (advertised as “premier performance” and the model I personally prefer) is listed as having a starting weight of 2.1Kg (which presumably doesn’t include the power pack). My Thinkpad T series (from about 2004) weighs about 2.4Kg according to my kitchen scales and has a battery weighing just over 400g. My practice for a long time was to own a spare power pack for my Thinkpad so that I could leave it at work (saving 400g when travelling to and from work). I have also had the practice of buying a spare battery when I buy a Thinkpad (you need a spare battery for a long trip). So if I had really wanted to save weight I could have left a battery at work and reduced by travel weight by another 400g (with the cost being that I couldn’t use it when on a train or bus). A spare power pack is not overly expensive. In the usual case students would only need a battery when at school (it’s a little known fact that Thinkpads work perfectly without a battery plugged in). So if a student had a power pack at home as well as one at school and if they left their battery at school and they owned one of the latest Thinkpad T series (listed with a starting weight of 2.1Kg) then their travel weight might be about 1.7Kg. If the majority of school texts could be stored on their laptop then the result of using a Thinkpad T series would be a significant weight reduction! If the students were using a Thinkpad X series (more expensive so maybe not a good option) then the list weight is 1.57Kg and the travel weight might be as low as 1.3Kg (at a rough estimate). The EeePC offers significant benefits for school use, it is light, cheap (children tend to break or lose things more frequently than adults so you should budget for buying two of anything that they use), and having no hard drive (flash storage) it should cope well with being dropped. The screen on the EeePC is unreasonably small buy Asus could release a new model with a bigger screen (they may do this in the future anyway or a government contract could encourage them to do it sooner). I agree that the EeePC or the Everex Cloudbook is probably the best option for high-school students, but I can’t agree with any claim about a traditional laptop being too heavy, the only reason for excluding a traditional laptop is that those new ultra-lights are better. Another reason that might be cited for not using laptops is the cost. While prices of $1000 or more for a traditional laptop are rather expensive, the $500 for an EeePC is not that expensive - and the government could surely negotiate a better deal, I would be surprised if they couldn’t get the price down to $350 by some bargaining and by removing the middle-man. A careful child could use the same laptop for the entire duration of high-school and their parents would incur less expense than they currently would spend on text books. As for the current lack of electronic text books. Currently when the education department selects a book it’s a license to print money for the author and publisher. All that the education department has to do is to declare that they will do a deal with the first company to release their books under a creative commons license. The idea would be that an author (or publishing company) would get paid a fixed sum of money for a CC release of a text book which would then be available for use by anyone anywhere in the world. World-wide free distribution would be no loss to the author (each country tends to have unique books anyway) but would be a good act of charity from our government to developing countries. Once books were available under a creative commons license (without the “no modifications” clause) they could be freely improved by anyone. Improving text books for younger students could be a good school project. Update: Thanks to Steve Walsh for pointing out that the Classmate can run Linux. It’s a pity that he didn’t link to my post so that his readers could see what he was referring to. I take it as a good sign of the quality of my posts that such small errors get pointed out.

15 February 2008

Stefano Zacchiroli: XQuery and XSLT 2.0 with Debian

XQuery 1.0 and XSLT 2.0: news and how to use them in Debian (long post about the second generation of the XSL family and how to use the related languages in Debian)
The 2nd generation of the XSL family At the beginning of 2007, W3C released a family of interrelated specification: XPath 2.0, XSLT 2.0, XQuery (1.0). The 3 specifications are based on the very same underlying data model which (finally!) supports typed values and exploits them to some extent, for example permitting some form of static type checking in XPath and XQuery. Types usually come from XML Schema, with both built-in and user-defined types supported. A brief overview of the 3 specifications and what they change in the state of the art follows. XPath 2.0 XPath 2.0 basically consists in XPath 1.0 + 3 new macro features. The first one is a revamp of those language features which are dealing with types, in order to better integrate them with the new typed data model. XPath now has operators to check whether a value belongs to a given type (so yes, type information are kept at run time), and to cast them from one type to another. The basic new type constructor is now the sequence, which replaces the old node-set solving many annoying issues, such as the impossibility of having a node ordering other than document order. The second feature is the improvement of standard library of functions which was ridiculously small in XPath 1.0; it is much better now. Additionally, 2nd generation languages (XSLT 2.0 and XQuery) now support the ability to define functions which will then be visible to inner (XPath) expressions, pushing yet forward the possibilities of plain old XPath. Functions can now also declare types in their signatures (for their arguments and return value) and untyped arguments will be automatically casted to them upon invocation. Hence, even if you are not using an implementation which assigns types to your XML trees, once you "enter" the typed world calling a typed function (almost all standard library functions are decently typed) you will be able to stay there avoiding annoying casts everywhere. Finally XPath 2.0 has turned into a powerful purely functional language and is now powered by constructs like conditionals, for-each loops, existential/universal quantifiers, and existentially-quantified comparison operators for sequences. Here is a complex expression to hwet your appetite (or scare you away ...), comments come as (: smiley faces :)
for $book in /bookshelf//books
return
  if ((every $author in $book/authors/author
       satisfies $author/nativeLang eq "it_IT")
      and $book/lang eq "it_IT")
  then $book
  else ()
(: think about the trouble of writing this in XSLT/XPath 1.0 ... :)

XSLT 2.0 XSLT 2.0 is what I would call a "bug fix release" of XSLT 1.0 + the routinary reworking of the language to deal with typed values, which is not sensibly different than what has been done for XPath 2.0. The fixed "bugs" are several, starting from the annoying issue of result tree fragments. They are basically tree snippets that in XSLT 1.0 you were able to generate for future use. Unfortunately they were not thaaat reusable, given that you were not even able to navigate them with XPath operators! Now the specification is much more clear and distinguishes final result trees from ordinary variables, which can now contain sequences of (navigable) tree nodes. Another important "bug" fixed is the new ability to output multiple documents with a single XSLT stylesheet: it marks the end of stupid extra post processing to be added in pipeline to a XSLT processor. Other minor "bugs" fixed are a limited amount of backtracking capabilities among imported templates, regular expression support directly in the language, and powerful grouping constructs on the lines of SQL's GROUP BY (but much more powerful). Here is a template snippet exploiting the latter feature:
<xsl:for-each-group select="*" group-starting-with="h1">
  <div>
    <xsl:apply-templates select="current-group()" />
  </div>
<xsl:for-each-group>

XQuery XQuery is the end of the chains imposed by XML-based syntaxes. Why the heck one has to use an XML syntax (as in the above snippet) only because she is manipulating XML tress is one of the mysteries of XML technologies which have always been floating around in my head. XQuery is the (supposedly) SQL equivalent for databases of XML documents, but is actually much more than that. I depict it in my head as the XML manipulation language with a syntax I can finally stand. Technically it is XPath 2.0 (say 80% of the whole language) + some extra ingredients (say 20%); so remember that every XPath 2.0 expression is also a XQuery expression. The main extra ingredient is the so called FLWOR expression (to be read: "flower expression", which in addition to the "smiley faces" used for comments gives a "back to 1968"-flavour to the language .... erm FLWOR/flower/flavour, no pun intended). A FLWOR expression is very similar to SQL's SELECT-FROM-WHERE: it lets you generate a tuple stream by iterating on sequences (F: for clauses), binding expression values to names (L: let clauses), filter out tuples which do not satisfy a required condition (W: where clause), order the survived tuples (O: order by clause), and finally return a sequence built using the residual tuple stream (R: return clause). The other interesting extra ingredient is the ability to build the XML snippets you want to manipulate. Within XQuery you do that using plain XML syntax (the only place where a sane-minded programmer actually wants to see it!) which also supports a classical interpolation mechanism to embed expressions which will be evaluated inside XML snippets, and also the other way around. A canonical XQuery example is:
for $t in doc("books.xml")//title,
    $e in doc("reviews.xml")//entry
where $t = $e/title
return <review>  $t, $e/remarks  </review>
(: braces denote the escaping context where XQuery expressions will
   be evaluated inside snippets; plain XML syntax is used for the
   other way around :)

But remember: XQuery for XML is much more than SQL for RDBMS, thanks to the implicit templating mechanism implemented by interpolation, and thanks to several language features fostering modularity (user-defined functions, library modules, XPath 2.0 standard library, ...) you can basically do with it any kind of XML manipulation you can imagine. I don't think I will ever write myself any other single line of XML output in DOM or XSLT ...
Cool, how can I use it in Debian? ... if only this stuff were decently supported in the open source world. Last time I checked, the author of most parts of the GNOME toolchain for dealing with XML (libxml2, libxslt, ...) was not intentioned to implement XSLT 2.0, not even mentioning XQuery. This comes as no surprise, the whole GNOME XML toolkit is written in C, and XSLT 2.0 / XQuery have reached a level of complexity and formal specification which usually entails a higher level approach. So on the GNOME side we are stuck. The other open source implementations of XSLT 2.0 / XQuery I'm aware of are Saxon and Galax. Saxon is an XSLT 2.0 and XQuery implementation written in Java, which is unfortunate per se. Additionally, it is also unfortunate that it is only partially open source. Indeed, Saxon is split into SaxonB (for "basic") which is open source under the Mozilla Public License and SaxonSA which is commercial. While SaxonSA is a fully conformant, XML Schema-aware processor, with support for static typing, SaxonB is a basic-conformant processor with no type-aware features and actually much less optimized than SaxonSA. This is annoying. (Much more annoying is the fact that SaxonSA's author is the only editor of the XSLT 2.0 specification and that instead of his mail address the specification includes an URL pointing to the website selling SaxonSA ...) Galax is an open source (IBM CPL / Lucent license) OCaml implementation of XQuery which is not fully conformant to the specification (though it gets quite close) which is type-aware and implements static typing. The only XQuery / XSLT 2.0 implementation available in Debian at the time of writing is SaxonB. The binary package is libsaxonb-java, kudos to Michael Koch and the Debian Java Maintainers for having packaged it (and to have stood some annoying pings of mine :-) bug #408842). To execute XQuery code you just have to aptitude install libsaxonb-java, prepare a query.xq file containing your query, and then execute something like:
CLASSPATH=/usr/share/java/saxonb.jar \
java net.sf.saxon.Query query.xq

note that the information in README.Debian are still referring to old Saxon versions, see bug #465894 which proposes a more up to date README.Debian. Similarly, to perform a XSLT 2.0 transformation you have to do something like:
CLASSPATH=/usr/share/java/saxonb.jar \
java net.sf.saxon.Transform -ext:off -s:input.xml -xsl:style.xsl -o:output.xml

Do not remove the -ext:off flag when processing untrusted stylesheets!, see bug #465885 for the reason. I've written some handier (1-liner) shell script helpers which remove the need of invoking java manually. They are attached to bug #465894 and I've proposed their addition to the saxonb package. Using them the above invocations become:
saxonb-xquery query.xq
saxonb-xslt -ext:off -s:input.xml -xsl:style.xsl -o:output.xml

Galax in Debian ... well, since long time I've been planning to package it (the ITP has been filed some months ago: bug #447984) and the authors sent me a newer version than what is available online to gather feedback before the long overdue final release. Unfortunately I've been lagging behind in finishing the packaging (which is tricky due to the need of binding libraries to several different languages: OCaml is native, but there is also Java for example). Hopefully this post will give me some renewed motivation for finishing the work ...
References
  • Debian package w3-recs, ships the whole list of W3C Recommendations for offline consultation; it includes all the specifications we have discussed in this post
  • Saxon: home page of Saxon, a XSLT 2.0 / XQuery processor written in Java
  • Galax: home page of Galax, a XQuery processor written in OCaml
  • Debian package libsaxonb-java, ships SaxonB as a Debian package

Acknowledgements Thanks to godog for his helpful comments.
Update: the helpers I've proposed have been accepted into the official package, I've also made available their manpages. Also the pending changes to README.Debian has been accepted. Kudos again to Michael Koch for his quick feedback on my patches!

3 January 2008

MJ Ray: MSN Santa Sex Scandal

I missed this one when it happened earlier last month, but I'm still putting it on my 2007 page of Bad Technology. Thanks to a colleague for pointing it out. Apparently MSN's Santa-bot made inappropriate comments to children and was exposed in Microsoft's sex-obsessed RoboSanta spouts filth at children The Register After that, it was almost inevitable that it would be taken off-line, even if just for a short while, so I think the next headline could have been predicted:- Microsoft kills Santa Claus The Register What surprised me was the ham-fisted PR attempt described in Microsoft accuses kids of bullying Santa into sex chat The Register If it was a mistake, then admit it. How did it happen? Unruly programmers wanting easter eggs at Christmas, did someone make the Santa-bot by modifying a porno-bot, or was it a learning bot finally corrupted by all the abuse it was sent - like Arnold on UEA/tsw's #pubfood IRC? Truly bizarre.

25 December 2007

Ben Armstrong: Fr-eee-dom: roaming on the bus with wpa_supplicant

As I wrote earlier, I bought an Eee PC to use on the bus. Initially, I only used it offline to do some Debian packaging and blogging, but I soon discovered that I could do a few things online on the many open networks on my daily commute. While the connections are normally brief in good traffic conditions, even a few seconds here and there is enough to participate in irc discussions. Manually connecting to each got old very quickly. So, to automate those connections I settled on wpa_supplicant, (wpasupplicant is the Debian package name,) which is quite easy to set up in roaming mode, as outlined in /usr/share/doc/wpasupplicant/README.modes.gz. All you need is the following in /etc/network/interfaces:
allow-hotplug ath0
iface ath0 inet manual
        wpa-driver wext
        wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
Then create your wpa_supplicant.conf as follows:
ctrl_interface=/var/run/wpa_supplicant
network= 
     key_mgmt=NONE
 
That’s it. You can now roam from one open network to the next and the supplicant will connect you to each one in turn. I have used this to reconnect to my screen session each time the bus slows down for a stop or gets stuck in traffic to carry on conversations on irc for the whole length of the commute. If you also connect to networks requiring authentication, you’ll need to add a “network” clause for each network. See /usr/share/doc/wpasupplicant/examples/ for help with that, particularly the annotated conf file, README.wpa_supplicant.conf.gz. For finer control over the process, I use sudo wpa_cli so i can:
  • keep an eye on what networks are around: scan, then scan_results,
  • disconnect from a network once I know it’s out of range
  • and reassociate as needed.
The only things that I haven’t figured out how to do yet are to make the process of switching from one network to the next a bit faster (it normally takes about a minute; precious seconds of online time are lost when the bus is in motion,) and to blacklist certain essids, e.g. commercial hotspots that make you pay before they’ll route your packets to the Internet. For the first problem, I have already tweaked my dhcp settings, which helps a bit. For the second, I tried adding network blocks for specific networks and setting them to a lower priority, but that doesn’t work because then the ‘catch all’ open network block kicks in and picks them up anyway.

24 December 2007

Steve Kemp: I saw momma kissing santa claus

Well I've been in Devon for the past week, and will remain here for another week. During that time I've averaged about ten minutes of online time a day! So far things are going well, but it will be wierd spending time with another family over Christmas. Still I've been vaguely productive. I've released a new version of chronicle - which has the CGI support for leaving comments upon my entries. (TODO: Reinstate some previous comments for Martin Krafft) One thing I'd not anticipated was the amount of spam I'd start recieving. The peak so far was 40+ comments a day, all with random URLs. I deleted them manually for the first day - but now I've written a shell script or two to classify comments via the spamfilter I use for handling email. I'm not 100% sure I should have done that. I suspect that over time I will find better results if I actually have a distinct "blog spam" and "blog ham" corpus - rather than risk confusion over "email" and "blog" texts to classify. Still I shall wait and see. The only thing that I think I want to do now is add a bit more fine control over the comment process, so the choice is not just between comments being globally on, or globally off. A nice middle-ground where I could say "Comments enabled for entries posted within the past two weeks or so". Anyway thats my quota for today. Now I have to walk the family dog ..

Next.

Previous.