I've got a Bilora Box some time ago. Since I'm shooting medium format with my Pentax 645n anyway both films and tools to develop them are at hand.

Box cameras are pretty much pin hole cameras on steroids -- one cheap fix-focus lens, if you're lucky more than one aperture, shutter speeds of about 1/30s and bulb. On the back of the case is a small red window for the picture counter -- numbers printed on the backing paper of the film.

My box takes 6x9cm pictures, big enough for contact prints. Given the blurriness of the pictures you don't want to enlarge them much anyway. As an alternative to making prints and scanning them I tried scanning the negatives directly today -- with impressing results, when ignoring that the scanner became quite dusty and I'm unable to locate it. Fortunately the dust and reams add to the antique look.

To scan the negatives I placed two sheets of paper on top of the negative and added light from two 500W halogen spotlights to replace the lack of a transparency unit.

Picture taken with the Bilora Box Pictures taken with the Bilora Box
(Click to enlarge)



Perls hashes are a handy way of storing lots of easily accessible data. Most of the time you just use it to hold lots of scalars, but sometimes it would be nice to add an array. This article describes how to do it.

Storing an array or an array reference in a hash is pretty straightforward, you just need to know when to explicitly cast the element to an array using @{} -- which is almost everytime, with two exceptions: You don't need the cast when assigning an array reference to a hash element or handing over an array reference as a function parameter:

@{%hash->{array}}=@array;
%hash->{arrayref}=\@array;


Of course it's possible to push() or pop() from a hash element, given you cast it:

push(@{%hash->{array}}, "push_array_1");


Looping -- you might have guessed it already -- works as always, once you added the cast:

print "$_\" foreach(@{%hash->{$_}});


The same syntax rules apply to using hash refs. The following example demonstrates everything described above, showing the difference between storing an array or an array reference by adding values to both an array and an array reference:

#!/usr/bin/perl

use strict;
my %hash;
my $href={};
my @array=('foo', 'bar', 'baz');

@{%hash->{array}}=@array;
%hash->{arrayref}=\@array;

@{$href->{array}}=@array;
$href->{arrayref}=\@array;

push(@array, 'push_ref_1');
push(@{%hash->{array}}, "push_array_1");
push(@{%hash->{arrayref}}, "push_ref_2");

foreach ('array', 'arrayref'){
print "$_:\n";
print "(hash)\t$_\n" foreach(@{%hash->{$_}});
print "(hashref)\t$_\n" foreach(@{$href->{$_}});
print "\n";
}



$ ./perl-array-hash.pl 
array:
(hash) foo
(hash) bar
(hash) baz
(hash) push_array_1
(hashref) foo
(hashref) bar
(hashref) baz

arrayref:
(hash) foo
(hash) bar
(hash) baz
(hash) push_ref_1
(hash) push_ref_2
(hashref) foo
(hashref) bar
(hashref) baz
(hashref) push_ref_1
(hashref) push_ref_2

Posted by Bernd Wachter -- 0 comments


Flashing the Fonera using custom firmware is widely documented. At least for the units I own TFTP-flashing is highly unreliable. Fortunately it's possible to flash the fonera using XMODEM or YMODEM. Unfortunately, my favorite terminal emulator (kermit) does not provide built-in XYMODEM-support.

Fortunately kermit supports external protocols, and there's a free implementation available in the lrzsz package. Once lrzsz is installed configuration for YMODEM is quite easy:

set protocol ymodem {} {} {sb %s} {} {rb} {}
set file type binary



