Search Results: "zed"

19 December 2007

Ian Haken: Trials and Tribulations of ARM Programming

I spent a rather long time today trying to figure out a rather obscure bug. I few months ago I bought a gp2x, an open portable gaming system (and media player, etc.). I've really enjoyed it so far. The open platform for development has lent itself it many fun apps, console emulators the most conspicuous I think, but it's also fun to experiment and develop with it. I recently ported an asteroids clone I wrote and the whole process was actually fairly simple. As such, I decided to take on a larger task of porting something like FreeCNC, which as far as I know, no one has done yet.

After some simple trouble with library version conflicts, I got the program compiling correctly. However, if wasn't reading files quite right. I spent a little while investigating and discovered the problem was in a function which essentially hashes filenames. In the end, it was this snippet of code which was giving the trouble:

char buffer[13];
...
calc = ROL(calc)+*(long *)(buffer+i)


In particular, this is trying to read 4 bytes from this character array as an integer. At first I though the trouble might be endian-ness, but both the gp2x (an ARM processor) and x86 use big-endian*. I finally resorted to running gdb and sifting through assembly level instructions.

$r2 = 0xbffffd7c
$r3 = 0x41434f4c
0x0000a310 _ZN8MIXFiles7calc_idEPc+52>: str r3, [r2]


Here, the register $r2 points to buffer and $r3 is the value we're trying to save into the buffer. After this we would expect
*0xbffffd7c = 0x41434f4c
but instead see
*0xbffffd7c = 0x08db9841.
If I purposely set *0xbffffd7c = 0xffffffff and repeat this instruction we see
*0xbffffd7c = 0xffffff41.

Clearly the problem lies in this single str instruction, and was resident to the ARM architecture. So of course it was time to go to the processor documentation. Reading the fine print finally reveals what I was looking for.
A word store (STR) should generate a word aligned address. The word presented to the data bus is not affected if the address is not word aligned. That is, bit 31 of the register being stored always appears on data bus output 31.
Yep, since the buffer was an odd-sized array and stored on the stack, it started on an odd number in memory. Hence its address was not word aligned, and so as per the documentation, the store did not have the expected result. Here's a short program which shows what I'm talking about.

x86ARM
buf=BFBF3471, buf%4=1
Num: 4C4F4341
Buf+0: 4C4F4341
Buf+1: 4C4F4341
Buf+2: 4C4F4341
Buf+3: 4C4F4341
buf=BFFFFD75, buf%4=1
Num: 4C4F4341
Buf+0: 4F434100
Buf+1: 43410000
Buf+2: 41000000
Buf+3: 4C4F4341

Perhaps the lesson to learn here is that when casting pointers, it's buyer-beware, and there are safer bitwise manipulations to use, though certainly less efficient.


*Edit: Both x86 and the ARM processor in question are little-endian, not big-endian. Typo on my part, but notwithstanding the point is that they both had the same endian-ness, so it wasn't where the issue lay.

David Welton: Android Task List / Selector

