Tuesday, October 30, 2012

HowTo fix laptop broken hinge

My old laptop right hinge broke off the other day and it was very hard to move it. Unfortunately there is some time until I can get a replacement so I had to do something in the meanwhile.
In the service they told me they can't fix it, that I need to find the part and then it can be replaced. So I was short of reasonable options for fixing.

The good thing was that right hinge with the monitor cables was working and I fortunately grasped that if I remove the right hinge I can close and open lid if I'm careful. The service man was kind enough to remove it and I was somehow happy.

But! Situation was still not perfect. If I did a bad move I could break the left hinge and end up with a machine in pieces. So it was time to see what I have in the bin... a broken pen... how could I throw it in the bin?! so useful!

Here's what I did:

I noticed the pen can be put inside the place of the removed hinge. The black parts in front and back are fitting ideally into the places the old hinge was expanding into the lid. So I needed to only cut the pen and use some glue to fix the black parts into it. Above is what I did. Here is how it ended up, you can also see the damaged place of the lid:

It's not very solid but good enough for the purpose.

P.S. I know, I need to clean it sometimes :-)

Friday, October 5, 2012

element namespace inheritance with XSLT

Ok, here's the task - an XML with namespaces, these namespaces change over time but rarely significantly enough to require changes to the XSL, and we want to have the XSL in such a way that these changes to namespace do not require us to go update the XSLs with the new ones. If we are not careful we can end up with the well known empty/blank namespace declarations like xmlns="" and these break XML validation

Let's take an example:

<?xml version='1.0' encoding='UTF-8'?>

<server xmlns="urn:jboss:domain:1.3">
   <extensions>
      <extension module="org.jboss.as.clustering.infinispan"/>
   </extensions>
</server>

We want to add an element "system-properties" next to extensions. So here we got this XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="xml" indent="yes"/>

      <!-- Append <system-properties/> element. -->
      <xsl:template match="//*[local-name()='extensions'">
         <xsl:variable name="thisns" select="namespace-uri()"/>
         <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
         <xsl:element name="system-properties" namespace="{$thisns}"/>
      </xsl:template>

      <!-- Copy everything else untouched. -->
      <xsl:template match="@*|node()">
         <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
      </xsl:template>

</xsl:stylesheet>

Now this transforms the initial XML into:

<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="urn:jboss:domain:1.3">
   <extensions>
      <extension module="org.jboss.as.clustering.infinispan"/>
   </extensions>
   <system-properties/>
</server>

