My Photo
Maht
Computer fiddler since I was 10, it really is my main activity - obsessively, continually, I enjoy getting use out of old computers people give away. I've got a room full of bits & bobs. I've been vegan since August 1st 1991, despite its impossible goals.
View my complete profile

compjootery

Record of some of the computer tech I deal with so that it's documented at least somewhere.

Saturday, 20 June 2009

Serialising multiple writers in the shell

A few years ago I came across wait_on for monitoring file changes on FreeBSD (from the kqueue) in the shell. Linux has inotify-tools for using inotify the same way. Using these tools we can build a fifo daemon with multiple writers and one reader. I'm not sure if Plan 9 already has a way to do this in userland, maybe even by using snoopy.

Here's the Linux version I use.


% cat /usr/local/bin/manage_queue
#!/usr/local/plan9/bin/rc

# we assume that / will never appear in a filename and thus is a safe delimeter
DELIMETER=/

fn waiter {
inotifywait -q $3 --format '%f'^$DELIMETER -e $2 $1
}

fn watch {
if(~ $1 -1) # do it once
waiter $*(2-)
if not # do it forever
waiter $1 $2 -m
}

fn process {
read_until $DELIMETER | sed 's/.$//' | $*
/usr/local/plan9/bin/dd -ibs 1 -count 1 >[2] /dev/null
}

# start the processing cmd in the queue directory
if(~ $1 -1) { # do it once
cd $2
watch -1 $2 $3 | process $*(4-)
}
if not { # ad infinitum
cd $1
watch $1 $2 | while() { process $*(3-) }
}


and you invoke it thus :
su -c 'manage_queue /tmp/uploaded_images/ moved_to make_thumbnails' uploadprocessor
although I use daemontools so that is the contents of /etc/service/uploads/run

My other usual option is close_write instead of moved_to, it depends how your files get there and are processed once they arrive.

The -1 option is for doing a spot of debugging, it does one file and then exits

The bit of script missing from there is read_until


% cat /usr/local/bin/read_until
#!/usr/local/plan9/bin/rc

ifs=()