You might want to put those two lines into .mykermrc, in case you intend to flash your unit more than once. Flashing works almost like using TFTP, you just need to tell `load' where to load from (-m ymodem) and start sending the file:


RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-vmlinux.lzma -m ymodem
C
(Back at zak.serf.lart.info)
----------------------------------------------------
(/home/bwachter/fonera/) C-Kermit>send /binary openwrt-atheros-vmlinux.lzma
Sending: openwrt-atheros-vmlinux.lzma
Bytes Sent: 786432 BPS:9014
Sending:
Ymodem sectors/kbytes sent: 0/ 0k
Transfer complete
(/home/bwachter/fonera/) C-Kermit>c
[..]
Raw file loaded 0x80040800-0x801007ff, assumed entry at 0x80040800
xyzModem - CRC mode, 6146(SOH)/0(STX)/0(CAN) packets, 3 retries
RedBoot> fis init
About to initialize [format] FLASH image system - continue (y/n)? y
*** Initialize FLASH Image System
... Erase from 0xa87e0000-0xa87f0000: .
... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot> fis create -e 0x80041000 -r 0x80041000 vmlinux.bin.l7
... Erase from 0xa8030000-0xa80f0000: ............
... Program from 0x80040800-0x80100800 at 0xa8030000: ............
... Erase from 0xa87e0000-0xa87f0000: .
... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
[...]



Unless you'd like to spend a nice evening watching data transferred at 9600Bps you might want to set the baudrate to 115200 before flashing:

RedBoot> baudrate -b 115200
Baud rate will be changed to 115200 - update your settings



The change is non-permanent. In case you're using a distribution which supports higher baudrates on the console you can change it permanently using fconfig.

Posted by Bernd Wachter -- 0 comments


It has been a while since my last post, for various reasons. One was the lack of interest to change my old scripts to allow posting while keeping out the incredible amount of spam. A new set of scripts is finally usable, replacing all my old cgi-scripts, making maintenance a lot easier. While everything is still far from ready I'm at a point where I can use it for basic blogging, amongst other things. New features will be added when I'm in the mood to do so, if some of them might be interesting for the readers I'll write about them.

There's no comment function right now, if you'd like to comment on something please write an email. For navigation, use the newly introduced tags.

Posted by Bernd Wachter -- 0 comments


I published a stable release of aardmail some time ago. I've been using it for retrieving (pop3) and sending (smtp) all my mail for several month now. While it currently covers most of the features I need some things may need to be added. Drop me a note or (better) subscribe to the aardmail mailinglist if you have any ideas worth discussing.

cram-md5. I don't like it at all, but it seems there are people out there using it. Currently you can use client certificates to authentificate to a mail relay, or password for pop3. I'd prefer having client certificates for pop3, too. My client can do it (it simply goes on with something like list after user, and the server requests a client certificate for auth) -- however, it seems that no other person ever wanted something like that, so there are currently no servers out there supporting it. I don't know if and when I'll add a pop3d to aardmail.

imap. I don't use it, but many people requested it. If you really want this feature please consider donating. I'll do it someday for sure, but with low priority.

sendmail. The current `sendmail' just spools mail into a users Maildir. I'd like to have a replacement for ssmtp, with a Maildir as spool. I'm still trying to figure out what's the best way to do this, but that's most likely the next part I'll change -- unless someone pays me for other features.

fetchmail. I'd like to have a frontend which acts like fetchmail, and calls the different aardmail clients. Especially fetchmail daemon mode has been requested by some people.

Windows users. I don't have the time to do much testing under Windows. I added Windows support to see how painful it is nowadays to support both UNIX and Windows, but can't do much more testing than doing regular builds.

Posted by Bernd Wachter -- 0 comments


I did some tests on POSIX threads recently. The API is simply braindead -- I have no idea how someone could ever think the way joinable threads work would be a good idea.

pthread_create(&thread1, &thread_attr, init_thread, (void*) 1);

pthread_create(&thread2, &thread_attr, init_thread, (void*) 2);

pthread_join(thread1);
pthread_join(thread2);



Please note that POSIX specifies that threads get created joinable per default. However, not all implementations stick to this. Therefore it's good style to explicitely create threads joinable.

The thread calling pthread_join will now block until thread1 terminates. Then block again until thread2 terminates (or go on immediately if thread2 already terminated). What happens if something went wrong in thread1, making it never terminate? Nothing. It will never go over the join. In complex applications I'd feel pretty bad using the above schematics without having a 3rd thread controlling the other 2, killing them if necessary.

Wait, you can get over this with detaching the threads? Partly true. We can easily create the threads detached, or detach a thread with pthread_detach (there's no way of making a detached thread joinable again):

pthread_attr_init(&thread_attr);

pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);



Whoops. The application exits now before our threads finished, killing all of them. Bad one. Back to the manpages -- there must be something like wait() for processes. The design of pthreads can't be that bad. Well, it seems it can.

So far I did not find anything like wait(). However, with the following code you can get close to it:

main:


int num_threads;
pthread_create(&thread1, &thread_attr, init_thread, (void*) 1);
num_threads++;
pthread_create(&thread2, &thread_attr, init_thread, (void*) 2);
num_threads++;
while (num_threads > 0){
pthread_mutex_lock(&condition_mutex);
pthread_cond_wait(&cond_texit, &condition_mutex);
pthread_mutex_unlock(&condition_mutex);
}

