Friday, June 27, 2014

Why I Hate Java, pt. 1

To get the body of an HttpResponse as a string, you have to do this:

HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
InputStreamReader contentReader = new InputStreamReader(content);
BufferedReader reader = new BufferedReader(contentReader);
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
    builder.append(line);
}

Am I the first person on the internet to ever do this? Why on earth isn't there a convenience method like getEntityText() or something?

Thursday, August 22, 2013

ssh to ipv6 link-local host

What I wanted to be able to do was run my Raspberry Pi as a headless server, and just plug an ethernet cable into it from my laptop and ssh in. Is that so much to ask? I expected it to be automatic with ipv6, since it has automatic host discovery built in. No so much.
  1. ipv6 is not enabled on a Raspberry Pi by default. Edit /etc/modules.conf and add a line for "ipv6". Reboot.
  2. You need to know what address to connect to. ip neigh will show you your neighboring IPs, but it doesn't know about the link-local hosts; you need to ping them first. But you need their addresses to ping them, don't you? The secret is to ping the magic link-local address, ff02::1. Then ip neigh will tell you what you need to know.
    $ ping6 -c 1 -I eth0 ff02::1
    PING ff02::1(ff02::1) from fe80::226:2dff:fef9:3f85 eth0: 56 data bytes
    64 bytes from fe80::226:2dff:fef9:3f85: icmp_seq=1 ttl=64 time=0.050 ms
    
    --- ff02::1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.050/0.050/0.050/0.000 ms
    $ ip -6 neigh
    fe80::ba27:ebff:feb6:6647 dev eth0 lladdr b8:27:eb:b6:66:47 DELAY
    
  3. Ok, I've got the address, but ssh fails with a cryptic "Invalid argument" message.
    $ ssh -6 pi@fe80::ba27:ebff:feb6:6647
    ssh: connect to host fe80::ba27:ebff:feb6:6647 port 22: Invalid argument
    
    This is because ssh (actually, the kernel) doesn't know which interface to talk to. Adding a route for the link-local host doesn't seem to work:
    $ sudo route -A inet6 add fe80::ba27:ebff:feb6:6647/128 dev eth0
    $ route -A inet6 | grep eth0
    fe80::ba27:ebff:feb6:6647/128  ::                         UH   1   0     0 eth0
    fe80::/64                      ::                         U    256 0     0 eth0
    ff00::/8                       ::                         U    256 0     0 eth0
    $ ssh -6 pi@fe80::ba27:ebff:feb6:6647 
    ssh: connect to host fe80::ba27:ebff:feb6:6647 port 22: Invalid argument
    
    So instead, I specified the interface in the ssh hostname (by adding it after a '%'). Here's what that looks like:
    $ ssh -6 pi@fe80::ba27:ebff:feb6:6647%eth0
    pi@fe80::ba27:ebff:feb6:6647%eth0's password: 
    
    scp has a similar problem, and it also uses colons to separate hostname and filename, so you have to put the colon-laden ipv6 address inside square brackets
    $ scp -6 my_file.txt pi@fe80::ba27:ebff:feb6:6647%eth0:
    ssh: Could not resolve hostname fe80: Success
    lost connection
    $ scp -6 my_file.txt pi@'[fe80::ba27:ebff:feb6:6647%eth0]':
    pi@fe80::ba27:ebff:feb6:6647%eth0's password: 
    
I ended up writing a shell script to do all that setup for me:
#!/bin/bash

user=$1
test -n "$user" || user=pi

iface=eth0

# Find the ipv6 address for our link-local host
linkhost=`ip -6 neigh | cut -d ' ' -f 1`
if test -z "$linkhost" ; then
    ping6 -c 1 -I $iface ff02::1 >& /dev/null
    linkhost=`ip -6 neigh | cut -d ' ' -f 1`
fi
echo "Found link local host $linkhost"

echo "ssh -6 -X $user@$linkhost%$iface"
ssh -6 -X $user@$linkhost%$iface

Friday, May 10, 2013

Wireshark Config

Wireshark is a GUI tool, so it runs as your normal user, but it needs to be able to capture packets, which is normally a superuser thing. There is a facility for giving a normal user limited permissions to capture packets, but that's not something you want enabled by default. All good and reasonable, but it has the unfortunate consequence that you can't actually do anything with Wireshark out of the box. Fortunately, they make it pretty easy to enable your permissions. You can just run this, and it brings up an ncurses UI to let you enable non-root packet capture.
$ sudo dpkg-reconfigure wireshark-common
It sets up a wireshark group and gives it permission to capture packets (using the dumpcap utility). Then you need to add yourself to the wireshark group.
sudo usermod -a -G wireshark myuser
You'll have to log out and back in for your user session to have the right permissions.

Wednesday, May 2, 2012

JSON pretty-printing

Today's magic invocation is for pretty-printing JSON strings. If I hit a REST service with my browser, I get back a wad of JSON, which is great, but a bit hard to read. In Chrome (at least), I can pop open the Javascript console and run this:
JSON.stringify(JSON.parse(document.body.children[0].textContent), null, 4)
The JSON is actually displayed by Chrome as text in a <pre> block, which is the only element on the page (child 0 of body). So I have to grab that text, parse it into JSON, and then pretty-print it using stringify (with a 4-space indent). Thanks to Stackoverflow for pointing me in the right direction.

Monday, April 16, 2012

vim config w/ pathogen

From article on Vim plugin management

What I actually did was install pathogen as per https://github.com/tpope/vim-pathogen (more or less)

mkdir -p ~/.vim/autoload ~/.vim/bundle; curl -so ~/.vim/autoload/pathogen.vim https://raw.github.com/tpope/vim-pathogen/HEAD/autoload/pathogen.vim
echo -e "\n\ncall pathogen#infect()\n\n" >> ~/.vimrc

Then manually install just the few plugins I really wanted.

cd .vim/bundle/
git clone git://github.com/pangloss/vim-javascript.git
git clone git://github.com/timcharper/textile.vim.git
git clone git://github.com/tpope/vim-markdown.git
git clone git://github.com/nono/vim-handlebars.git
git clone git://github.com/kchmck/vim-coffee-script.git
mkdir jQuery
curl -o jQuery/jquery.vim http://www.vim.org/scripts/download_script.php?src_id=15752

Saturday, February 11, 2012

Disable touchpad tap-to-click

I'm on Xubuntu now, and the settings manager doesn't have any way to disable tap-to-click on the touchpad. Found the solution on the Ubuntu forums:

/usr/bin/synclient MaxTapTime=0

The instructions also say how to get this to run on startup.

Tuesday, January 31, 2012

Javascript in Eclipse

The problem: In Eclipse on my Windows machine at work, I get an error attempting to open Javascript files, and have to open them as plain text.

After a bit of Googling around, I ended up using the JSEditor plugin. There doesn't seem to be an update site for it, so I downloaded it from

http://sourceforge.net/projects/jseditor/

To install it, cd into the eclipse directory (with the 'plugins' subdir), and unzip it. Then restart Eclipse.

Jekyll Pages List

Getting a list of pages in a Jekyll site is easy, but paring that down to just the top-level files and the index pages is tricky. {% for p...