Credit for finding out how to do this goes to dims, who has been doing lots of cool Android hacking lately: http://davanum.wordpress.com/2007/12/18/android-task-manager-primitive-prototype/ If you're interested in Android and what it can do, you should be following his online journal! As a way to keep pushing and testing Hecl, I decided to see if I could copy what he'd done in Hecl. It has indeed produced a few improvements to the Java code. That done, making it work was short and sweet:
set layoutparams [linearlayoutparams -new  FILL_PARENT WRAP_CONTENT 
set layout [linearlayout -new $context]
$layout setorientation VERTICAL
# Create ourselves some commands to access Android internals.
java android.app.ActivityManagerNative activitymanagernative
java android.app.IActivityManager iactivitymanager
java  android.app.IActivityManager$TaskInfo  taskinfo
java android.content.ComponentName componentname
java java.util.List javalist
set am [activitymanagernative getdefault]
set tasks [$am gettasks 10 0 [null]]
set len [$tasks size]
set tasklist [list]
for  set i 0   < $i $len   incr $i   
    set baseactivity [[$tasks get $i] -field baseactivity]
    lappend $tasklist "Task: [$baseactivity getpackagename]"
 
$layout addview [textview -new $context -layoutparams $layoutparams \
         -text "Currently running tasks"]
set lview [basiclist $context $tasklist -layoutparams $layoutparams]
$layout addview $lview
$lview requestfocus
set callback [callback -new [list [list SelectTask]]]
$lview setonitemclicklistener $callback
heclcmd setcontentview $layout
proc SelectTask  parent view position id   
    [activitymanagernative getdefault] movetasktofront $position
 
It could have been squeezed further by avoiding some of the temporary variables, and perhaps also by implementing a mapping between java.util.List and Hecl lists. I think one of the next things I want to do is work on some infrastructure so that people will be able to actually work on scripts on their phone. That's sort of a departure from the past (most phone keyboards would be sheer torture for inputting long scripts), but it's a cool demo in any case.

17 December 2007

John Goerzen: Everything Update

It's been an interesting week. For those of you that haven't been following along: we lost power Tuesday and have been without ever since.

Yesterday was the annual Christmas party at work. About an hour away, supposed to be there at 6. So at 2:30 I went outside to see if I could get the car out past all the snow. At first, YES! But then, halfway down the driveway... well, no. Our driveway needs help. It's actually lower than the fields around it. Thankfully it's on a hill so it doesn't flood, but it does drift shut when there's snow. So the car got stuck. I dug it out, and it got stuck again. And a third time.

I eventually called my dad to see if he'd be willing to come over with his tractor and open up our driveway. He said yes, and drove the 5 miles in his tractor -- which has no cab, and it was below freezing -- and got the driveway open, and helped me get the car unstuck. We had planned to leave at 4, to give us time to get Jacob to the babysitter. We didn't think a babysitter would enjoy spending the evening at a cold house with only a generator providing power, so we were taking him to their place. Well, we left about 4:30.

We got down our driveway, onto the road, and hey -- more drifts. Yay. Got out onto the highway, over to the road to their place. Which someone, ahem, had assured me was a paved road. But instead we got 5 miles on a very drifty east-west country road. That's the deepest snow I've ever put a car through, and I am still surprised that we didn't get stuck anywhere.

So then we dropped off Jacob, and off to the party, and squeaked in just a few minutes late. Phew. It was nice to be out of the house, too.

When we picked up Jacob later -- taking the non-drifty route -- he was sleeping, of course. I carried him out to the car and put him in his seat. There's nothing quite like carrying a sleeping boy snuggled into you to make you forget the lack of electricity outside.

Today we went to church. Church was canceled last Sunday, and the Wednesday evening activities were too. So I think everybody made an effort to be there today. All sorts of electricity stories were heard. Generators moved around the countryside as those that owned them got power and loaned them out to those that didn't have power. The president of a nearby college called the church and offered two rooms at his personal residence to anyone that needed them. One woman announced during sharing time that her husband was taken to the hospital on Friday. They determined that he needed heart surgery, and that will happen tomorrow... and she added that she'd be with him for a couple of days, so if anyone needed a warm house for a family, theirs was available and had a couple of bedrooms, fridge, and garage that people were welcome to use.

At noon there was a free lunch offered to anyone still without power. We went and enjoyed some warm soup and bread with about 30 others.

After that, we went to my parents' place to do some laundry, then came home.

We ate supper. As Terah got up to give Jacob some more chili, I suggested that she look out the window and see if any yard lights were on yet. I had flipped our master breaker off, just to be extra cautious due to having wired our furnace into the generator temporarily. So this is how we would tell that power was back on somewhere (though we did check it periodically during the day). Terah looked out the window, and said, "I DO see yard lights out there... Do you think?" I got up, went downstairs, flipped the breaker, and light came on! We turned on the lights -- Jacob had missed them -- and plugged in the Christmas tree. The power had come on for people miles in either direction from us at the same time. Dad came over to get our electrical box back to normal state and to help me load up the generator to return tomorrow.

There's nothing quite like this to make us feel fortunate to be a part of such a caring community of friends and family -- people who don't think twice about helping out someone in need, even in the midst of having a husband hospitalized.

Jacob didn't seem to mind the power outage. Except for one thing. He is very excited about lights these days. I can spend 15 to 30 minutes exploring lights with him, especially in the kitchen. He will point at a light and say "da?" ("that"). "Da? Da?" means he wants it turned on or off. We'll go to the light switch, and he'll get to flip it, or watch while I do. "Dooooo!" is his excited response.

Well, when he wants something and it's not happening fast enough for him, "Da? Da?" changes to "Da!... Da!..." and then to "DA!! DA!!" and finally some fussing. That happened several times as we couldn't turn on lights.

Then we got to church this morning and boy was he excited. Lights everywhere! He'd point to one bright light and say "Da!" -- look at the light over there, dad! Point to another place and "Da!" Another one over here! And ceiling fans! Lights everywhere! He was so excited he was trying to jump up and down.

Jacob's favorite new word is "hi." He has just barely figured out how to say it, and it takes effort, and comes out very breathy -- but it's there. He can spend several minutes saying hi to someone over and over if he's in the right mood. He wouldn't say hi to the greeters at church, or anyone that said hi to him. But we were sitting in the back row, and halfway through the sermon, he started saying hi to the ushers that were behind us. I couldn't see them very well, but I imagine they were trying to keep from cracking up.

Frans Pop: aptitude upload not something to be proud of

Sometimes it is extremely tempting to wave a huge, heavy, spiked cluebat around. Today I've decided to give in to this temptation. The case in point is the upload today by their maintainer of first cwidget and later aptitude. The fact that the maintainer blogged about both uploads probably means that he's pretty happy about it. Unfortunately I, and people in the Debian release team, were less than amused. Reason is that the uploads set back a complex transition of apt and related packages by at least a week. This is a transition we'd already been following and trying to get into testing for over a month and which was finally as good as ready to go. So what was so wrong about these uploads and what could (should?) the maintainer have done? First of all he should have realized that aptitude has become a rather central package in Debian with strong ties to apt and thus to a lot of other packages. Second, he should have checked whether his previous uploads had already migrated to testing and, if not, why not. The excellent testing migration page for aptitude (which is linked from its PTS page clearly shows that it is tied in a transition involving about a 100 packages in total. The right thing to do in such a case is to contact the release team (preferably at the debian-release mailing list, or at #debian-release). This would undoubtedly have resulted in a request to delay the uploads a few days until the transition had finished. Unfortunately that did not happen and cwidget was uploaded. Because of an ABI bump it ended up in NEW. Because of the transition I did a quick request to Joerg Jaspert to please delay accepting cwidget until the transition was over. But then a third mistake, and arguably the most serious one of the lot, was made. aptitude was uploaded for i386, built against the cwidget library which had not yet been accepted into unstable. Basically that means that an uninstallable package was uploaded. And of course it meant that at that point all efforts to finalize the transition for apt went down the drain. Some alternatives were discussed on how to deal with the new situation, including a sourcefull upload of the previous version of aptitude, but in the end it was decided to just accept the delay as one of the more annoying facts of life and instead ask Joerg to accept cwidget from NEW. In the end the damage may be a bit less than a week if the buildds cooperate (which they probably won't with cwidget still stuck at the wrong priority) and the RMs decide to force things. I sincerely hope that this story will make all Debian Developers and Debian Maintainers a bit more aware of the broader context and consequences of uploads. Oh, as I'm not an RM myself you may wonder what my interest is in this. We've got this great new feature in Debian Installer that adds support for multiple CDs during an installation (a feature that was lost with the integration of base-installer into D-I). However, we can only upload the relevant D-I component after apt 0.7.9 has reached testing...

15 December 2007

David Welton: Free Software Beer Network

I've actually had this idea floating around in my head for a while. Recently, I mentioned it on a Debian list, where it was well received. Since I don't think I'll be able to implement it any time soon, let me just throw it out there: One of the cool things about belonging to a group like Debian or the Apache Software Foundation, or other similar groups is that there are people all over the world that are often willing to meet if you're in their area. Wouldn't it be cool to have a centralized resource where you could post something like "hey, I'm going to be in Paris/Perth/Padova/Philadelphia/Porto Alegre/Pretoria, anyone want to get together for a beer or whatever people drink there?". You'd have to balance it some - make it too generic and it loses some of the appeal - part of the appeal about meeting someone from a group you belong to is that you instantly have something to talk about. Extend that too far and it would just be like meeting random people on Facebook. I don't have the time or inclination to pursue the creation of such a site, but it would be quite simple, I believe. And of course, if anyone is headed to Innsbruck, I'm always happy to go out for a beer!

Joerg Jaspert: Using a SSH jumphost

As Tolimar was asking about it and I am using the setup at some places to get past idiotic^Wbroken firewalls, where you always want to kill the clueless people that did set them up - lets write a bit how to ease ssh usage at such locations. Imagine a place where you can’t ssh elsewhere directly, you have to go through at least one, in some cases two or three hosts, to get anywhere sane.[1] So the topic is SSH jumphost. Thats basically what you do manually if you
  ssh some.host
  ssh next.host
where some.host is your jumphost. Add as many some.host as you want into this chain. We are all lazy and don’t want to type that by hand, one ssh is enough for everybody. Hurray, ssh already provides what we need, namely the ProxyCommand directive, it’s just not known as much as it should be. For this example imagine I have to ssh via the following host chain to get out: kosh -> vir -> babylon5 -> sheridan and also want to have my local port 2525 forwarded to sheridans port 25. The following config snippet (.ssh/config) is doing that[2]
 Host yay
 ProxyCommand ssh -q -A -X vir ssh -q -A -X babylon5 'nc -w1 sheridan 22'
 LocalForward 2525 localhost:25
   
 Host vir
 ProxyCommand ssh -q -A -X kosh 'nc -w1 %h %p'