init_thread:

pthread_mutex_lock(&condition_mutex);
threads_active--;
pthread_cond_signal(&cond_texit);
pthread_mutex_unlock(&condition_mutex);



Yep. You have to
- keep track of how many threads you created
- wait for a condition in the thread (at least you don't have to poll)
- make sure a thread decreases the number of active threads before it exits and signals cond_exit
just to emulate something like a wait()!

You should always let the thread decrease the number of threads. If you put that part in the wait()-loop it's possible that 2 threads signal the condition at the same time, leading to missing some threads (which will turn the wait()-loop into an endless loop...)

Please note that this will only work if the thread does not get cancelled. To make sure the code gets always called it's better to install a cleanup handler (see pthread_cleanup_push()) immediately after starting the thread.

Please drop me a note if I missed anything there.

Posted by Bernd Wachter -- 0 comments


It's been a long while since my last posts. I collected much stuff to publish in that time, and I'm currently going over all that stuff to correct errors -- or dump it if it's outdated by now. Expect a bunch of postings to different topics over the next days.

Posted by Bernd Wachter -- 0 comments


-

Das Bundesinnenministerium (BMI) will Prüfberichte von elektronischen Wahlmaschinen, die bei der Bundestagswahl am Sonntag zum Einsatz kommen, nicht veröffentlichen. Auf Anfrage des Physikers Dr. Ulrich Wiesner erklärte das zuständige Referat V3, eine Veröffentlichung der Prüfberichte nehme das Ministerium zum Schutz des Firmen-Know-hows des Herstellers nicht vor.

-

aka `die Dinger waren scheissteuer, taugen aber auch nicht mehr als die Diebold-Maschinchen der Amis'? Wahlmaschinen gehoeren eindeutig zu Bereichen in denen ich von Blackboxen absolut nix halte.

Meldung bei heise.de



On 9/11 (!) my newsserver suddenly got `a bit' unstable, i.e. crashed every few minutes. Attaching strace to the newly started server process gave the following:

[...]
open("/var/spool/news/overview/a/r/i/alt.religion.islam.DAT", O_RDWR|O_APPEND|O_CREAT, 0664 <unfinished ...>
+++ killed by SIGSEGV +++

The fix was pretty simple -- offline xfs_check made the file readable again. It even contained useable content. Overview file for an islamic newsgroup, causing crashs on 9/11 -- coincidence? Or an attack targeted directly at my poor inn? Conspiracy theories are welcome...

Tags: None
Posted by Bernd Wachter -- 0 comments


Day 1 is over. I have been unable to visit all the talks I wanted to, but met many old friends (and met some of the people I know from IRC irl for the first time). There was time for some pretty interesting discussions, as well as helping some people getting their stuff to work.

By now I got power _and_ network in my tent (cat5 -- thanks for the cable ;) ), which means I can write this lines out of my sleeping bag. At about 11 it gets too hot in here to stay in longer -- but there's much more interesting stuff to see outside the tent anyway.

It rained again today -- harder than yesterday. Fortunately my old tent seems to be in a way better condition than I'd expected it to be -- no water except the few drops I brought in in clothing inside of the tent. I guess it will stay so for the rest of the camp -- fine. Except for a very few ants who prefer my dry tent to the outside it's quite comfortable in here.

Networking seems to be working reliable by now -- at least IPv4, at least using cable. WLan ist pretty much broken, sometimes it works, more often it doesnt. v6 does not appear to be routed at the moment, which is a bit annoying since all boxes I'd like to reach are both v6 and v4 -- resulting in timeouts, without manually removing the v6-address. At least they shot the idiot who kept running a second (inofficial) radvd.

I managed to show up at the speakers desk this morning, as expected nothing has changed, talk stills on Sunday, ... -- let's see if CCCB will manage something like that on day, too. Releasing a final schedule some time _after_ the event has finished is not the right way... ;)

I don't know what to do tomorrow. Would be fun to see what they mean by `Morning Practicalities' -- but it seems to be targeted mostly at the masochists among the hackers. 9:30 in the morning -- hey, the nicest talks start when the program is over, and I'd like to have a shower in the morning. Later that day there are some quite interesting talks, more about it tomorrow if I managed to attend to the one I wanted...

Tags: None
Posted by Bernd Wachter -- 0 comments