while() {
c=`{/usr/local/plan9/bin/dd -ibs 1 -count 1 >[2] /dev/null}
if(~ $#c 0)
echo -n ' '
if not
switch($c) {
case $1
exit
case *
echo -n $c
}
}
}


I had to make that because newline is a valid filename character thus defeating various line reading commands.

Now you've got the thing going, you'll need a processor like make_thumbnails, which I've made up here as an example (gm is graphicsmagick which kept the older api when ImageMagick changed):

#!/usr/local/plan9/bin/rc
ifs=()
fin=`{cat}
gm convert -resize 100x100 /tmp/uploads/$fin /var/www/thumbs/$fin.jpeg
gm convert -resize 350x500 /tmp/uploads/$fin /var/www/mids/$fin.jpeg



So, using this mechanism the user uploads the image via a web browser, when the CGI is satisfied it can do 'mv /uploadir/$up /tmp/uploads/$up' and carry on sending html to the user, the thumbnail will get made when it gets to the front of the queue.

The other issues this can solve is ring fencing users from each other and just communicating via files and filenames (of which the above is an example but also internal users). www can write to /tmp/downloads but not /var/www/*. By passing the uploaded image through gm it gets (hopefully) sanitized, by running gm as its own user that mitigates attacks against gm, one can use the OSes limiters to let gm only have so much cpu etc.

By serialising like this it also protects against a DoS uploading loads of massive images and trying to thumbnail them in parallel. You've still got the problem of processing them but at least only one process will be pegged at 100% not one per upload.

Though I've not done it yet, you could also use it as a marshall which does some load balancing (perhaps using Xcpu), or just forked threads.

--

Saturday, 16 May 2009

Strip invalid characters UTF-8 from a bytestream

Found this at http://snippets.dzone.com/posts/show/6194

iconv -c -f UTF-8 -t UTF-8 < invalid > valid

Friday, 10 April 2009

VNC serving

if you want passwordless vnc, use Debian package vnc4server

vncserver -SecurityTypes None

Build your own Inferno

http://code.google.com/p/inferno-os/source/checkout

first I'll need subversion

apt-get install subversion subversion-tools
then get the code
cd /usr/local; svn checkout http://inferno-os.googlecode.com/svn/trunk/ inferno-os-read-only; mv inferno-os-read-only inferno

edit mkconfig
ROOT=/usr/local/inferno
SYSHOST=Linux
OBJTYPE=386

edit makemk.sh
ROOT=/usr/local/inferno
SYSTARG=Linux

% sh makemk.sh
PATH=$PATH:/usr/local/inferno/Linux/386/bin
mk install

seems to have worked
ohoh fonts
copied lucida, lucidasans and pelm from the vitanuova cdinstall.iso

Tuesday, 24 March 2009

more trig

for a half circle

for a point X, Y

if X < w / 2

x = ( w / 2 ) - X

a = atan(y / x)
R = sqrt(x * x + h * h)
scale = h / R

Monday, 23 March 2009

Projection trig

the throw ratio (R) is defined as distance to screen (D) divided by the width of the image (W)

or rather R = D / W
As we normally have R, are constrained by D and want to know W rewrite that as

W = D / R

if we assume D = 1 then W = 1 / R
for atan we only use half the triangle for the angle from straight :
thus
a = atan (W / 2) = atan ( (1 / R) * (1 / 2) ) = atan ( 1 / 2R )
ergo the angle of the cone A = 2 * a = 2 * atan ( 1 / 2R )
for a Ratio of 0.8, A = 2 * atan( 1 / 1.6) = 64.011 degrees

mpeg2enc & dvdauthoring on debian

basically you have to install
http://debian-multimedia.org/

apt-get install mjpegtools mkisofs dvdauthor ffmpeg

2mpeg

#!/usr/local/plan9/bin/rc

f = 8 # for dvdauthor otherwise go with 3
br = 7500
a = 3
q = 5

while(~ $1 -*) {
switch($1) {
case -b
br = $2
shift 2
case -f
f = $2
shift 2
case -a
a = $2
shift 2
# 1 - 1 - 1:1 display
# 2 - 2 - 4:3 display
# 3 - 3 - 16:9 display
# 4 - 4 - 2.21:1 display
case -i
deinterlace = '-deinterlace'
shift
case -q
q = $2
shift 2
}
}

paff = $1
shift
fname = `{basename $paff}

2mp2 $paff &
2m2v -q $q -a $a -f $f -b $br $paff $deinterlace &
wait

mplex -f 8 -o $fname.mpeg $fname.m2v $fname.mp2 && rm $fname.m2v $fname.mp2


2mp2

#!/usr/local/plan9/bin/rc

mplayer -vc null -vo null -ao 'pcm:fast:file=' ^$1.wav $1
mp2enc < $1.wav -o `{basename $1} ^.mp2 && rm $1.wav


2wav

#!/usr/local/plan9/bin/rc

aid = ''
while(~ $1 -*) {
switch($1) {
case -aid
aid = '-aid ' $2
shift 2
}
}

mplayer $aid -vc null -vo null -ao 'pcm:fast:file=/dev/fd/1' -

make some mpegs : 2mpeg 1.mov
2mpeg 2.mov
so you'll end up with 1.mov.mpeg 2.mov.mpeg
ffmpeg can deduce your aspect if you don't want to specify it
then make an xml (dvd.xml) file thus :

<dvdauthor dest="dvd">
<vmgm />
<titleset>
<titles>
<video format="pal" aspect="4:3" />
<audio format="pcm" lang="EN" />
<subpicture lang="EN" />
<pgc>
<vob file="1.mov.mpeg" />
<vob file="2.mov.mpeg" />
</pgc>
</titles>
</titleset>
</dvdauthor>


then


dvdauthor -x dvd.xml
mkisofs -dvd-video -udf -o dvd.iso dvd
wodim dev=/dev/cdrw1 -dao dvd.iso


done