The effect of this is: and I end up having a shell on host sheridan. The LocalForward line also tells ssh to tunnel my port forwarding over that multi-hop session, voila, done. Of course there is a little caveat with this - all hosts do have to know the next one (ie. .ssh/known_hosts should have the right data). You should also think about using ssh keys (maybe including Agent forwarding). You really dont want to see 5 Password: prompts right behind each other for a 5-hop setup - with no clue if its for the next host or for a typo… Update: If you are a Debian Developer and do not have a host “outside” that listens to something else than Port 22 but are behind a firewall that only allows Port 80 and 443 - you are lucky. As long as you aren’t hit by [1] you put the following into your .ssh/config file and have fun:
Host foo.gl bar.gl
ProxyCommand ssh -q -a -p 443 -x gluck.debian.org 'nc -w1 $(basename %h .gl) 22'
Add as many other config options as you want. The effect is: and as such you can get out via gluck. We are using the .gl as an extension here to remember that we go via gluck. Idea stolen from someone on IRC, just can’t remember who atm. [1] For added fun, which I have at one place, add things like a proxy with user authentication done in a way that tools like tor or openvpn can’t get through it and you always wish those admins use Windows, just so they suffer. Anyway, I talk about the first part only, using jumphost, other ways getting around crap admins needs, in my case, an own script to do it, not part of this topic… [2] Yes, one can do it in lots of ways and those here might not be the most optimized/nice/whatever ones. But they work and are just examples here, select your own parameters if you dont like mine!

14 December 2007

Joerg Jaspert: Using a SSH jumphost

As Tolimar was asking about it and I am using the setup at some places to get past idiotic^Wbroken firewalls, where you always want to kill the clueless people that did set them up - lets write a bit how to ease ssh usage at such locations. Imagine a place where you can’t ssh elsewhere directly, you have to go through at least one, in some cases two or three hosts, to get anywhere sane.[1] So the topic is SSH jumphost. Thats basically what you do manually if you
  ssh some.host
  ssh next.host
where some.host is your jumphost. Add as many some.host as you want into this chain. We are all lazy and don’t want to type that by hand, one ssh is enough for everybody. Hurray, ssh already provides what we need, namely the ProxyCommand directive, it’s just not known as much as it should be. For this example imagine I have to ssh via the following host chain to get out: kosh -> vir -> babylon5 -> sheridan and also want to have my local port 2525 forwarded to sheridans port 25. The following config snippet (.ssh/config) is doing that[2]
 Host yay
 ProxyCommand ssh -q -A -X vir ssh -q -A -X babylon5 'nc -w1 sheridan 22'
 LocalForward 2525 localhost:25
   
 Host vir
 ProxyCommand ssh -q -A -X kosh 'nc -w1 %h %p'
The effect of this is: and I end up having a shell on host sheridan. The LocalForward line also tells ssh to tunnel my port forwarding over that multi-hop session, voila, done. Of course there is a little caveat with this - all hosts do have to know the next one (ie. .ssh/known_hosts should have the right data). You should also think about using ssh keys (maybe including Agent forwarding). You really dont want to see 5 Password: prompts right behind each other for a 5-hop setup - with no clue if its for the next host or for a typo… [1] For added fun, which I have at one place, add things like a proxy with user authentication done in a way that tools like tor or openvpn can’t get through it and you always wish those admins use Windows, just so they suffer. Anyway, I talk about the first part only, using jumphost, other ways getting around crap admins needs, in my case, an own script to do it, not part of this topic… [2] Yes, one can do it in lots of ways and those here might not be the most optimized/nice/whatever ones. But they work and are just examples here, select your own parameters if you dont like mine!

13 December 2007

Raphael Geissert: HOWTO create and maintain a repository using reprepro and DeBaBaReTools

DeBaBaReTools seems to work good enough that writing an early-stage HOW TO seems to worth the time :)

The first thing to do is of course fetch the sources:
$ svn export https://neo.yahostme.com/svn/DeBaBaReTools/trunk/ DeBaBaReTools


Build and install the package:
$ cd DeBaBaReTools; dpkg-buildpackage -b; dpkg -i ../debabaretools_0.2_all.deb


$ dpkg -L debabaretools
/.
/etc
/etc/DeBaBaReTools
/etc/DeBaBaReTools/common.conf
/usr
/usr/bin
/usr/bin/wannaBuild
/usr/bin/needsBuild
/usr/bin/needsReBuild
/usr/bin/buildQueue
/usr/bin/checkSums
/usr/bin/wannaUpload
/usr/bin/processIncoming
/usr/share
/usr/share/doc
/usr/share/doc/debabaretools
/usr/share/doc/debabaretools/copyright
/usr/share/doc/debabaretools/ENV
/usr/share/doc/debabaretools/changelog.gz
/usr/share/doc/debabaretools/TODO
/usr/share/DeBaBaReTools
/usr/share/DeBaBaReTools/backends
/usr/share/DeBaBaReTools/backends/config
/usr/share/DeBaBaReTools/backends/config/reprepro.sh
/usr/share/DeBaBaReTools/backends/probe.sh
/usr/share/DeBaBaReTools/backends/fetch
/usr/share/DeBaBaReTools/backends/fetch/dget.sh
/usr/share/DeBaBaReTools/backends/verbosity.sh
/usr/share/DeBaBaReTools/backends/lock
/usr/share/DeBaBaReTools/backends/lock/default.sh
/usr/share/DeBaBaReTools/backends/setDefault.sh
/usr/share/DeBaBaReTools/backends/buildQueue
/usr/share/DeBaBaReTools/backends/buildQueue/plaintext.sh
/usr/share/DeBaBaReTools/backends/signature
/usr/share/DeBaBaReTools/backends/signature/gpgv.sh
/usr/share/DeBaBaReTools/backends/check
/usr/share/DeBaBaReTools/backends/check/default.sh
/usr/share/DeBaBaReTools/backends/build
/usr/share/DeBaBaReTools/backends/build/pbuilder.sh
/usr/share/DeBaBaReTools/backends/upload
/usr/share/DeBaBaReTools/backends/upload/dput.sh
/usr/share/DeBaBaReTools/backends/parsers
/usr/share/DeBaBaReTools/backends/parsers/default.sh
/usr/share/DeBaBaReTools/backends/repository
/usr/share/DeBaBaReTools/backends/repository/shared.sh
/usr/share/DeBaBaReTools/backends/repository/reprepro.sh
/usr/share/DeBaBaReTools/backends/misc.sh
/usr/share/DeBaBaReTools/backends/codenamesTable
/usr/share/DeBaBaReTools/backends/codenamesTable/release.sh
/usr/share/DeBaBaReTools/backends/codenamesTable/reprepro.sh
/usr/share/DeBaBaReTools/backends/config/default.sh
/usr/share/DeBaBaReTools/backends/fetch/default.sh
/usr/share/DeBaBaReTools/backends/buildQueue/default.sh
/usr/share/DeBaBaReTools/backends/signature/default.sh
/usr/share/DeBaBaReTools/backends/build/default.sh
/usr/share/DeBaBaReTools/backends/upload/default.sh
/usr/share/DeBaBaReTools/backends/repository/default.sh
/usr/share/DeBaBaReTools/backends/codenamesTable/default.sh


