1&1 USB Surfstick with OpenWRT

Due to my new provider being somewhat slower at connecting my phone line than expected I currently do not have a wired internet connection. As not having internet is no longer an option in my household, I managed to convince customer support to send me a surf-stick (3g USB dongle) to bridge the gap until my landline goes live. (Interestingly enough no one at my household seems to care about the fact that we do not have a landline telephone to use. Apparently that is no longer an issue in 2015...)

Of course these sticks are only supposed to be used on a single WIndows PC, forcing some crap software with a horrible UI on the user. As I am definitely not alone in the household and tend to have more than one device online at any one time, that was certainly not an option for me.

Thus I tried plugging it into my OpenWRT Router.

The good news - It almost works out of the box with OpenWRT. That is, it works once you get the stick to actually act as a 3g dongle and stop pretending to be a CD-drive, The bad news is - for some reason it isn't recognized by USB-Modeswitch and thus it never stops pretending.

On the box it says it is a ZTE-MF190v - and that small 'v' at the end means its not quite as well known as the MF190. If you stick into a Linux Mint 17 PC usb-modeswitch simply will not react at all. The Vendor ID 0x19d2 and Product ID 0x2000 are apparently not known.

Even trying the most similar configuration (for the ZTE MF620 which has the same Product ID in USB Mode), found here (http://www.draisberghof.de/usb_modeswitch/device_reference.txt) has no effect.

Thus I was forced to install the USB stick on my partners PC (the last Windows PC left in the household). Then I followed the instructions given here:
http://www.3g-modem-wiki.com/page/executing+AT-commands+under+Windows
and issued the following AT command using putty.

----

AT+ZCDRUN=8

----

That command disables the 'pretend' CD-mode that simply wouldn't go away on my linux box.

The end result - the stick works beautifully as a 3g dongle. It also has a micro-sd card slot that is recognized just fine. Installing it on OpenWRT works just as explained in the instructions here:

http://wiki.openwrt.org/doc/recipes/3gdongle

Although I recommend not even bothering with the usb_serial_generic driver as using the usb_serial_option driver did the trick for me!

Freifunky

After setting up my new router (described here), I've decided that only using TOR is not enough. Thus I've added 'Freifunk' functionality to the router as well.

Thankfully the Freifunk firmware is completely based on OpenWRT. After all that effort getting my router to work properly I didn't want to just re-flash everything and losing all of the settings I had just added.

Instead I got myself a copy of the current firmware (http://fw.freifunk-rhein-neckar.de/) and unzipped it. Then I followed the instructions on the wiki to manually configure my router to join the Freifunk network.

Sadly the instructions were not completely applicable - as is stated on the site itself they were slightly out of date. Also I wanted to keep my firewall settings as complete as I could - so I had to change some of the /etc/config/firewall rules to keep my settings.

But in the end I was able to connect to the Freifunk net using client hardware! So I assume everything is working as it should. Yay for free (as in freedom) internet!

Securing your WDR3600

After hearing about exactly how much of my communication is secure and private I decided to do something about it. These Posts will be more or less a series of guides on how to increase your privacy online.

This is Part 1: Securing my router. My goals are:

  • Logging which sites I have visited
  • Reducing the amount of advertising I have to put up with (Privoxy)
  • Making it harder for others to know which sites I have visited (TOR)
  • Using software that is not trivial for crackers to exploit (OpenWrt)

NOTE: Although this is a step-by-step guide, it does require you to have at least some experience in command line Linux. Additionally I cannot guarantee that it will work for you.

0. Get some hardware that you can modify

I won't describe this part in too much detail - basically any router that can run OpenWRT should do. For bonus points (i.e. more logging) I would definitely recommend a router with at least one USB Port. That way it is trivial to add more storage space.

At the time of me writing this, the TP-Link TL-WDR3600 was a pretty good deal, with Gigabit-LAN, USB and 5GHz wireless - so the post will deal with this hardware. If you have another router, you will need to substitute hardware specific links where necessary.

1. Install and setup OpenWRT on your router

For the TL-WDR3600 I just followed the instructions at here:

NOTE: If you want to install the latest version of OpenWRT (barrier-breaker 14.07) I recommend simultaneously enabling attitude-adjustment packages by adding the following line to /etc/opkg.conf. (Just behind the similar line for barrier_breaker.

src/gz attitude_adjustment htp://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages

For some reason not all packages are always available for barrier-breaker. By also having the attitude-adjustment link in opkf.conf opkg will fall back to older packages whenever this is the case.

1b Connect to the web as a routed client (optional)

To fully install OpenWRT you will need an internet connection. If you are somewhat 'paranoid' you might not want to directly connect to the internet until OpenWRT has been fully set up. If that is the case you will need to set it up as a routed client by reconfiguring the WAN port.

Another benefit is that the PAF (Partner Acceptance Factor) will rise if the Internet is still available while you are configuring :-)

See here if you want to do this using wireless:

3 Monitor Traffic Levels

(important for QoS at some point)

If you want to keep stats across reboots you need to edit vnstat.conf to not use the /var/* directory (as var is mapped to tmp)

4 Install & configure privoxy

By using privoxy we can speed up the web by blocking unnecessary ads and simultaneously keep a log of visited sites. The logs will be a big help later when we are trying to create white- and blacklists for tor.

NOTE: to properly analyze the log files later the log file format should be the Common Format. This is done by adding the following line to /etc/privoxy/config

------

  debug 512

------

5 Install TOR

This step is only necessary if you want to obfuscate which sites you are visiting. If everyone where to do this, the secret services of our countries would once again be able to concentrate on their real jobs - instead of trying to capture everyones metadata. If you want to use TOR you will experience a slightly laggier and less reliable internet connection. But even if you do not use Tor for your connections, please consider setting up a relay so that those of us without a choice can at least experience some sort of 'free' internet.

Run the following commands on the command line of your router.

----

	ipkg update
	ipkg install tor
	/etc/init.d/tor enable
	/etc/init.d/tor start

----

NOTE: If you want to run a tor relay and also use tor for your connections you will need to run two separate tor processes. Else if you set up a bandwidth limit you will no longer be able to surf the net once the limit is reached. (Learned this the hard way...)

To do so, you need to copy the /etc/tor/torc file and edit it to only run as relay. Then copy /etc/init.d/tor and modify it to use the second torc file.

Finally enable your copy (I called it /etc/init.d/tor.relay)

6 Combine privoxy and tor

By first moving all traffic to privoxy and then to TOR we have two advantages:

  • We can block most ads thus improving our online experience
  • We can analyze which websites use the most traffic - so that we can whitelist those sites to not use tor
Aside: There is no point in shuffling ALL of your traffic through tor. Sites like Facebook track what you are doing anyway and will report this information to anyone requesting it. Streaming videos through tor is not much fun, so it makes sense to whitelist youtube, etc.

Add the following lines to /etc/privoxy/config (Assuming your network is on 192.168/16)

----

  forward-socks5 / 127.0.0.1:9050 .
  forward 192.168.*.*/ .

----

NOTE: The filter doesn't need to be finegrained as only non-whitelisted traffic will be passed on to privoxy

NOTE2: This will only move http traffic from privoxy through tor, as secure traffic cannot be read by it. (Else you would be using it as an intercepting proxy - which is something you don't want)

7 Move non-privoxy (e.g. https) traffic directly to tor:

This guide will move all traffic through tor:

We only need the /etc/tor/torrc and the /etc/firewall.user part. Both need to be modified to use the interface br-lan and the correct ip address.

8 Whitelist traffic (from tor)

After first forcing everything through tor we now need to whitelist some traffic to not pass through tor. The hardest part is getting a list of sites we need to whitelist.

We will use the privoxy logs we enabled earlier to see which sites tend to fail, and/or are called often. These sites we will then whitelist.

Sadly this is not trivial, as most websites these days tend to link and stack quite deeply. Thus simply whitelisting a single IP for facebook won't work.

To start we create an ipset with whitelisted sites and pass this ipset to iptables. Frst install the packages:

  ipset iptables-mod-ipset kmod-ipt-ipset

Then edit: /etc/config/firewall - add the lines before the firewall.user include

----

  config include
  option path '/etc/firewall.whitelist

  config include
  option path '/etc/firewall.blacklist

-----

Create the file /etc/firewall.whitelist with the content

----

  ipset create whitelist hash:ip -exist
  ipset add whitelist 192.168.2.0/24
  ...add your sites here

----

And /etc/firewall.blacklist

----

  ipset create blacklist hash:ip
  ...add your sites here

----

Modify /etc/firewall.user to use the "whitelist" and "blacklist" ipsets.

----

  # Move DNS requests to tor
  iptables -t nat -I PREROUTING -i br-lan -p udp --dport 53 -j REDIRECT --to-ports 9053

  # Drop all blacklisted traffic
  iptables -t raw -I PREROUTING -i br-lan -m set --match-set blacklist dst -j DROP

  # Move any http traffic to privoxy
  iptables -t nat -A PREROUTING -i br-lan -m set ! --match-set whitelist dst -p tcp --dport 80 --syn -j REDIRECT --to-port 8118

  # Move remaining traffic straight to tor
  iptables -t nat -A PREROUTING -i br-lan -m set ! --matchset whitelist dst -p tcp --syn -$

----

NOTE: this means that only those addresses that are NOT in your whitelist will be passed to tor

NOTE2: To increase the PAF you can comment out the last line until the whitelist is well defined. If you do this, then you will also need to remove the last lines of /etc/privoxy/config which you added in step 6.

Finally, modify /etc/config/firewall to no longer redirect (as it is does exactly the same thing as the 3rd line in firewall.user)

----

#config redirect
# option proto 'tcp'
# option target 'DNAT'
# option dest 'lan'
# option name 'intercepting-proxy for HTTP'
# option src 'lan'
# option dest_port '8118'
# option src_dport '80'
# option dest_ip '192.168.2.1'
# option src_dip '!192.168.2.1'

----

9 Creating sensible white/blacklists

See the section on parsing the privoxy logs below.
Any sites you really do not want to visit - for example anything with 'ad' in the URL tends to be a good start - can go in the blacklist.

9a Resolving hostnames

Sipmply adding hostnames to the ipset is sadly not very useful - and not recommended.

  • Only the first IP address will be used
  • If the DNS Record changes the firewall will not care (it resolves only once)
Thus we need to write a script that will resolve the hostnames that we have gathered (somewhere...) to all possible IPs - and then run that script periodically

(Edited from here as openwrt does not have host):

/usr/bin/rebuild_fw_lists.sh (needs to be created and chmodded)

----

#!/bin/ash

#NOTE: we could skip building the files /tmp/xxxxlist.ip, but this way it
#      is easier to see what everything resolves to.

rm /tmp/whitelist.ip
rm /tmp/blacklist.ip

#build a list of IPs using nslookup and the hostnames in /root/hostnames.whitelist
for ipaddress in $(egrep -h -v -E "^#|^$" /root/hostnames.whitelist); do
   nslookup $ipaddress | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])' | grep -v 127.0.0.1 >> /tmp/whitelist.ip
done

#build a list of IPs using nslookup and the hostnames in /root/hostnames.blacklist
for ipaddress in $(egrep -h -v -E "^#|^$" /root/hostnames.blacklist); do
   nslookup $ipaddress | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])' | grep -v 127.0.0.1 >> /tmp/blacklist.ip