What is special about this is that <system-properties/> does not have `xmlns=""'. If you change XSL template to <system-properties/> instead of specifying NS with <xsl:element name="system-properties" namespace="{$thisns}"/> then you will see that empty namespace decaration added in output XML by any namespace aware XSLT processor like xalan, saxon, xsltproc, etc.

Now the magic bit so one doesn't need to hardcode the namespace URI is <xsl:variable name="thisns" select="namespace::*[name()='']"/>. This puts our matched element namespace into a variable we can later use to create the elements we want. Be careful to avoid copying or creating elements by just inlining them into the templete like a raw <system-properties/>, otherwise they will be considered no namespace instead of inheriting parent namespace. I wish there was an option to have elements inherit namespace but until then, we are stuck with complications like this one.

Credits to: http://stackoverflow.com/a/123005/520567

command line XSLT 2.0

I had troubles with with XSLT 2.0 transformations done through a system and found myself lacking a command line XSLT 2.0 tool to debug what's going on. I found saxon but it is a piece of code I can't install everywhere and I'm not sure how well does it work.

Thanks to this post I crafted a script with no external dependencies to output transformed document with first param the XSL, second param the XML to transform and the rest of params are key=value pairs if needed. Hope it helps somebody. UPDATE: xalan also has command line support

example: ./xsltJava.sh mystyle.xsl myxml.xml key1=hello


#!/bin/bash

set -e

XSL=`readlink -f "$1"`
XML=`readlink -f "$2"`
shift ; shift

TMPDIR=""
cleanup () {
   set +e
   popd > /dev/null
   [[ "$TMPDIR" ]] && rm -rf "$TMPDIR"
}

TMPDIR=`mktemp -d`
pushd "$TMPDIR" > /dev/null
trap cleanup EXIT

if [ -f "$XSL" ]; then
   cp "$XSL" mytran.xsl
   java com.sun.org.apache.xalan.internal.xsltc.cmdline.Compile mytran.xsl
else
   echo stylesheet does not exist
   exit 1
fi

if [ -f "$XML" ]; then
   java com.sun.org.apache.xalan.internal.xsltc.cmdline.Transform "$XML" mytran "$@"
else
   echo no file to transform
   exit 1
fi

Tuesday, April 3, 2012

RFC 2069 digest auth generator

Preface:
I had a bad problem with mod_proxy vs chromium vs a gwt based app. Every other browser worked fine except chromium for no obvious reason. The server was returning 403 only to chromium. And also without proxy Chromium was working fine.

After quadruple-checking everything is configured correctly I thought maybe digest (server only allows digest auth) generation is wrong with chromium... I saw a couple of digest auth issues in its bug tracker still opened.

So here's the digest generator:
# user:realm:password
HA1="$1"
# request_method:request_uri
HA2="$2"
nonce=$3

getFirst () {
echo -n "$1"
}
md5get () {
local dat="$1"
echo -n `getFirst $(md5sum -b <(printf "%s" "$dat"))`
}

HA1=`md5get "$HA1"`
HA2=`md5get "$HA2"`
res="$HA1:$nonce:$HA2"
echo responce=`md5get "$res"`
usage: run script with user:realm:password as first param, request_method:request_uri as second param and nonce as third param; for RFC 2617 you can adjust the values of HA1 and H2 you pass to the script, that's described in the wikipedia article below.
example:
./digest_auth.sh "admin:SecureRealm:securepassword" "POST:/management" 6ec791feebb1f853f4757330ffed1d8e

useful for: verifying client is computing values correctly looking at tcpdump/wireshark log
references: http://en.wikipedia.org/wiki/Digest_access_authentication
how story ended: It turned out only chromium always sends a header named "Origin". It also seems that header can give some CSRF protection so perhaps mod_proxy should learn to handle it. For the time being though this Apache HTTPD directive gets rid of the beast:
RequestHeader unset Origin

Friday, March 16, 2012

skype codec choice

I recently found that my UK calls are using PCMU. So with bad Internet calls dropped. Found a way to disable PCMU from a forum post and other sources. In ~/.Skype//config.xml:
<config>
<lib>
...
<call>
...
<disablecodecs> SILK_V3 PCMA PCMU </DisableCodecs>
</Call>
...
</lib>
</config>

For windows see this blog post.

Unfortunately this didn't help because chosen codec is g729 what I wanted but I hear only silence from the remote end. Disabling g729 makes call fail.

P.S. thanks to this guy and this tool for the xml encoding above

Thursday, February 23, 2012

bash parameter parsing from data

I had to write a script where parameters are read form a shell script. At first I thought writing a shell function to extract values would be nice and if it could allow shell syntax and quoting that would also be nice so here it is:
get_param() {
    local paramname="$1"
    local result=""

    local IFS="
"
    for line in $SCRIPT_DATA; do
        unset IFS
        line=${line%%#*} # removed any comments
        case "$line" in
        *"$paramname"=*)
            # lets check we are not matching only suffix of param
            case `echo ${line%%=*}` in
            $paramname) result=`eval "$line ; echo \"\\${$paramname}\""` ;;
        esac
        ;;
        esac
    done
    echo -n "$result"
}

if SCRIPT DATA is like:
param1=value1
hostname=`hostname`
paramN=valueN


get_param hostname would return the hostname of machine.

If SCRIPT_DATA is like:
hostname='`hostname`'

get_param hostname would return `hostname` avoiding expansion.

A couple of limitations:
  • control structures are not regarded
  • not secure (run only through trusted code)
  • multi-line expressions not supported
After all I decided complexity isn't worth it so just source/eval the script data. If necessary use grep/sed to filter it.
Maybe it would have been more useful if I could split the script data to complete shell expressions but I'm not sure added complexity will be worth it either.

In any case I just put this function here to not lose it. Similar use cases pop from time to time...

Saturday, February 4, 2012

batch convert to MP3

I've got a car MP3 player and immediately found out all my music is in various formats and it's a pain to copy something over to the player with the correct format.
Searching the net didn't show something reasonable for mass/batch/bulk converting files to mp3, at least not something that would really make the job easier. So I thought it's time for some bash again.
Here I have a script that given a list of sources which can be directories and files and a destination will go over known music files in sources and copy them to the destination with their relative paths preserved *AND* converted to MP3.
Conversion is performed by playing the file through mplayer which feeds pcm audio data to the lame mp3 encoder stdin. So a wide range of input formats are supported even video files where the first audio stream is processed.

Usage:
./cp2mp3.sh <src1> ... <srcN> <dst>


For example if you have:
$ find
./file1.flac
./dir1/file2.ogg
./dir2/dir3/file3.wav
./dir4/dir5/file4.avi
and run:
./cp2mp3.sh file1.flac dir1 dir2 dir4/dir5 <somedir>
you will end up with:
$ cd <somedir>
$ find
./file1.mp3
./dir1/file2.mp3
./dir2/dir3/file3.mp3
./dir5/file4.mp3


Script may need some small modifications depending lame or mplayer locations, lame/mplayer settings, additional file extensions might be necessary, stuff like that, but generally I think its ready to use.


Download it from here and let me know how it works for you. And before I forget again, file is licensed under GPLv3.

Friday, January 20, 2012

IP request filtering in JBoss and Tomcat

I just needed to allow only particular IPs to have access to a servlet or web app and was somehow surprised IP filtering of requests is not part of the standards. The portable way of doing so is to write a custom filter [1] [2] but this is not something I want to bother with.
Fortunately JBoss AS has this capability OOB being based on Apache Tomcat which has a valve to help with that [3]. update: Wildfly, the JBoss AS new name will be using undertow as the servlet and web server engine so this won't work on it.

In short you can create a file WEB-INF/context.xml for JBoss or see docs [4] for Tomcat with content like:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="192.168.*,142.104.128.*"/>
</Context>

[1] http://www.roseindia.net/servlets/ip-filter-example.shtml
[2] http://stackoverflow.com/questions/2869623/how-to-block-a-ip-address-using-web-xml
[3] http://hcmc.uvic.ca/blogs/index.php?blog=30&p=2658&more=1&c=1&tb=1&pb=1 - I've started here and saved me lots of time
[4] http://tomcat.apache.org/tomcat-5.5-doc/config/context.html