Now you have to create a base reprepro repository. I strongly recommend setting the REPREPRO_BASE_DIR ENV variable if possible.

A recommended repository structure is (in repoitory/):
.:
./build:
./build/cache:
./build/data:
./build/data/logs:
./build/tmp:
./conf:
distributions
incoming
options
tiffany.py
uploaders
./db:
./debian:
./debian/dists:
etch
oldstable
sarge
sid
stable
testing
unstable
./debian/dists/...
./debian/pool/...
./incoming:
./incoming/accepted:
./incoming/new:
./incoming/rejected:
./pub:
./pub/UploadQueue:

Note that the build/, incoming/ and pub/ directory structures are DeBaBaReTools' defaults, if you want to change them you will have to set some variables at the configuration file ($HOME/.DeBaBaReToolsrc).

The distributions file must at least contain the Codename, Suite and Architectures entries for DeBaBaReTools to work correctly. Note that the current code used to correlate the suites with the codenames greps for the given codename/suite including two lines before and two after the match, so the entry must be on that scope.
E.g.
$ cat conf/distributions
Codename: sid
Suite: unstable
Architectures: i386 amd64 source
Components: main contrib non-free
Uploaders: uploaders
DebIndices: Packages Release .bz2 .gz .
DscIndices: Sources Release . .gz .bz2
Contents: .bz2 .gz .
Tracking: minimal includechanges keepsources


conf/incoming must name at least one rule. This is because when installing, DeBaBaReTools will grep for all the rule names and execute them one by one.
The rest of reprepro's setup is trivial.

When building packages with pbuilder, DeBaBaReTools expects the basetgz's to be named like $PBUILDER_CACHE/$CODENAME.tgz where $PBUILDER_CACHE is an environment variable defaulting to /var/cache/pbuilder.

Tweaking DeBaBaReTools:
Because we are using reprepro and pbuilder we'll give some hints to DeBaBaReTools so it uses a reprepro-specific and/or pbuilder-specific backend where possible.

$ echo 'HINT_ALL="reprepro pbuilder"' > $HOME/.DeBaBaReToolsrc


The .DeBaBaReToolsrc file is sourced by all scripts, so you might even set variables like $REPREPRO_BASE_DIR there.

/usr/share/doc/debabaretools/ENV documents only some of the multiple environment variables that can be specified to customise DeBaBaReTools' behaviour. It is important to say that variables which are empty will be filled with a default value.

You may now want to modify .dput.cf by adding a 'local' target for your repository:
[local]
fqdn = localhost
method = local
incoming = /home/raphael/Deb/repository/pub/UploadQueue
allow_unsigned_uploads = 0
run_dinstall = 0


So let the fun begin! :)

To make sure everything is ok let's run processIncoming in verbose mode:
VERBOSE=1 processIncoming
processIncoming v0.1 started.
processIncoming v0.1 stopped.

Not getting that output means something is not ok.

All the scripts will try to source a file called $HOME/.$ APP_NAME rc, where $APP_NAME is the name of the script, e.g. processIncoming. This can be used to customise them even more.

Tweaking the scripts behaviour:

processIncoming offer some options such as:


wannaBuild:



When you should call which DeBaBaReTools script:
processIncoming takes care of accepting package uploads and installing them when told to do so.
needsBuild processes the .changes files accepted by processIncoming and tells the build queue manager that a given package needs to be built, or when the binary package is also uploaded, or is already built.
wannaBuild only takes care of building source packages (note that arch: all-onnly packages WON'T be built, they must be uploaded together with the source package).

So the workflow is:
processIncoming -> needsBuild -> INSTALL=1 processIncoming

A package won't be installed in the repository if it isn't handled before by needsBuild.

Here's a demonstration (note the usage of VERBOSE=1):
$ dput local kcometen3_1.1-1_source.changes
Checking Signature on .changes
...
Uploading to local (via local to localhost):
Successfully uploaded packages.
Not running dinstall.
sh: /usr/bin/mini-dinstall: No such file or directory
Error while executing command.
Continuing...

The package is now at pub/UploadQueue

$ VERBOSE=1 processIncoming
processIncoming v0.1 started.
Processing /home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1_source.changes...
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1.diff.gz" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1.dsc" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1_source.changes" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1.orig.tar.gz" to "/home/raphael/Deb/repository/incoming/accepted/"
processIncoming v0.1 stopped.

After checking sums and signature, the upload is accepted.

$ VERBOSE=1 needsBuild
needsBuild v0.2 started.
Architectures: i386 amd64 all
Now processing /home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1_source.changes
Adding kcometen3 to be built in i386 for the sid distribution
Adding kcometen3 to be built in amd64 for the sid distribution
mv'ing "/home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1.dsc" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1.orig.tar.gz" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1.diff.gz" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1_source.changes" to "/home/raphael/Deb/repository/incoming"
needsBuild v0.2 stopped.

The package is now marked to be built on i386 and amd64 for sid (note that distro to codename conversion is performed) and moved to incoming/ so processIncoming is able to install it.

$ VERBOSE=1 processIncoming
processIncoming v0.1 started.
processIncoming v0.1 stopped.

There's nothing under pub/UploadQueue and nothing is installed (do you remember the INSTALL=0 option? :))

$ INSTALL=1 VERBOSE=1 processIncoming
processIncoming v0.1 started.
No distribution found for 'kcometen3_1.1-1_source.changes'!
There have been errors!
No distribution found for 'kcometen3_1.1-1_source.changes'!
There have been errors!
No distribution found for 'kcometen3_1.1-1_source.changes'!
There have been errors!
making diffs between /home/raphael/Deb/repository/debian/dists/sid/main/source/Sources and /home/raphael/Deb/repository/debian/dists/sid/main/source/Sources.new:
generating diff
Exporting indices...
processIncoming v0.1 stopped.

The errors can be safely ignored, it is just that reprepro couldn't install kcometen3_1.1-1_source.changes for the specified install rule (I've one for each distro, that's why).

$ VERBOSE=1 wannaBuild
wannaBuild v0.1 started.
Fetching list of packages to be built for unstable
Fetching source package kcometen3 v1.1-1
Use of uninitialized value in string eq at /usr/bin/dget line 377.
cat: /home/raphael/Deb/repository/build/data/needsBuild.unstable: No such file or directory
Starting build backend...
Executing sudo pbuilder --update --basetgz /var/cache/pbuilder/unstable.tgz
Starting build process
Verifying signature of /home/raphael/Deb/repository/build/kcometen3jb3362/kcometen3_1.1-1_i386.changes...
gpgv: no valid OpenPGP data found.
gpgv: the signature could not be verified.
Please remember that the signature file (.sig or .asc)
should be the first file given on the command line.
Fetching list of packages to be built for testing
Fetching list of packages to be built for stable
Fetching list of packages to be built for oldstable
wannaBuild v0.1 stopped.

There are still some things that need to be fixed (e.g. the no such file or directory message).
Other than that, the output is just fine: the package wasn't automatically signed so when trying to check the signature it failed to find it thereby not uploading the package automatically.

Now we cd to build/kcometen3jb3362/, review the build log, the .changes file, and we finally sign it.
Afterwards, we upload the package and install it:

$ VERBOSE=1 processIncoming
processIncoming v0.1 started.
Processing /home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1_i386.changes...
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1_i386.changes" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/kcometen3_1.1-1_i386.deb" to "/home/raphael/Deb/repository/incoming/accepted/"
processIncoming v0.1 stopped.

$ VERBOSE=1 needsBuild
needsBuild v0.2 started.
Architectures: i386 amd64 all
Now processing /home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1_i386.changes
mv'ing "/home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1_i386.deb" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/kcometen3_1.1-1_i386.changes" to "/home/raphael/Deb/repository/incoming"
needsBuild v0.2 stopped.


$ INSTALL=1 VERBOSE=1 processIncoming
processIncoming v0.1 started.
No distribution found for 'kcometen3_1.1-1_i386.changes'!
There have been errors!
No distribution found for 'kcometen3_1.1-1_i386.changes'!
There have been errors!
No distribution found for 'kcometen3_1.1-1_i386.changes'!
There have been errors!
making diffs between /home/raphael/Deb/repository/debian/dists/sid/main/binary-i386/Packages and /home/raphael/Deb/repository/debian/dists/sid/main/binary-i386/Packages.new:
generating diff
Exporting indices...
processIncoming v0.1 stopped.


done :)