done

#shutdown the firewall so that we can rebuild the lists
/etc/init.d/firewall stop

#then delete any sets we have
/usr/sbin/ipset destroy whitelist
/usr/sbin/ipset destroy blacklist

#restart the firewall (and thus rebuild the lists)
/etc/init.d/firewall start

#now we can add our ips to the ipsets
for ipaddress in $(egrep -h -v -E "^#|^$" /tmp/whitelist.ip); do
ipset add whitelist $ipaddress
done

for ipaddress in $(egrep -h -v -E "^#|^$" /tmp/blacklist.ip); do
ipset add blacklist $ipaddress
done

----

We want to execute this file periodically so that any changes in dns-records are reflected in our ipsets. Thus we use cron by adding the following line to the crontab file /etc/crontabs/root

----

  01 03 * * * /usr/bin/rebuild_fw_lists.sh

----

10 Additional logging

Openwrt does not log a lot. Also any logs that are created are not rotated and stored in /tmp (and thus deleted at every reboot).

To get the system logs into a file, add the following line to the system section of /etc/config/system

-----

  option log_type 'file'

----

From here: (Needs a reboot to work)

To get logs that survive a reboot, we need to move /var/log away from the tmpfs

(Only do this if you have the space available.) If you have a router with an USB port - and have set it up as described in the links above you should have plenty of space for logs.