We can now setup some cronjobs:
*/10 * * * * processIncoming
*/5 * * * * needsBuild
@daily INSTALL=1 processIncoming

needsReBuild and uploadQueue still need to be written, so don't expect them to do anything right now.

I hope people start using it so I receive more feedback :D

Michael Prokop: Checklist for 1:1 clone of a Debian system

When cloning a Linux/Debian system 1:1 you should have a checklist of what’s important to change on the cloned system. For cloning I use the grml Linux Live-CD of course (the following tips are part of grml-tips as well). To create a 1:1 clone I boot grml on the systems (usually using the ssh=password bootoption to be able to access the system remotely as well) and use something like:
Listener:
# nc -vlp 30000 > /dev/sda1
Source:
# dd if=/dev/sda1 bs=$VALUE   nc -vq 0 $IP_OF_LISTENER 30000
When I have to leave the place where the clone process is running and if the CD-ROM doesn’t reinsert CDs on reboot automatically (usually that’s the case for server systems) I can use my remote-reboot procedure via ssh later on like:
eject &>/dev/null
umount -l /cdrom
eject /dev/cdrom
echo b > /proc/sysrq-trigger
But stop: before executing the last steps to reboot the server you should take care of a few important steps, otherwise rebooting might fail and you won’t be able to login via SSH. ;-) That’s my personal checklist: Tip: I highly recommend the use of a version controll system for maintaining /etc, for example etckeeper and mercurial should do the job for you.

Benjamin Mako Hill: SPARC Innovator

SPARC, the Scholarly Publishing and Academic Resources Coalition -- a large alliance of academic and research libraries and other organizations working on open access scholarly publishing issues -- just recognized me as a SPARC Innovator. The award/recognition is given semi-annually to honor contributions to the open access movement. I'm being singled out in part for my work on Overpriced Tags and for other OA work and advocacy. I'm sharing the stage with several friends -- all of whom are students active in the Free Culture movement. SPARC seems to see this set of innovator awards as an opportunity to recognize the contributions of the next generation of activists. I'm honored to be counted among them!

Gunnar Wolf: Supertheory of supereverything

First time I had read the Bible
It had stroke me as unwitty
I think it may started rumor
That the Lord ain't got no humor Put me inside SSC
Let's test superstring theory
Oh yoi yoi accelerate the protons
stir it twice and then just add me, 'cause I don't read the Bible
I don't trust disciple
Even if they're made of marble
Or Canal Street bling From the maelstrom of the knowledge
Into the labyrinth of doubt
Frozed underground ocean
melting - nuking on my mind Yes give me Everything Theory
Without Nazi uniformity
My brothers are protons
My sisters are neurons
Stir it twice, it's instant family! I don't read the Bible
I don't trust disciple
Even if they're made of marble
Or Canal Street bling My brothers are protons
My sisters are neurons
Stir it twice dlja prekrastnih dam... Do you have sex maniacs
Or schizophrenics
Or astrophysicists in your family
Was my grandma anti anti
Was my grandpa bounty bounty
Hek-o-hek-o-hej-o
They ask me in embassy! 'Cause I don't read the Bible
I don't trust disciple
Even if they're made of marble
Or Canal Street bling And my grandma she was anti!
And my grandpa he was bounty!
And stir it twice
And then just add me!
Partypartypartypartypartyparty
now afterparty...
That's the Supertheory of Supereverything, by the gypsy-punk Gogol Bordello. I was really surprised to find their Super Taranta! at a local music shop. Of course, five minutes later, we were heading home with our shiny and oh-so-very-green purchase. Highly recommendable!BTW, does anybody else think that Eugene Hutz is Larry Wall's evil twin? (No, and I don't only mean it because of their choices in background colors)

12 December 2007

David Welton: Programming languages are not like hand tools

I have seen the "right tool for the job" comment one too many times, and felt like writing something about it. Real tools are pretty simple, really. Things like saws and hammers have been around for thousands of years, and don't require a great deal of thinking to understand. Some people are masters with hand tools and create wonderful works of art with them, but the tools themselves are not complex. My programming language, Hecl, is a pretty simple one in a lot of ways (it has to be, to fit on cell phones), and at last count, the core has 7670 lines in a rough count that includes comments. That entails quite a few "moving parts" compared to even something like an electric drill. Programming languages are complex. Certainly to create, but even to use well; to understand the nooks and crannies and ramifications of the language's design is not something that is accomplished in a few days for most people. Your average programmer really doesn't know all that many languages, and even those who know many probably don't use most of them on a day to day basis. I like learning new languages, yet still wouldn't relish the idea of going through the mental task-switch required to move between too many in one day. What this means, is that when there is a job to be done, most programmers will reach for what they already know, rather than the best possible system, and that makes sense. If you know Python, why not write web software in Python, if you get asked to create something for the web? Or if you know Tcl because you create gui's with Tk, you're still likely to pick it when you need to create a little server. There are reasons why something like Erlang might make for a better server platform than Tcl, but is it that much better to justify dropping everything, learning a new language, committing to a new set of infrastructure requirements, and adding another thing to ask of people joining your organization? Most likely, it is not, unless the server you're writing is for a telephony switch that has to be on all the time, in which case, yes, maybe you do need Erlang. If, as is often the case, it wasn't something that had to be the best in the world, all that extra time to learn a new language would have been mostly "wasted" (ignoring, of course, the fact that for individuals, learning new things is almost always good, but that's not what we're talking about). Even the smart folks who hack away in languages like Haskell are fond of using what it has to offer, rather than jumping ship to something else at the first hint of the "something else" being better at their language of choice for a given task. So both Tcl and Erlang were up to the task of creating a little server. You could have used Ruby or Python as well. Java might prove a bit more verbose, but it's certainly up to the task. Any number of languages would be, of course. So it's not like there is a "right tool" and a "wrong tool". Maybe a better analogy is languages are like toolboxes, or even whole workshops, full of tools. Most of them have most of the common tools like hammers and saws, some sort of web libraries or the means to create tcp/ip servers. Where they differ is in things like the amount of tools available, the specialized tools that you get for free, the craftsmanship and ease of use of the tools in the hands of both experts and beginners... or in some cases (lisp, say), some fancy tools and supplies that make it possible to build yourself some new tools if you need to (that only you know how to use, but that's another topic). Some sets of tools really aren't very good for some jobs - you don't want to build blazing fast 3-d shooter games in PHP, just as you wouldn't want to use a regular set of screwdrivers on a delicate watch. However, even though you'd want to use a toolset that also has some specialized tools for working on the watch, you'd rather own a toolbox that came with the watch tools as well as the regular Phillips screwdrivers, because those are pretty handy around the house, and it wouldn't do to have only the watch tools for fixing common household items. The point being, languages are big investments, so those that do more, even if they're not the absolute greatest or first choice for a given task, are generally going to be more useful to more people, especially those just starting out who want a "safe" choice, a language they know will let them do a variety of things, rather than only one or two things (pound nails, say) really well.

Pierre Habouzit: NM: FD is fixed

Following Lucas[1] post about NM, I used his data to create the following two nice graphs[2]. Both are the normalized datas of average count of people waiting for Front Desk, the DAM or their account. The first one does that on a 90 samples window (roughly 3 months) and the second one on a 180 samples one (roughly 6 months). 3 months smoothing 6 months smoothing This kind of smoothing actually eliminates high frequencies, hence we see what a usual behavior each step has. What is clear to me is that FD situation is clearly fixed for quite a long time. FD was definitely an issue one year ago, but it has been really really fixed: for more than a year, even on the 6-months smoothing graph that has quite a long memory, the average queue is around 3 people, I can't see how it could even be reasonably improved. Of course, given that the Keyring step is just after the DAM, and that people at those steps works in batches, the data is a bit biased, though it gives a pretty good idea of the bottlenecks of the whole process.
Notes [1] I'm a lazy bum, and don't have the energy to find the proper link to it [2] gnuplot is a real horror, isn't there any kind of GUI for that ?

11 December 2007

John Goerzen: It's Cold Outside

A day or two ago, I got the feeling that winter has set in. Maybe you know the feeling.

I looked outside the bedroom window. The trees had a bit of white all over. The tall grass in the distance had a sheen of gray on it. The sky was a uniform gray. Small ice pellets hit at our window. As far as the eye could see, not a sign of anything that wasn't frozen.

As I stood in our warm 68-degree house, I was reminded of how little separates us from the frozen outdoors. A few inches of wood and insulation is all. How easy it is to fret about the rapidly rising cost of propane these days, the cost of heating a house. But still, how easy we have it compared to the people that came before in this house.

They had to keep a fire going for warmth, keep a ready supply of firewood for the winter, figure a way to get the warmth throughout the house. All with insulation that wasn't as good as we have, windows that didn't shut as tight as ours, doors that were draftier. As is typical today, our furnace has safety systems designed to detect problems and shut itself down if something weird happens. Back then, indoor heat was a dangerous thing. There's been at least one chimney fire in this house, an event which often claimed the entire house and sometimes the lives of its inhabitants. Ten feet from my desk, there's a rounded out black spot on the floor where, perhaps 70 years ago, someone opened the door to a wood stove, only to be surprised by a burning log falling out to the wood floor.

Today, we can't use wood heat due to Terah's asthma. We had the chimney removed to boost the energy efficiency of the house with modern heat. Out back in the trees north of the house, there is a pile of bricks, saved from our chimney for future use. Each brick has a scorched side, darkened from the chimney fire and decades of use.

As we experienced firsthand in the ice storm of 2005 (see also more stories and pictures), it doesn't take much to be thrown back a hundred years from a convenient modern heat to our non-automated, non-mechized, past. All it takes is a tree to snap too close to the right power line anywhere between our house and the generating station -- which I think is 80 miles away -- to make our house mighty cold. Even though I still have a stack of firewood, it wouldn't do us much good these days.

With that in mind, today I was listening to the radio while driving in to work. How lovely to hear this quote:

"The National Weather Service will issue a Winter Storm Warning effective at noon today, lasting through 6AM tomorrow." We are to expect rain, freezing rain, ice pellets, and ice. A "wintry mix" is the technical term for it, I believe.

Temperatures were just a few degrees warmer than expected this afternoon, so we got mainly rain. What we will get tonight is an open question yet. I'm sure that schoolchildren all over the state are hoping for ice and lots of it. Personally, I feel that it's only been three years since I spent a week carrying a saw in my trunk in order to be able to clear my driveway every time I left home or got back home. I think I'm owed another year or two off. I also wouldn't mind avoiding the giant branch sitting on the ground right in front of the front door, or the 40-degree indoor temperatures, or the lack of running water due to lack of electricity.

But these crisp, cold winter days are a rare thing to enjoy these days. We get a month or two of stifling heat each summer, but only a week or two to enjoy this really cold part of winter. I miss the snowdrifts when we don't get them.

So, mother nature, bring it on. I'll be waiting with my camera and a glass of hot chocolate. Because even without electricity, I can still light a burner on our oven with a match.

9 December 2007

Evan Prodromou: 18 Frimaire CCXVI