I back up my logs to /usr/share/log_save

----

  mkdir /usr/share/log_save

----

Edit the startup script /etc/init.d/boot New lines between mkdir -p /var/log and mkdir -p /var/lock

----

  cp -r /usr/share/log_save/* /var/log/
  chown tor /var/log/tor -R

----

To get rotating logs we need to use logrotate. Install the package logrotate (depends on libpopt apparently)

Either edit /etc/logrotate.conf directly or add files in /etc/logrotate.d (I guess the latter is cleaner but maybe slightly overkill) At the end of logrotate.conf add the files you want to rotate

----

  /var/log/privoxy
  /var/log/tor/notices.log

----

Finally edit crontab to rotate (and save) the logs

----

  01 03 * * * /usr/sbin/logrotate /etc/logrotate.conf
  */5 * * * * /bin/cp -r /var/log/* /usr/share/log_save

----

12 Parsing the logs

After all this effort we have some privoxy log files formatted in CLF. (See the section on privoxy above.)

To get some sensible data out of these we will use analog, but as analog is designed for servers (and not for proxy log files), we will need to reparse the privoxy log files.

  1. We only need the request parts of the files
  2. We want to reverse the source and who requested the file (after all we are the client, and not the server)

To achieve this I created the following script: extract.sh

----

#!/bin/bash

gunzip -c log_save/privoxy.4.gz | grep  "^192\.168\.2\.[0-9]* -" > privoxy.clf
gunzip -c log_save/privoxy.4.gz | grep  "Request: " > privoxy.request
paste -d '\n' privoxy.request privoxy.clf | sed "N;s/^.*Request: \([^/]*\).*\n\([0-9.]*\) - - \(.*\)$/\1 - \2 \3/"  > log_save/privoxy.log

gunzip -c log_save/privoxy.3.gz | grep  "^192\.168\.2\.[0-9]* -" > privoxy.clf
gunzip -c log_save/privoxy.3.gz | grep  "Request: " > privoxy.request
paste -d '\n' privoxy.request privoxy.clf | sed "N;s/^.*Request: \([^/]*\).*\n\([0-9.]*\) - - \(.*\)$/\1 - \2 \3/"  >> log_save/privoxy.log

gunzip -c log_save/privoxy.2.gz | grep  "^192\.168\.2\.[0-9]* -" > privoxy.clf
gunzip -c log_save/privoxy.2.gz | grep  "Request: " > privoxy.request
paste -d '\n' privoxy.request privoxy.clf | sed "N;s/^.*Request: \([^/]*\).*\n\([0-9.]*\) - - \(.*\)$/\1 - \2 \3/"  >> log_save/privoxy.log

gunzip -c log_save/privoxy.1.gz | grep  "^192\.168\.2\.[0-9]* -" > privoxy.clf
gunzip -c log_save/privoxy.1.gz | grep  "Request: " > privoxy.request
paste -d '\n' privoxy.request privoxy.clf | sed "N;s/^.*Request: \([^/]*\).*\n\([0-9.]*\) - - \(.*\)$/\1 - \2 \3/"  >> log_save/privoxy.log

more log_save/privoxy | grep  "^192\.168\.2\.[0-9]* -" > privoxy.clf
more log_save/privoxy | grep  "Request: " > privoxy.request
paste -d '\n' privoxy.request privoxy.clf | sed "N;s/^.*Request: \([^/]*\).*\n\([0-9.]*\) - - \(.*\)$/\1 - \2 \3/"  >> log_save/privoxy.log

rm privoxy.clf privoxy.request

----

This script expects 4 log files (for 4 weeks) in the folder log_save. The end result will be a single file log_save/privoxy.log which we can parse using analog (see http://www.analog.cx/)

After installing analog, we need the following configuration file: analog.conf

----

OUTFILE privoxy_%y%M%D.html
HOSTNAME "phoenix Internet"
HOSTURL "phoenix-nas.ddns.net"

DOMCOLS RrPpBb
DOMSORTBY BYTES
SUBDOMSORTBY BYTES
SUBDOMAIN *.*.*.*.*
ORGCOLS RrPpBb
ORGSORTBY BYTES
SUBORG *.*.*
SUBORGSORTBY BYTES
DIRCOLS RrPpBb
DIRSORTBY BYTES
SUBDIR */*/*/*/*/*/

----

Then we can run analog with the following command:

----

  analog +ganalog.conf log_save/privoxy.log

----

and finally open the resulting html file in your browser. Using the domain report you can pick the domains which use the most data. In my household these tend to be the typical cases: dropbox, microsoft update, linux update, android store and video streaming sites.

Use these domains to blacklist or whitelist as wanted.

Note: Once you are somewhat confident that your whitelist is complete I would recommend disabling the logging that privoxy does, as the logs tend to take up quite some space.

Conclusion

If you managed to get to here, you should now have a router that:

  • No longer uses some default firmware by a manufacturer that quite frankly won't provide updates until it is too late anyway. That doesn't mean that OpenWRT is perfect, but it is easier to keep up to date.
  • Filters out quite a bit of the advertising that makes some parts of the web more or less unusable
  • Will block any traffic to domains you wish to avoid
  • Will obfuscate your browsing habits to the outside world by moving (almost) everything through TOR
  • Enables those of us on the web that do not have access to an uncensored internet to browse the full web

Heatmapping your home with digitemp

After spending some time (quite a bit of it improving on my rusty soldering iron skills) setting up some temperature sensors around the home I came to the realization that I don't really care about graphs plotting the past temperature - I just want a pretty picture telling me how warm it is.

If this interests you, here are some pointers (instructions is really to big a word) to get you on your way to something similar.

My goal was to set up digitemp so that the output could be parsed into a scalable vector graphic representing my floor layout. This image would then be returned by my webserver whenever someone wants to see the temperature.

Set up your sensors and get some readouts

For some excellent instructions on setting up the sensors see here: http://www.instructables.com/id/Temperature-sensor--weatherstation/?ALLSTEPS. I can only recommend using the DS1820 sensors and digitemp, as getting everything running is really cheap - I bought everything twice not trusting my soldering skills and still had a BOM of < 20€. Also using telephone cable to wire everything up is also simple to do.

I ended up building the 'improved' serial connector which supplies power on a separate line instead of on the data line - as I wanted to make sure even if I run wires all over the place I will still get a stable connection. And because (as stated) using telephone cable meant I had some cables spare for the power line. See instructions here (German - but the schematics should be understandable): http://www.lax.priv.at/digitemp/

Once you are finished you should be able to run the folowing command to read the temperature output of your connected sensors.

----

digitemp -a

----

Create a SVG of your floor layout

A SVG is a scaleable vector graphic. The good thing about them is, that - uncompressed - they are simply xml files, which makes them extremely easy to change on the fly. Using Inkscape, I drew some lines representing my outer walls and then created grey rectangles for each room. The colour will be replaced by the temperature colour later. Make sure you only create one shape for each room - as that will make things easier later.

Then enter some text (e.g. two question marks) in each room - this will be replaced by the temperature as number.

Finally (not really necessary) I added a scale, displaying each temperature in 1 degree steps on top of a colour range representing each temperature.

If you are using Inkscape (or probably any SVG editor) you should now edit the IDs of your room shapes/rectangles to title<number> and tspan_<number>. Here each number corresponds to a room as identified by digitemp. (Just start with 0 and add 1 for each room - more on that later).

Because I am calling cthulhu and parsing the svg xml using a regex, we will need to make sure that the XML attributes are in the right order. The 'fill' attribute for the room shapes/rectangles needs to be just in front of their 'title id=title<number>' element.

My resulting SVG can be downloaded here, I assume that will clear things up.

Aside - convert temperature into a colour range

To make the temperature nice and easy to read, I wanted to replace the background colour of each room with a corresponding colour - red for hot, green for warm and blue for cold.

I did this by plotting the RGB values of the colour range I added to my SVG above and then created several linear functions to increase/decrease the individual RGB values to stay as close to the colour range as above. The following table describes my colour steps (which are entirely arbitrary)

Temperature

Red Value

Green Value

Blue Value

<11 FF 00 FF
<15.8 FF->00 00 FF
<19.82 00 00->FF FF
<21.41 00 FF FF->00
<26.92 00->FF FF 00
<32.11 FF FF->00 00
else FF 00 00

Combine everything for your webserver

To make it easier to read the digitemp output, I reconfigured the digitemprc file slightly to produce a very minimal output: <room number>:<temperature>.

----

TTY /dev/ttyUSB0
READ_TIME 1000
LOG_TYPE 1
LOG_FORMAT "%s:%.2C"
CNT_FORMAT "%m %d %H:%M:%S Sensor %s #%n %C"
HUM_FORMAT "%m %d %H:%M:%S Sensor %s C: %.2C H: %h%%"
SENSORS 4
ROM 0 0xAB 0xCD 0xEF 0x01 0x02 0x03 0x04 0x05 
ROM 1 0xAB 0xCD 0xEF 0x01 0x02 0x03 0x04 0x06 
ROM 2 0xAB 0xCD 0xEF 0x01 0x02 0x03 0x04 0x07
ROM 3 0xAB 0xCD 0xEF 0x01 0x02 0x03 0x04 0x08 

----

You will need to rearrange your sensors to fit in with the room numbering that you used in your svg above. To make that easier just hold each sensors in your hand for a few minutes before taking a new readout. The warm sensor will be in the room you are in.

As this was a quick hack, I simply ended up hooking up a bash script as a cgi response for my webserver.

The script calls digitemp using the config file above, and then creates color values for each temperature response.

The result is then passed into the svg which it assumes to be in the same directory.

----

#!/bin/bash

echo "Content-type: image/svg+xml; charset=UTF-8"
echo ""

# Get the SVG into a var
image=$(cat ./Grundriss.svg)

# First get temperatures into array temps
#digitemp -q -a -c /<location of your config file>/digitemprc
temps=$(digitemp -q -a -c /<location of your config file>/digitemprc)

# Now we build up a regex using these strings.
# fill:#949494">\n<title id="title0
# and id="tspan_0">??</tspan
for x in $temps
do
	id=$(echo $x | cut -f1 -d:)
	temp=$(echo $x | cut -f2 -d: | sed 's/\./\\./g')
	temp_num=$(echo $x | cut -f2 -d:)
	red="00"
	green="00"
	blue="00"
	if (( $(bc <<< "$temp_num < 11") == 1 )); then
		red="FF"
		green="00"
		blue="FF"
	elif (( $(bc <<< "$temp_num < 15.8") == 1)); then
		red=$(echo "obase=16; 255*-($temp_num-15.8)/4.8" | bc)
		printf -v red "%02X" "0x"$red
		green="00"
		blue="FF"
	elif (( $(bc <<< "$temp_num < 19.82") == 1)); then
		red="00"
		green=$(echo "obase=16; 255*($temp_num-15.8)/4.02" | bc)
		printf -v green "%02X" "0x"$green
		blue="FF"
	elif (( $(bc <<< "$temp_num < 21.41") == 1)); then 
		red="00"
		green="FF"
		blue=$(echo "obase=16; 255*-($temp_num-21.41)/1.59" | bc)
		printf -v blue "%02X" "0x"$blue
	elif (( $(bc <<< "$temp_num < 26.96") == 1)); then 
		red=$(echo "obase=16; 255*($temp_num-21.41)/5.55" | bc)
		printf -v red "%02X" "0x"$red
		green="FF"
		blue="00"
	elif (( $(bc <<< "$temp_num < 32.11") == 1)); then 
		red=="FF"
		green=$(echo "obase=16; 255*-($temp_num-32.11)/5.15" | bc)
		printf -v green "%02X" "0x"$green
		blue="00"
	else
		red="FF"
		green="00"
		blue="00"
	fi
	patterncf='fill:#949494"><title id="title'$id'">'
	patterncr='fill:#'$red$green$blue'"><title id="title'$id'">'
#	echo $patterncf
#	echo $patterncr
	image=$(sed -e s/"$patterncf"/"$patterncr"/g <(echo $image)) 
	
	patternf='id="tspan_'$id'">??<\/tspan'
	patternr='id="tspan_'$id'">'$temp'<\/tspan'
	image=$(sed -e s/"$patternf"/"$patternr"/g <(echo $image)) 
done

echo $image

exit 0

----

I have embedded the output as image in a web page. You can of course do something else with it.

Mari0 without a keyboard

Update: I've moved the file to github, so that I can improve on it if required

One of the advantages of using an HTPC instead of just getting a Smart TV or something similar, is that you can do more than just watch TV. You can play games too!

After installing XBMC on a tiny PC I decided that it would be fun to install some Add-Ons that would let me play games. Obviously I didn't want to use a keyboard, so I got myself some Xbox 360 wireless controllers. The hardware is excellent, and they work with linux.

The next problem was getting good games to play. My definition of good included "multiplayer" as there was no point in me sitting in front of the living room TV by myself to play games - I have a proper PC for that. Instead I was looking for games that I could play with my partner quickly without much fuss.

One game I stumbled across was Mari0. If you haven't heard of it, and still remember the fun you had playing Super Mario on a NES (or on a Gameboy in my case), I highly recommend you to download it: http://stabyourself.net/mari0/

So you'd think all is well - but then why would I bother writing this post. Sadly, although Mari0 makes it easy to play using any controller you wish to use, the menu only works with a keyboard. That clearly wouldn't do for a PC sitting in the living room that hasn't seen a keyboard since it was set up.

Thus I gathered up whatever rusty Lua skills I had (none, but thankfully it's just your run of the mill procedural language) and decided to enable my controllers in the necessary menus. I was too lazy to extend this to all of the menus, so the downloadable add-ons menu DOES NOT work.

Thus if you happen to have Xbox 360 controllers and want to play Mari0 on your TV - this patch is for you!

----

Mari0-joystick-menu 

----

To use it:

  • Download the source package of Mari0 1.6 - http://stabyourself.net/dl.php?file=mari0-1006/mari0-source.zip
  • Extract the zip AND the inner .love file (which is simply a zip file). If your file manager is confused you can rename mari0_1.6.love to mari0_1.6.zip first
  • NOTE: the resulting folder needs to be called mari0_1.6.love_FILES (or you need to change the command below)
  • Now you can apply the patch using the following commands

----

cd mari0-source
patch -d mari0_1.6_FILES --dry-run  mari0_xpad.patch

----

After you repackage the mari0_1.6_FILES folder back into a zip and rename it .love you should be able to control the game using the controllers even when in a Menu.
Enjoy!