Chris Messina wrote an interesting post on his blog about his OpenID Shitlist, Hitlist and Wishlist for 2008. (I'm going to briefly try to remember if using the word "shit" is cause for alarm on Planet Debian, and then I'm going to ignore the problem and move on.) I think it's a good post and it really identifies some of the key players that are helping and failing in the OpenID space. I got a shout-out for Wikitravel and for the MediaWiki OpenID extension, which yay for me. I think Chris was probably a little unfair about Wikimedia's lack of support. The site is moving very slowly towards a unified login for all its wikis, which is a really difficult task to make happen. OpenID is slated for installation some time after that, so it's going to be a while. But I hope that it will be useful for Wikipedians. My main impression from this blog post, however, is that OpenID's day in the sun might be over. That's not a bad thing -- usually the hard work gets done after the cameras are turned off. Zealots like myself tend to think that if only the world knew about our latest-greatest idea or technology, they'd fall right into line and adopt it immediately. But my experience has been that things work a lot slower than that, and I'd guess that OpenID is probably going to have a similar adoption curve. In thinking about opening up the Social Web, it's probably good to compare the opening of the Web Web in the mid-1990s. At the time, most Americans who were "online" were subscribed to a proprietary network like AOL, Compuserve, Delphi or MSN. (I'm not sure how things were in the rest of the world... Similar? Worse?) Many of these services either walled their users from the Internet entirely, or made it a one-way interaction. AOLers could read stuff from the rest of the Web, for example, but others couldn't see what AOL folks were doing. That system looked impenetrable; after all, AOL was paying millions of dollars to make great content and manage forums and the like, and why would they give that away to Internet leeches for free? But eventually it came apart because the Web became more interesting than the on-line services. (I personally think the watershed was the Ate my balls meme, but others might differ. I just kind of picture hundreds of thousands of AOLers calling up technical support asking to see the Mr. T pictures, and that's what finally broke things down.) Today, on-line service "walled gardens" are a negligible part of the on-line world -- those that still exist are more or less big ISPs. I think that the parallel with the Social Web is probably pretty apt. Today, Google, Facebook and Digg are reluctant to open up their identity silos to a distributed social Web. Their main asset today is their collection of identities and the relationships between them -- why give away the crown jewels? My guess is that it's not going to be until a mature, standardized and distributed Social Web exists outside the walls of the big social-networking players that we'll see them really willing to sit down at the table and come to the party. Of course, by that time, it'll be a moot point. But that just means there's a nice big fat market for somebody smart to take advantage of. tags:

8 December 2007

Raphael Geissert: DeBaBaReTools: finally something functional...

...but a lot of code still needs to be written.

Let's give a try to the last changes...

processIncoming
$ VERBOSE=1 processIncoming
processIncoming v0.1 started.
Processing /home/raphael/Deb/repository/pub/UploadQueue/php-timezonedb_2007.10-1_source.changes...
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/php-timezonedb_2007.10-1.diff.gz" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/php-timezonedb_2007.10-1.dsc" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/php-timezonedb_2007.10-1_source.changes" to "/home/raphael/Deb/repository/incoming/accepted/"
mv'ing "/home/raphael/Deb/repository/pub/UploadQueue/php-timezonedb_2007.10.orig.tar.gz" to "/home/raphael/Deb/repository/incoming/accepted/"
processIncoming v0.1 stopped.


needsBuild
$ VERBOSE=1 needsBuild
needsBuild v0.2 started.
Architectures: i386 amd64 all
Now processing /home/raphael/Deb/repository/incoming/accepted/php-timezonedb_2007.10-1_source.changes
Adding php-timezonedb to be built in i386 for the sid distribution
Adding php-timezonedb to be built in amd64 for the sid distribution
mv'ing "/home/raphael/Deb/repository/incoming/accepted/php-timezonedb_2007.10-1.dsc" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/php-timezonedb_2007.10.orig.tar.gz" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/php-timezonedb_2007.10-1.diff.gz" to "/home/raphael/Deb/repository/incoming"
mv'ing "/home/raphael/Deb/repository/incoming/accepted/php-timezonedb_2007.10-1_source.changes" to "/home/raphael/Deb/repository/incoming"
needsBuild v0.2 stopped.


wannaBuild
$ VERBOSE=1 wannaBuild
wannaBuild v0.1 started.
Fetching list of packages to be built for unstable
Fetching source package php-timezonedb v2007.10-1
Use of uninitialized value in string eq at /usr/bin/dget line 377.
cat: /home/raphael/Deb/repository/build/data/needsBuild.unstable: No such file or directory
Starting build backend...
Executing sudo pbuilder --update --basetgz /var/cache/pbuilder/unstable.tgz
Starting build process
Could not find /home/raphael/Deb/repository/build/php-timezonedbx10525/*.changes, build failed
Fetching list of packages to be built for testing
Fetching list of packages to be built for stable
Fetching list of packages to be built for oldstable
wannaBuild v0.1 stopped.

Yikes!
$ c=/home/raphael/Deb/repository/build/php-timezonedbx10525/*.changes; echo $c
/home/raphael/Deb/repository/build/php-timezonedbx10525/php-timezonedb_2007.10-1_i386.changes

wth?:
#!/bin/bash
#... some code
set +f
#... some code
CHANGES=$workingDir/*.changes
#
# Make sure we got something
#
if [ ! -f "$CHANGES" ]; then
Say "\t\tCould not find $CHANGES, build failed"
buildQueue "$ENTRY" "$buildingForArchs" "failed"
continue
fi

no globbing? :(
this works:
#!/bin/bash
#... some code
set +f
#... some code
CHANGES=$workingDir/*.changes
#
# Make sure we got something
#
if [ ! -f $CHANGES ]; then
Say "\t\tCould not find $CHANGES, build failed"
buildQueue "$ENTRY" "$buildingForArchs" "failed"
continue
fi

(note that $CHANGES is not between quotation marks in the functional piece of code)

but how can I get file globbing to make $CHANGES actually store the globbed path? :confused:

7 December 2007

Benjamin Mako Hill: New Antifeatures Article and FSF Members' Bulletin

The FSF's fall members bulletin is out. For it, I spent some time refining the blogpost I recently wrote on antifeatures into an article. I got a whole lot of feedback last time (Thanks!), most of which criticized my choice of examples. I've structured this version around different, and I hope less controversial, examples. Please read the new article and leave comments here, especially if you criticized the old one. The bulletin also includes two pieces introducing a campaign against software patents that the FSF plans to launch early next year and a discussion of the AGPL by Brett Smith. This bulletin hints at what I think are the big issues that the FSF plans to take on next year: software patents, web services, and creative new takes on the free software message that are designed to resonant beyond our historically very technical community of hackers. I'll write more on this in the next week or so. To support this mission, and to receive future copies of the bulletin directly, please consider becoming an associate member today during the FSF's year-end members drive.

5 December 2007

Evan Prodromou: 14 Frimaire CCXVI

One thing that's been interesting me lately is RSS. Yeah, I know, not exactly cutting-edge technology, but the format -- in its three different forms -- has become the default for machine-to-machine transfer of serial information on the Web. So RSS really represents our individual or collective presence on the Web spread across time, space, and theme. I'm particularly interested in RSS because I'm working on themed portals like Keiki. It's one of our goals to pull in the parenting part of a person's personality spread on other parts of the Web, so you don't have to re-enter it in Keiki if you don't want to. It's a fun problem to be solving. But as I was playing with the format, I realized that I'm spread pretty far across the Web, myself. I make most of my contributions to this blog, but I'm also part of other communities and a user of other services. What if I used some software like Planet to pull together the disparate threads of me into one place? So that's what I did. I ended up using a tool called Gregarius instead of Planet, mostly because I originally intended to install it on Godaddy's hosting service, which doesn't support cron jobs, which Planet needs. Once I realized how ad-infested GD's "free" hosting service is, though, I moved all my sites off of it, and back to Antipater. And my personal aggregator is there, too. It was interesting to pull in the accounts I've listed on About Me and see which ones produced RSS feeds. Some I expected (my Flickr feed, my del.icio.us feed) and others I didn't (my Upcoming feed surprised me). I was also surprised by sites that didn't produce a feed. I really expected something from Pownce and Tribe.net), but I couldn't get them to cough up a feed. Most disappointing was Facebook, which has a really nice mini-feed of my activity there that doesn't seem to translate into an RSS feed in any possible way. But otherwise things went very quick. I found Gregarius really easy to work with, although its inability to pull tag (metadata) and categories out of RSS streams. There's an autotagger plugin, but I haven't gotten it to catch any tags yet. Oh, and the OPML output was horrible -- I think it might generate HTML that looks like raw OPML -- totally useless. In any event, if you feel like cyberstalking me or just seeing what I'm doing around the rest of the Web, keep an eye on evanprodromou.info. There's even a handy aggregated RSS feed... just in case you want it. tags:

David Welton: Hecl Java Integration

Yesterday, I took the Java integration I'd been building into the Hecl Android port, and moved it into its own directory, so now it's built in to the command line/j2se (non JavaME) version of Hecl for people to experiment with. Here's a slightly modified version of my posting on the subject: I created a java/ subdirectory with an org.hecl.java package that does a few things. The core of the system is in JavaCmd and Reflection. The first creates commands out of Java classes. It utilizes, obviously, the reflection stuff in Reflection. Both are, at the moment, sort of hacky and tentative, but work. For instance, I checked in this bit of test suite today:
test java-2  
   java java.util.Hashtable ht
   set hasht [ht -new  ]
   $hasht put foo "bar"
   $hasht get foo
   bar 
The 'java' command takes a class, and string, and creates a new Hecl command 'ht' that is tied to the Hashtable class. ht -new (could have been -new [list]) is how we call the constructor. After this, $hasht points to a Hashtable, and we can utilize its methods. Up to a point, at least - there have to be mappings in Reflection to deal correctly with types. For instance, there isn't a mapping for Enumeration right now, so calling the .keys() method wouldn't do the right thing. There are some more bits and pieces of magic: There are some open issues with the ongoing work:

Matthew Palmer: Strategists and Tacticians

Like most things, the scale of decisions that have to be made by a person or organisation fall across a wide spectrum. At one end, you've got the fine-detail work: lines of code, individual config settings, IP addresses, that sort of thing. This is crucial work, because it's this detail that ultimately produces saleable results. Travelling all the way to the other end, there's the "big picture" decisions: the "visionary" stuff. What market segment will we target? What will we do (in large-scale terms) to get there? I am convinced that individuals naturally gravitate towards one end of this spectrum or the other, depending on their psychology. While people usually can work at all scales, they have a "most comfortable" point where they work the most naturally. The further away from this point they are pushed, the less comfortable and effective they are. No level of thinking is better or worse than the other; they're just different. While "large scale thinker" and "small scale thinker" could be taken as being insulting, I certainly don't mean it that way. I should point out that "Strategy" isn't (just) about setting goals. A strategist isn't someone who comes out with grand pronouncements like "By the end of next year this company should be providing telecommunications services to 20% of the Fortune 500" without knowing how to get there. That's not a strategist, that's a poor-quality management consultant. People whose only skill is making vague pronouncements should just be taken out and shot. They're not doing anything useful for anyone. A strategist is someone who is good at planning the goal of "20% of the Fortune 500". They're thinking about the big picture issues, without getting bogged down in the minutiae. A tactician, given the job of planning something at the macro scale, will chase some good idea down an intricately detailed rabbit hole, and miss the other dozen or so large issues that need to be considered. The strategist's planning needs to stop at a certain level and let other people take on the detail work. Conversely, a good tactician can focus on the individual details without getting distracted by the big picture. A strategist put into a tactical role will miss all the important minutiae because they're working out how their little part fits into the big picture, instead of working out how to make their little part work, in and of itself. It's important, for individual happiness, to try and work out what level you're most comfortable thinking at, and then trying to find a job that puts you there. It's almost as important to make sure that the people who are working at the more and less detail levels around you are equally comfortable. Take, for example, the micromanager. We've all either been there ourselves or have heard multiple stories on the subject. I think the micromanager is nothing more than a person who wants to work at a smaller scale than they're being forced to by their organisational rank. Since they can't do the detail work any more, their only outlet is working vicariously through their subordinates. Voila! Instant micromanagement. An even more painful case of micromanagement would be when the subordinate wants to think at a larger scale than the superior. In that case, the subordinate will naturally be thinking large scale, and will miss the details. To the small scale thinking superior, that is incompetence, and will naturally be dealt with by more micromanagement. In reality, both parties are incompetent at their jobs, and they should really swap roles, so that everyone is in their element. It would be nice if companies stopped thinking hierarchically in this way -- that a more "senior" person has to think at larger levels. Just because you've been somewhere longer (or have been working in an industry longer, or got higher marks, or whatever), it doesn't mean that you're more of a strategist. This is probably the Peter Principle restated: people get promoted to a level where they just can't comfortably think at the necessary scale any more. If instead people were put into a planning hierarchy based on their natural scale of thinking, we'd all be a lot better off. There'd be a lot less power games, though, which makes me think it's not going to happen any time soon. A business, at whatever size it might be, needs an appropriate mix of strategists and tacticians. A really small business (1-10 people) can get away without needing large scale thinkers, in the same way that a really small boat can get away without needing a rudder or pilot. If a really small boat gets itself into trouble, everyone on board can grab an oar or bucket and help get the boat out it's predicament -- it's small and nimble enough to be able to do that. As the company expands, though, it's important to make sure you've got some strategists around. If you don't have anyone to keep an eye out for problems and plan around them, your small-to-medium sized boat is likely to have a hole punched in it by a submerged rock. Even if somebody on board happens to notice the rock before you actually hit it, once you get to a certain size you can't physically stop or turn the boat in time. If you don't understand the growth issues in the company, you might not even realise that you're no longer the nimble and low-inertia dinghy until you're up to your knees in sea water. Although an obvious solution to this problem might be to say that all businesses should be small and nimble ones, it's as impractical as saying that all boats should be dinghies. A fleet of dinghies isn't going to be able to support the worldwide sea freight market, and a fleet of small companies doesn't have the necessary resources on hand to take on the big projects that are so often needed. Also, a dinghy is at risk of being swamped by one freak wave, while a larger ship can weather significant storms without going under. Regardless of the size of the business, there always needs to be a good supply of tacticians. A boat (of whatever size) full of people who are all looking out for rocks isn't going to go anywhere, because nobody's making the thing move. Similarly, a company full of strategists isn't going to be doing any of the day-to-day work that actually earns money, and no money means no company. The single most important thing, though, is be self-aware enough to know what sort of person you are, and try to find something that lets you work at the level you're most comfortable at. Otherwise you're just setting yourself up for unhappiness.
(I'm not really sure why I'm suddenly writing management blog posts; this idea of "levels of thinking" just came to me and I figured I'd put it out there. If it makes you feel more comfortable, there's a fairly transparent mapping of these ideas to the practice of software development, although I'll leave the execution of that mapping to the reader. Comments are welcome.)

Next.

Previous.