<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bluish Coder</title>
 <link href="http://bluishcoder.co.nz/atom.xml" rel="self"/>
 <link href="http://bluishcoder.co.nz/"/>
 <updated>2013-06-11T01:22:17+12:00</updated>
 <id>http://bluishcoder.co.nz/</id>
 <author>
   <name>Chris Double</name>
   <email>chris.double@double.co.nz</email>
 </author>

 
 <entry>
   <title>Editing remote files with Acme in Inferno OS</title>
   <link href="http://bluishcoder.co.nz/2013/06/11/editing-remote-files-with-acme-in-inferno-os.html"/>
   <updated>2013-06-11T01:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/06/11/editing-remote-files-with-acme-in-inferno-os</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.vitanuova.com/inferno/'&gt;Inferno OS&lt;/a&gt; ships with a version of the &lt;a href='http://acme.cat-v.org/'&gt;acme&lt;/a&gt; text editor. I&amp;#8217;ve tried to use acme on and off for a bit and it never stuck. I&amp;#8217;ve always been a &lt;code&gt;vim&lt;/code&gt; and &lt;code&gt;emacs&lt;/code&gt; user. Recently I watched a video by Russ Cox called &lt;a href='http://research.swtch.com/acme'&gt;A Tour of Acme&lt;/a&gt; that motivated me to try it again.&lt;/p&gt;

&lt;p&gt;The video is short and covers a lot of what makes Acme interesting. Most of it is related to the extensibility of the editor via shell commands dealing with piped input and output alongside the power of &lt;a href='http://sam.cat-v.org/'&gt;sam&lt;/a&gt; editing commands.&lt;/p&gt;

&lt;p&gt;Some useful acme papers and tutorials are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://research.swtch.com/acme'&gt;A Tour of Acme&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://doc.cat-v.org/plan_9/4th_edition/papers/acme/'&gt;Acme: A User Interface for Programmers&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://man.cat-v.org/inferno/1/acme'&gt;Acme man page&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://doc.cat-v.org/bell_labs/sam_lang_tutorial/'&gt;A Tutorial for the Sam Command Language&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://doc.cat-v.org/plan_9/4th_edition/papers/sam/'&gt;The Text Editor Sam&lt;/a&gt; (for more on the command language)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a recent task I had restored a backup of my &lt;a href='http://double.co.nz/creatures/'&gt;Creatures Developer Resource&lt;/a&gt; website, recovering from &lt;a href='/2013/04/03/parts-of-this-site-temporarily-down.html'&gt;a hard drive failure&lt;/a&gt;. I wanted to remove the Google ad code from each page of the website.&lt;/p&gt;

&lt;p&gt;To do this from within Inferno and using Acme I first ensured I had the &lt;code&gt;styx&lt;/code&gt; service running on the remote web server and had the host file system bound so remote users could connect to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; bind &amp;#39;#U*&amp;#39; /mnt/host
; svc/styx&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On my client Inferno machine I mounted this remote directory and ran &lt;code&gt;acme&lt;/code&gt; to edit the files on it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mount tcp!example.com!styx /n/host
% acme&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;acme&lt;/code&gt; editor starts and from here I can edit files on the remote server by accessing &lt;code&gt;/n/host/mnt/host&lt;/code&gt;. The first step was to load all HTML files in the webserver directory into &lt;code&gt;acme&lt;/code&gt;. This was done by executing the following command in an &lt;code&gt;acme&lt;/code&gt; window that had its location set to &lt;code&gt;/n/host/mnt/host/var/www/example.com&lt;/code&gt; (using mouse button 2 to execute):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Edit B &amp;lt;du -an|grep &amp;#39;html?$&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From the &lt;a href='http://doc.cat-v.org/plan_9/4th_edition/papers/sam/'&gt;Sam Reference&lt;/a&gt; it can be seen that &lt;code&gt;B&lt;/code&gt; is used to load files into the editor. In this case I load the output of the command &lt;code&gt;du -an|grep &amp;#39;html?$&amp;#39;&lt;/code&gt;. The command &lt;code&gt;du -an&lt;/code&gt; provides a recursive list of all files in the current directory and subdirectories and the &lt;code&gt;grep&lt;/code&gt; limits it to those ending in &lt;code&gt;htm&lt;/code&gt; or &lt;code&gt;html&lt;/code&gt;. Once executed acme has loaded all the files we&amp;#8217;re interested in from the remote server.&lt;/p&gt;

&lt;p&gt;The Google Ad snippet to be removed looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;!-- Gooogle --&amp;gt;
...
&amp;lt;!-- Gooogle --&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following &lt;code&gt;sam&lt;/code&gt; command will find this snippet and delete it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;,x&amp;lt;!-- Gooogle --&amp;gt;(.|\n)*&amp;lt;!-- Gooogle --&amp;gt;/ d&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;,&lt;/code&gt; means the starting range is the entire file. The &lt;code&gt;x&lt;/code&gt; command executes another comand for each part of the range that matches the regular expression - in this case the entire Google Ad snippet. The command to execute for each match is &lt;code&gt;d&lt;/code&gt; which is to delete the region. To have &lt;code&gt;acme&lt;/code&gt; run this on all open HTML files I used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Edit X/html?$/ ,x&amp;lt;!-- Gooogle --&amp;gt;(.|\n)*&amp;lt;!-- Gooogle --&amp;gt;/ d&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;X&lt;/code&gt; command iterates over all open windows with the name matching the regular expression and runs the following command, which I described above. This results in all the ad snippets from being removed from all the HTML files. To save them back to disk:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Edit X/html?$/ w&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And to close the &lt;code&gt;acme&lt;/code&gt; windows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Edit X/html?$/ D&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The task is done, closing &lt;code&gt;acme&lt;/code&gt; and unmounting the remote file system:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% unmount /n/host&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This task was pretty simple and could be done with a number of existing Unix tools but I wanted to give Acme a try with a real world task. It worked well editing remote files, and iterating towards the correct &lt;code&gt;sam&lt;/code&gt; commands to use was easy by interactively testing on single files and using the &lt;code&gt;p&lt;/code&gt; command to print ranges instead of deleting. Make sure &lt;a href='http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os.html'&gt;authentication&lt;/a&gt; is set up before sharing remote files though!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Remote Shells with Inferno OS</title>
   <link href="http://bluishcoder.co.nz/2013/06/05/remote-shells-with-inferno-os.html"/>
   <updated>2013-06-05T18:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/06/05/remote-shells-with-inferno-os</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.vitanuova.com/inferno/'&gt;Inferno OS&lt;/a&gt; provides a mechanism to connect to remote computers and execute commands similar to the way SSH works on Unix systems. The command to do this is &lt;a href='http://www.vitanuova.com/inferno/man/1/cpu.html'&gt;cpu&lt;/a&gt;. This can be used to execute commands, start a remote shell, and share GUI applications.&lt;/p&gt;

&lt;p&gt;To use &lt;code&gt;cpu&lt;/code&gt; you&amp;#8217;ll need to set up &lt;a href='http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os.html'&gt;authentication and encryption&lt;/a&gt;. This provides the mechanism to authentiate to the remote machine and encrypt the session data.&lt;/p&gt;

&lt;p&gt;The &lt;a href='http://www.vitanuova.com/inferno/man/8/svc.html'&gt;rstyx&lt;/a&gt; command needs to be run on the remote host to start the services that &lt;code&gt;cpu&lt;/code&gt; uses to connect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; ndb/cs
; ndb/dns
; svc/rstyx&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;ndb&lt;/code&gt; commands shown there start the services to use the network and DNS. Usually this is started beforehand but I list them for completeness.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;rstyx&lt;/code&gt; running and authentication configured the client can connect to the remote machine using &lt;code&gt;cpu&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cpu example.com
; ...now on server...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a session that is encrypted during authentication but then unencrypted. To use an encrypted session the &lt;code&gt;-C&lt;/code&gt; flag is required:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cpu -C rc4_256 example.com
; ls
; ...server directory listing...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;cpu&lt;/code&gt; takes an optional argument, that defaults to the shell, to execute:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cpu -C rc4_256 example.com ls
; ...server directory listing...
%&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The namespaces available to the &lt;code&gt;cpu&lt;/code&gt; command are mapped to the directory &lt;code&gt;/n/client/&lt;/code&gt; in a &lt;code&gt;cpu&lt;/code&gt; session. This means the remote shell or command can use resources on the client. For example a &lt;a href='http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html'&gt;phone running Inferno&lt;/a&gt; can &lt;code&gt;cpu&lt;/code&gt; to a remote host and that remote host can make calls, send messages, etc using the phones resources. By controlling what namespaces exist before &lt;code&gt;cpu&lt;/code&gt; is called the client can restrict what resources are available in the remote session.&lt;/p&gt;

&lt;p&gt;Another example of resource sharing is to run GUI programs on the server but have the display appear on the client, similar to how X11 forwarding operates. Doing this requires having the &lt;code&gt;wm&lt;/code&gt; window mananger on the client export its interface to a namespace (it&amp;#8217;s one of the few applications that doesn&amp;#8217;t do this by default on Inferno) and then in the &lt;code&gt;cpu&lt;/code&gt; session bind that to a location that GUI programs can see. On the client the export would look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mount {wmexport} /mnt/wm
; cpu -C rc4_256 example.com
; wmimport -w /n/client/mnt/wm acme &amp;amp;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This runs the editor &lt;code&gt;acme&lt;/code&gt; on the server but the display is shown on the client. The &lt;code&gt;-w&lt;/code&gt; flag passed to &lt;code&gt;wmimport&lt;/code&gt; gives the path to an exported directory provided by &lt;code&gt;wmexport&lt;/code&gt;. In this case we use the directory exported on the client which &lt;code&gt;cpu&lt;/code&gt; has exposed under &lt;code&gt;/n/client/mnt/wm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Any graphical program can be run this way including GUI shells, games, etc. Unfortunately, like X11 forwarding, it&amp;#8217;s fairly slow over low bandwidth connections. For local connections it&amp;#8217;s quite usable however. This could be a useful way to share a phone application on a desktop or a desktop application on a phone when it&amp;#8217;s connected to the same network.&lt;/p&gt;

&lt;p&gt;A combination of resources on the remote server and the client can be used to work around the low bandwidth issue. The &lt;code&gt;acme&lt;/code&gt; editor exposes &lt;a href='http://www.vitanuova.com/inferno/man/4/acme.html'&gt;directories and files to control the editor&lt;/a&gt;. By running &lt;code&gt;acme&lt;/code&gt; on the client, cpu-ing to the remote server so it can see these directories, the programs on the remote end can send data to the client &lt;code&gt;acme&lt;/code&gt; window. An example follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; acme
; ...create a terminal in acme by 2nd-button clicking `win`...
; ...in the acme terminal window...
; cpu -C rc4_256 cd.pn&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the remote session running inside &lt;code&gt;acme&lt;/code&gt; will expose the needed interfaces to control the client &lt;code&gt;acme&lt;/code&gt; program via &lt;code&gt;/n/client/mnt/acme&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; echo Hello &amp;gt;/n/client/mnt/acme/new/body&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This command, executed on the server in the remote session, creates a new window in the client &lt;code&gt;acme&lt;/code&gt; program with the text &amp;#8220;Hello&amp;#8221;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Building Wasp Lisp and MOSREF for Android</title>
   <link href="http://bluishcoder.co.nz/2013/05/09/building-wasp-lisp-and-mosref-for-android.html"/>
   <updated>2013-05-09T19:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/05/09/building-wasp-lisp-and-mosref-for-android</id>
   <content type="html">&lt;p&gt;Wasp Lisp is a small cross platform lisp by Scott Dunlop &lt;a href='/2009/11/27/wasp-lisp-small-scheme-like-lisp.html'&gt;that I&amp;#8217;ve written about before&lt;/a&gt; and MOSREF is the &lt;a href='/2009/11/28/using-wasp-lisp-secure-remote-injection.html'&gt;secure remote injection framework&lt;/a&gt; that is one of the applications written with it.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been wanting to get Wasp running on Android and Gonk (the low level Android layer of Firefox OS) for debugging and small applications. One of the nice features of Wasp is being able to have a minimal interpreter running on a platform and send byte code from another system to that interpreter which is loaded and run. You can even send the bytecode compiler itself to be loaded and run in the interpreter to get a full system on the target. This is the basis of how MOSREF works where the drone gets sent code to run from the console system.&lt;/p&gt;

&lt;h2 id='standalone_toolkit'&gt;Standalone Toolkit&lt;/h2&gt;

&lt;p&gt;Building Wasp for Android requires generating a &lt;a href='http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html'&gt;standalone toolchain&lt;/a&gt; from the Android NDK. This results in a vesion of &lt;code&gt;gcc&lt;/code&gt; and libraries that can be run from conventional makefiles and configure scripts.&lt;/p&gt;

&lt;p&gt;To generate a standalone toolchain to build Wasp I used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$NDK_ROOT/build/tools/make-standalone-toolchain.sh \
      --platform=android-8 \
      --install-dir=$STK_ROOT&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Replace &lt;code&gt;NDK_ROOT&lt;/code&gt; with the path to the Android SDK and &lt;code&gt;STK_ROOT&lt;/code&gt; with the destination where you want the standalone toolkit installed. The &lt;code&gt;android-8&lt;/code&gt; in the platform makes the standalone toolkit generate applications for FroYo and above (See &lt;a href='http://www.kandroid.org/ndk/docs/STABLE-APIS.html'&gt;STABLE-APIS.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Adding &lt;code&gt;$STK_ROOT/bin&lt;/code&gt; to the &lt;code&gt;PATH&lt;/code&gt; will make the compiler available:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export PATH=$PATH:$STK_ROOT/bin&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='building_libevent_for_android'&gt;Building libevent for Android&lt;/h2&gt;

&lt;p&gt;The Wasp virtual machine uses &lt;a href='http://libevent.org/'&gt;libevent&lt;/a&gt; to enable asynchronous operations. Building this for Android using the standalone toolkit is straightforward:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
tar xvf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure --host=arm-linux-androideabi --prefix=$STK_ROOT
make
make install&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This configures &lt;code&gt;libevent&lt;/code&gt; to be built using the ARM compilers in the standalone toolkit and to install the resulting libraries in the same install location as the toolkit. This makes it easy for other applications to find and link with the library.&lt;/p&gt;

&lt;h2 id='building_the_wasp_stub_for_android'&gt;Building the Wasp stub for Android&lt;/h2&gt;

&lt;p&gt;A Wasp VM stub file is used for generating Wasp applications. The bytecode for an application is appended to the stub file and the result made to be executable. By having stubs for various operating systems and architectures you can create executables specific to them easily. To build the Android stub:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git://github.com/swdunlop/WaspVM.git
cd WaspVM
STRIP=arm-linux-androideabi-strip \
  CC=arm-linux-androideabi-gcc \
  CFLAGS=&amp;quot;-I $STK_ROOT/include -L $STK_ROOT/lib&amp;quot; \
  ARCH=arm-linux \
  OS=android \
  make&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To build we define the correct version of the build programs to compile for ARM and set the architecture and OS to stop the build system from picking up the host system version of these. The result is a &lt;code&gt;waspvm-android-arm-linux&lt;/code&gt; stub in the &lt;code&gt;stubs&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2 id='creating_the_host_wasp_programs'&gt;Creating the host Wasp programs&lt;/h2&gt;

&lt;p&gt;To easily create Wasp programs for different platforms we&amp;#8217;ll need versions of them for the host we are running on. By doing a &amp;#8216;clean&amp;#8217; followed by a &amp;#8216;make&amp;#8217; on the host we&amp;#8217;ll clean out the Android build files and rebuild what&amp;#8217;s needed for the host. The &amp;#8216;clean&amp;#8217; process doesn&amp;#8217;t remove the stub file we created in the previous step which still allows us to do android Wasp programs.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;make clean
make&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This produces a &lt;code&gt;waspvm-linux-x86_64&lt;/code&gt; stub in my &lt;code&gt;stubs&lt;/code&gt; directory. To generate the Wasp interpreter and other programs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;make repl&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Exit out of the repl with &lt;code&gt;(exit)&lt;/code&gt; and there will be a &lt;code&gt;wasp&lt;/code&gt;, &lt;code&gt;waspc&lt;/code&gt; and &lt;code&gt;waspld&lt;/code&gt; program for the host system. Now we can make a version of &lt;code&gt;wasp&lt;/code&gt; for Android:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd mod    
../waspc -exe ../awasp -platform android-arm-linux bin/wasp.ms&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;waspc&lt;/code&gt; command takes a stub file (defined by the &lt;code&gt;platform&lt;/code&gt; or &lt;code&gt;stub&lt;/code&gt; argument) and appends the bytecode resulting from the compilation of the Wasp lisp code given as an argument. &lt;code&gt;wasp.ms&lt;/code&gt; is the source for the intepreter. The output is set as &lt;code&gt;awasp&lt;/code&gt; which is our executable for running on Android. We can use a similar command for producing Android versions of the other Wasp programs. MOSREF for example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;../waspc -exe ../amosref -platform android-arm-linux bin/mosref.ms&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='running_on_android'&gt;Running on Android&lt;/h2&gt;

&lt;p&gt;Running these executables on Android involves pushing them to somewhere writeable on the phone. If you have a rooted Android device (or a Firefox OS device) you can push them pretty much anywhere. On my non-rooted Jellybean Galaxy Note 2 I&amp;#8217;m limited to just &lt;code&gt;/data/local/tmp&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb push awasp /data/local/tmp
adb shell
cd /data/local/tmp
chmod 0755 awasp
./awasp
&amp;gt;&amp;gt; (+ 1 2 3)
:: 6&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This gives you a running Wasp interpreter. To develop and do interesting things on the phone you really need the Wasp &lt;code&gt;mod&lt;/code&gt; files and the stub files copied over:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb push mod /data/local/tmp
adb push stubs /data/local/tmp
adb shell
cd /data/local/tmp
./awasp
&amp;gt;&amp;gt; (import &amp;quot;lib/http-client&amp;quot;)
:: #t
&amp;gt;&amp;gt; (http-response-body (http-get &amp;quot;http://icanhazip.com/&amp;quot;))
:: &amp;quot;xxx.xxx.xxx.xxx\n&amp;quot;
&amp;gt;&amp;gt; (exit)&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='mosref_android_drone'&gt;MOSREF Android drone&lt;/h2&gt;

&lt;p&gt;It&amp;#8217;s simple now to create a &lt;a href='/2009/11/28/using-wasp-lisp-secure-remote-injection.html'&gt;MOSREF drone&lt;/a&gt; that runs on Android. Make sure the MOSREF console has a &lt;code&gt;stubs&lt;/code&gt; directory containing the Android stub then create the drone as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;console&amp;gt; drone drone1 myphone android-arm-linux
Drone executable created.
Listening for drone on 10000...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Copy the created &lt;code&gt;drone1&lt;/code&gt; onto the phone and run it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb push mod/drone1 /data/local/tmp
adb shell
cd /data/local/tmp
chmod 0755 drone1
./drone1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now on the console you can see the drone on the phone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;console&amp;gt; nodes
NODES: console online address: 192.168.1.101 port: 10000
       myphone online
console&amp;gt; on myphone sh ls
...directory listing...
console on myphone do (print &amp;quot;hello\n&amp;quot;)
...prints hello on the phone &amp;#39;adb shell&amp;#39; session...
console&amp;gt; on myphone load lib/http-file-server.ms
:: spawn-http-file-server
console&amp;gt; on myphone do (offer-http-file 8080 &amp;quot;/test&amp;quot; &amp;quot;text/plain&amp;quot; &amp;quot;Hello world!&amp;quot;)
:: [queue 1F5DD00]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;load&lt;/code&gt; command shown above loads and compiles the Wasp lisp file on the host and sends the compiled bytecode to the drone on the phone. We then run the lisp code on the phone to start an HTTP server to serve data.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ranged integer types and bounds checking</title>
   <link href="http://bluishcoder.co.nz/2013/05/07/ranged-integer-types-and-bounds-checking.html"/>
   <updated>2013-05-07T17:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/05/07/ranged-integer-types-and-bounds-checking</id>
   <content type="html">&lt;p&gt;There&amp;#8217;s a discussion going on in the &lt;a href='https://mail.mozilla.org/pipermail/rust-dev/2013-April/003654.html'&gt;Rust mailing list about ranged integer types&lt;/a&gt; and whether they&amp;#8217;re useful for safety. Some of the points raised have been about the performance costs of dynamic bounds checks and the overhead of code for static bounds checks. I thought I&amp;#8217;d write a post with my experiences with overfow checking in Gecko and with programming languages that can do overflow checking at compile time.&lt;/p&gt;

&lt;h2 id='gecko'&gt;Gecko&lt;/h2&gt;

&lt;p&gt;There have been places in Gecko (the core Firefox engine) where overflow detection at compile time would be useful. An example is in the &lt;a href='http://hg.mozilla.org/mozilla-central/file/b842d26dd5f0/content/media/wave/WaveReader.cpp'&gt;WAV audio format reading code&lt;/a&gt;. In this C++ code we have the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;static const int64_t BLOCK_SIZE = 4096;
int64_t readSize = std::min(BLOCK_SIZE, remaining);
int64_t frames = readSize / mFrameSize;

const size_t bufferSize = static_cast&amp;lt;size_t&amp;gt;(frames * mChannels);
nsAutoArrayPtr&amp;lt;AudioDataValue&amp;gt; sampleBuffer(new AudioDataValue[bufferSize]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here &lt;code&gt;frames * mChannels&lt;/code&gt; can overflow with the result of the memory buffer allocated following it being of the wrong size and a memory access error occurring later. We can do a run time check that it won&amp;#8217;t overflow but this is error prone if someone changes &lt;code&gt;BLOCK_SIZE&lt;/code&gt; to be of a size that causes overflow, or the size of &lt;code&gt;AudioDataValue&lt;/code&gt; changes to do the same. It&amp;#8217;ll take an edge case in a test to find the problem. Better is to ensure that it will never overflow at compile time. The &lt;code&gt;PR_STATIC_ASSERT&lt;/code&gt; construct can do this for us:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PR_STATIC_ASSERT(uint64_t(BLOCK_SIZE) &amp;lt; UINT_MAX / sizeof(AudioDataValue) / MAX_CHANNELS);
const size_t bufferSize = static_cast&amp;lt;size_t&amp;gt;(frames * mChannels);
nsAutoArrayPtr&amp;lt;AudioDataValue&amp;gt; sampleBuffer(new AudioDataValue[bufferSize]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now if &lt;code&gt;BLOCK_SIZE&lt;/code&gt;, &lt;code&gt;AudioDataValue&lt;/code&gt; or &lt;code&gt;MAX_CHANNELS&lt;/code&gt; changes it will complain if the result overflows at compile time. Because C++ doesn&amp;#8217;t have dependent types and constraint solving, we don&amp;#8217;t have the ability to statically confirm that &lt;code&gt;frames * mChannels&lt;/code&gt; avoids overflow automatically. We have to encode how those values are calculated in the &lt;code&gt;PR_STATIC_ASSERT&lt;/code&gt; but it&amp;#8217;s better than nothing.&lt;/p&gt;

&lt;p&gt;Similar code follows to check &lt;code&gt;readSize&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PR_STATIC_ASSERT(uint64_t(BLOCK_SIZE) &amp;lt; UINT_MAX / sizeof(char));
nsAutoArrayPtr&amp;lt;char&amp;gt; dataBuffer(new char[static_cast&amp;lt;size_t&amp;gt;(readSize)]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We encode the rule that &lt;code&gt;BLOCK_SIZE&lt;/code&gt; must not be greater than &lt;code&gt;UINT_MAX&lt;/code&gt; knowing that &lt;code&gt;readSize&lt;/code&gt; is capped at &lt;code&gt;BLOCK_SIZE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Other uses of &lt;code&gt;PR_STATIC_ASSERT&lt;/code&gt; are in that same file and various other places in the codebase. For example, &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=623998'&gt;Bug 623998&lt;/a&gt;. This was caused by an overflow in the implementation of the C++ &lt;code&gt;operator new&lt;/code&gt; so we used &lt;code&gt;PR_STATIC_ASSERT&lt;/code&gt; to ensure that the argument passed to &lt;code&gt;operator new&lt;/code&gt; couldn&amp;#8217;t overflow based on analysis of the constraints of the arguments we pass to it.&lt;/p&gt;

&lt;h2 id='ats'&gt;ATS&lt;/h2&gt;

&lt;p&gt;The &lt;a href='http://www.ats-lang.org/'&gt;ATS programming language&lt;/a&gt; has a dependent type system that allows expressing ranges for integers at the static level. Unfortunately the current implementation uses machine integers in the constraint solver and this prevents easily expressing constraints involving overflow.&lt;/p&gt;

&lt;p&gt;The &lt;a href='https://github.com/xlq/aos'&gt;Applied Operating System&lt;/a&gt;, an operating system kernel written in ATS, uses a patched ATS that uses &lt;a href='http://gmplib.org/'&gt;libgmp&lt;/a&gt; for constraint solving and it declares types such overflow causes a type error. For example, the following code will not typecheck:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun test () = {
  val a = ubyte1_of 250
  val c = ubyte1_of 6

  val d = a + b
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The type checker recognizes that &lt;code&gt;a&lt;/code&gt; is the exact unsigned byte value of &lt;code&gt;250&lt;/code&gt; and that &lt;code&gt;c&lt;/code&gt; is the exact type value of unsigned byte &lt;code&gt;6&lt;/code&gt;. Adding these together causing a &lt;code&gt;byte&lt;/code&gt; greater than &lt;code&gt;255&lt;/code&gt; which is a type error.&lt;/p&gt;

&lt;p&gt;Constraints on types are propogated as expected. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun add_me {a,b: Ubyte} (a: ubyte a, b: ubyte b): ubyte (a+b) = a + b

fun test () = {
  val x = add_me (ubyte1_of 200, ubyte1_of 10)  
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here the arguments to &lt;code&gt;add_me&lt;/code&gt; cannot be determined statically (assume &lt;code&gt;test&lt;/code&gt; and &lt;code&gt;add_me&lt;/code&gt; are compiled seperately so the compiler does not know the exact values at compile time) and the type checker will complain about the &lt;code&gt;a+b&lt;/code&gt; since it can&amp;#8217;t prove that any unsigned byte added to another unsigned byte is less than the maximum value of an unsigned byte.&lt;/p&gt;

&lt;p&gt;A solution is to add to the static system to say that the arguments to &lt;code&gt;add_me&lt;/code&gt; add up to less than 255 and will not overflow and make callers check the range before calling:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun add_me {a,b: Ubyte | a+b &amp;lt;= 255 } (a: ubyte a, b: ubyte b): ubyte (a+b) 
  = a + b

fun test () = {
  val x = add_me (ubyte1_of 200, ubyte1_of 10)  
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With judicious use of constraints you can then push out the range check from the inner loops to the callers at the outmost region to reduce overhead. Or you can add dynamic checks close to the inner loops to reduce the burden on callers. The good thing is the compiler tells you when you get it wrong.&lt;/p&gt;

&lt;h2 id='ats2'&gt;ATS2&lt;/h2&gt;

&lt;p&gt;&lt;a href='https://github.com/githwxi/ATS-Postiats'&gt;ATS2&lt;/a&gt; is a work in progress with improvements and additions to ATS. You&amp;#8217;ll need a recent version of ATS to build and then &lt;a href='http://sourceforge.net/p/ats-lang/wiki/Building%20and%20installing/'&gt;follow the instructions&lt;/a&gt; to get a working ATS2.&lt;/p&gt;

&lt;p&gt;One of the improvements in ATS2 is allowing using libgmp to deal with constraints so range checks can be done to detect overflow. Hongwei Xi &lt;a href='http://sourceforge.net/mailarchive/message.php?msg_id=30692249'&gt;posted to the mailing list&lt;/a&gt; an example of using this to &lt;a href='https://github.com/githwxi/ATS-Postiats/blob/master/doc/EXAMPLE/MISC/arith_overflow.dats'&gt;detect integer overflow in bsearch&lt;/a&gt; at compile time. This file can be typechecked with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;patsopt -tc -d doc/EXAMPLE/MISC/arith_overflow.dats&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;arith_overflow&lt;/code&gt; example starts off by declaring an abstract type, &lt;code&gt;intb&lt;/code&gt; to represent bounded integers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;abst@ype intb (i: int) // bounded integers&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The type is indexed over a sort &lt;code&gt;int&lt;/code&gt;. This is a dependent type that represents the value of the bounded integer. Cast functions are provided to allow converting between a normal integer and a bounded integer:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;castfn intb2int {i:int} (i: intb i): int (i)
castfn int2intb {i:int | isintb(i)} (i: int i): intb (i)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;int2intb&lt;/code&gt; cast function has a contraint on its type index saying that the given integer is a bounded int via the &lt;code&gt;isintb&lt;/code&gt; call. This is defined as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;stacst INTMIN : int and INTMAX : int
stadef isintb (i:int): bool = (INTMIN &amp;lt;= i &amp;amp;&amp;amp; i &amp;lt;= INTMAX)
praxi lemma_INTMINMAX (): [INTMIN &amp;lt; ~0X7FFF ; INTMAX &amp;gt;= 0x7FFF] void&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The way this works is two sorts constants are declared, INTMIN and INTMAX. The definition &lt;code&gt;isintb&lt;/code&gt; constrains the index &lt;code&gt;i&lt;/code&gt; to be between these two values. The values are not yet defined so all the type system knows for now is that &lt;code&gt;isintb&lt;/code&gt; returns true if the given number is between two other numbers.&lt;/p&gt;

&lt;p&gt;The axiom (introduced with &lt;code&gt;praxi&lt;/code&gt; and is equivalent to a &lt;code&gt;prfun&lt;/code&gt; or proof function) &lt;code&gt;lemma_INTMINMAX&lt;/code&gt; states that INTMIN is &amp;lt; -0x&amp;amp;FFFF and INTMAX &amp;gt;= 0x7FFF. Once this proof function is called it tells the constraint system what the &lt;code&gt;intb&lt;/code&gt; is bounded by.&lt;/p&gt;

&lt;p&gt;Basic mathematic operations are provided for a bounded integer and the standard mathematical operators are overloaded with these. For example, adding two bounded integers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun add_intb_intb {i,j:int | isintb(i+j)} (i: intb (i), j: intb (j)):&amp;lt;&amp;gt; intb (i+j)
overload + with add_intb_intb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is similar to the &lt;code&gt;add_me&lt;/code&gt; function shown previously using the modified ATS compiler. It adds two bounded ints with the contraint that the result must also be a bounded int. Because the type system uses &lt;code&gt;libgmp&lt;/code&gt; for the contraints it is able to ensure that the type system itself doesn&amp;#8217;t overflow when doing this check.&lt;/p&gt;

&lt;p&gt;With these definitions for bounded ints in place it&amp;#8217;s possible to write code that will not typecheck if overflow occurs. The example in &lt;code&gt;arith_overflow&lt;/code&gt; implements &lt;code&gt;bsearch&lt;/code&gt;. Within the &lt;code&gt;bsearch&lt;/code&gt; implementation it has the follow code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val m = (l + r) / 2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here &lt;code&gt;l&lt;/code&gt; and &lt;code&gt;r&lt;/code&gt; are bounded ints. Adding &lt;code&gt;l&lt;/code&gt; and &lt;code&gt;r&lt;/code&gt; can overflow and this will fail to compile. Changing the code to do effectively the same thing but avoiding adding the two numbers to prevent overflow results in compiling because the type checker can prove no overflow occurs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val m = l + half (r - l)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where &lt;code&gt;half&lt;/code&gt; is defined to return the number divided by two:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun half_intb {i:nat} (i: intb (i)):&amp;lt;&amp;gt; intb (ndiv(i,2))
overload half with half_intb&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;I think overflow checking at the type level is a very useful feature. It helps find important bugs early as people hardly ever check for overflow. When they do it&amp;#8217;s at runtime and the code is often not exercised until an issue actually occurs so may not handle things correctly.&lt;/p&gt;

&lt;p&gt;For Mozilla C++ code we can use &lt;code&gt;PR_STATIC_ASSERT&lt;/code&gt; (or preferably the recently introduced &lt;a href='http://whereswalden.com/2011/12/26/introducing-mozillaassertions-h-to-mfbt/'&gt;MOZ_STATIC_ASSERT&lt;/a&gt;) to help get some of the benefits of compile time overflow checking.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Social Engineering Attempt Warning</title>
   <link href="http://bluishcoder.co.nz/2013/05/01/social-engineering-attempt-warning.html"/>
   <updated>2013-05-01T16:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/05/01/social-engineering-attempt-warning</id>
   <content type="html">&lt;p&gt;This morning when I checked my email I got a nice email from my server hosting provider titled &amp;#8220;Root password reset&amp;#8221;. That&amp;#8217;s not usually a good sign when you haven&amp;#8217;t done any password resets recently.&lt;/p&gt;

&lt;p&gt;The email was a service request response from the provider asking for confirmation to reset the root account on my server. I responded that this appeared to be a hack attempt, got online to chat with them and got the details of what happened.&lt;/p&gt;

&lt;p&gt;An attacker had registered a domain, &lt;code&gt;chrisdouble.co.nz&lt;/code&gt;, this morning. They rang my hosting provider to say they were me, and to reset the email address in my account to that domain. They managed to convince them to do this.&lt;/p&gt;

&lt;p&gt;Once that was done they were able to get into the customer service portal for the server. No server maintenance could be done there but they got access to my phone number, billing details and the ability to raise service requests.&lt;/p&gt;

&lt;p&gt;They raised a service request to reset the root password on the server. The service response was that they couldn&amp;#8217;t do this as the server was set up to use SSH keys and passwords were disabled. The attackers response to that was to ask them to physically access the server and re-enable password logins.&lt;/p&gt;

&lt;p&gt;The support person emailed back to confirm this request but the email to the attackers domain bounced. They then emailed the previous address, which is my real email, and that was the one I read this morning.&lt;/p&gt;

&lt;p&gt;While I was talking to the support person to resolve the issue the attacker was on the phone with this hosting company as well, trying to prove their identity as me. They had a number of personal details and it seemed to be a pretty well thought out social engineering attempt. In the end they realised we were fishing for information from them and they hung up.&lt;/p&gt;

&lt;p&gt;It is amazing how close they got to being able to gain access to the server. If I hadn&amp;#8217;t been awake to read that email and respond quickly support would most likely have given them access. I&amp;#8217;ve now arranged a protocol with them to prevent this from happening again.&lt;/p&gt;

&lt;p&gt;If anyone I know receives an email or contact from &lt;code&gt;chrisdouble.co.nz&lt;/code&gt; it is not me. If you are unsure you can ask for me to sign a message with GPG. My GPG fingerprint can be obtained by contacting me directly. Because the attacker gained access to the service portal they have a reasonable amount of identifying information (address, phone number, date of birth, etc). Don&amp;#8217;t take any of these as information to confirm an unusal contact as being me.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Backing up Gmail messages with offlineimap</title>
   <link href="http://bluishcoder.co.nz/2013/04/30/backing_up_gmail_messages_with_offlineimap.html"/>
   <updated>2013-04-30T18:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/04/30/backing_up_gmail_messages_with_offlineimap</id>
   <content type="html">&lt;p&gt;A while back I realised I had a ton of email archived on Gmail which I would be sad to lose if I lost access to my Google account or couldn&amp;#8217;t access the internet for some reason. I also wanted a backup in case I decided to migrate away from Gmail to use another service.&lt;/p&gt;

&lt;p&gt;The approach I took was to use &lt;a href='http://offlineimap.org/'&gt;offlineimap&lt;/a&gt; to download the contents of my mail using Gmail&amp;#8217;s IMAP support. I set it up to download a few days of email at a time so I wouldn&amp;#8217;t encounter any bandwidth limiting from Google or risk getting my account temporarily suspended for aggressive use.&lt;/p&gt;

&lt;p&gt;I chose to use &amp;#8216;Maildir&amp;#8217; format for the downloaded mail so I could use &lt;a href='http://notmuchmail.org/'&gt;notmuch&lt;/a&gt; locally to read and search.&lt;/p&gt;

&lt;p&gt;The matter of dealing with Gmail folders is a bit tricky. These are exposed as IMAP folders and if you&amp;#8217;re not careful you can end up downloading emails multiple times for each folder. I didn&amp;#8217;t really want the folder structure. I just wanted all emails and I&amp;#8217;d use the tagging mechanism of notmuch to add tags after the fact.&lt;/p&gt;

&lt;p&gt;The secret to ignoring folders is to create a &lt;code&gt;folderfilter&lt;/code&gt; entry in the &lt;code&gt;.offlineimaprc&lt;/code&gt; file. This is a lambda function that given a folder name should return true if it&amp;#8217;s a folder you want to be downloaded by offlineimap. I use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;folderfilter = lambda foldername: foldername in [&amp;#39;[Gmail]/All Mail&amp;#39;, &amp;#39;[Gmail]/Sent Mail&amp;#39;]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This downloads &amp;#8220;All Mail&amp;#8221; and &amp;#8220;Sent Mail&amp;#8221;. This way I get everything in my Gmail without the folder structure.&lt;/p&gt;

&lt;p&gt;I chose to add a &lt;code&gt;nametrans&lt;/code&gt; entry so that the downloaded folders in the Maildir have more relevant names. &lt;code&gt;nametrans&lt;/code&gt; is a lambda function that, given a folder name, returns the name that should be used locally for that folder. Here I translate &amp;#8220;All Mail&amp;#8221; to &amp;#8220;all&amp;#8221; and &amp;#8220;Sent Mail&amp;#8221; to &amp;#8220;sent&amp;#8221;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nametrans = lambda foldername: 
              re.sub(&amp;#39;^\[Gmail\]/All Mail$&amp;#39;, &amp;#39;all&amp;#39;, 
              re.sub(&amp;#39;^\[Gmail\]/Sent Mail$&amp;#39;, &amp;#39;sent&amp;#39;,foldername))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To connect to Gmail the following entries are used in the remote repository section:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;type = Gmail
remotehost = imap.gmail.com
realdelete=no
maxconnections=1
ssl = yes
cert_fingerprint = 6d1b5b5ee0180ab493b71d3b94534b5ab937d042
remoteport = 993
remoteuser = ...
remotepass = ...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My local repository section is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;type = Maildir
localfolders = ~/.Mail&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To prevent having to run offlineimap for a long time on the initial sync I did it over a series of days. I used the &lt;code&gt;maxage&lt;/code&gt; setting in the &lt;code&gt;Account&lt;/code&gt; section. When set mail older than this number of days is not synced. So I&amp;#8217;d set it for 100 days, do a sync. Then I&amp;#8217;d increase it by a 100 the next day and do another sync. Over a series of days/weeks I have all my email. Once completely synced I removed the entry from the &lt;code&gt;.offlineimaprc&lt;/code&gt; file. I&amp;#8217;m not sure what the best value is and maybe it doesn&amp;#8217;t matter but this worked for me.&lt;/p&gt;

&lt;p&gt;My .offlineimaprc then looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[general]
accounts = gmail
ui = TTY.TTYUI

[Account gmail]
localrepository = gmailLocal
remoterepository = gmailRemote
maxage = 1000

[Repository gmailLocal]
type = Maildir
localfolders = ~/.Mail

[Repository gmailRemote]
type = Gmail
remotehost = imap.gmail.com
realdelete=no
maxconnections=1
ssl = yes
cert_fingerprint = 6d1b5b5ee0180ab493b71d3b94534b5ab937d042
remoteport = 993
remoteuser = ...
remotepass = ...
nametrans = ...show above...
folderfilter = ...show above...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I used &lt;code&gt;notmuch&lt;/code&gt; to process and search the &lt;code&gt;Maildir&lt;/code&gt; locally. By setting &lt;code&gt;synchronize_flags=true&lt;/code&gt; in my &lt;code&gt;.notmuch-config&lt;/code&gt; file I could read the offline email in notmuch, incrementally sync with offlineimap, and the &amp;#8216;read&amp;#8217;, &amp;#8216;replied&amp;#8217;, etc flags are synchronized between them.&lt;/p&gt;

&lt;p&gt;To tag with &lt;code&gt;notmuch&lt;/code&gt; I run a script after syncing with &lt;code&gt;.offlineimap&lt;/code&gt; that tags based on certain criteria. Something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;offlineimap
notmuch new
notmuch tag +sent -- folder:sent and not tag:sent 
notmuch tag +bugzilla -inbox -- tag:inbox and from:bugzilla-daemon@mozilla.org
notmuch tag +ats -inbox -- tag:inbox and to:ats-lang-users
...etc...&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Running Firefox OS on Nexus S</title>
   <link href="http://bluishcoder.co.nz/2013/04/22/running-firefox-os-on-nexus-s.html"/>
   <updated>2013-04-22T20:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/04/22/running-firefox-os-on-nexus-s</id>
   <content type="html">&lt;p&gt;Last year I posted about how to &lt;a href='/2012/03/20/building-and-running-b2g-on-nexus-s.html'&gt;build and run B2G on the Nexus S&lt;/a&gt;. Much has changed since then and this post attempts to provide up to date instructions on building Firefox OS and installing the latest &lt;a href='https://wiki.mozilla.org/Gaia'&gt;Gaia&lt;/a&gt; version.&lt;/p&gt;

&lt;p&gt;I wrote &amp;#8216;attempts&amp;#8217; because the support for the Nexus S bitrots frequently due to (I assume) most development effort going towards developer devices and devices that intend to be shipped. These instructions worked for me on my Nexus S and gives me a phone that can use Wifi, make calls, use 3G data, take photo&amp;#8217;s, record video and install applications.&lt;/p&gt;

&lt;h2 id='getting_the_source'&gt;Getting the source&lt;/h2&gt;

&lt;p&gt;The main source repository is on github, &lt;a href='https://github.com/mozilla-b2g/b2g'&gt;https://github.com/mozilla-b2g/b2g&lt;/a&gt;. The first step is to clone this repository. I clone this into a directory called &lt;code&gt;nexus-s&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/mozilla-b2g/B2G nexus-s
$ cd nexus-s&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a file in this directory called &lt;code&gt;.userconfig&lt;/code&gt; containing the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export CC=gcc-4.6
export CXX=g++-4.6
export HIDPI=1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first two entries are required if you are building on Ubuntu 12.10 to use gcc version 4.6, which you must install. B2G does not build using gcc version 4.7.&lt;/p&gt;

&lt;p&gt;The last entry, &lt;code&gt;HIDPI&lt;/code&gt;, results in applications using the correct resources for the screen size on the Nexus S. Without this many things will be scaled incorrectly.&lt;/p&gt;

&lt;h2 id='configuring'&gt;Configuring&lt;/h2&gt;

&lt;p&gt;Once the source is obtained you need to pull down the sub-repositories required for the Nexus S. This step downloads multiple gigabytes of data and can take a long time:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s$ BRANCH=v1-train ./config.sh nexus-s&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the use of the &lt;code&gt;BRANCH&lt;/code&gt; environment variable. This configures our build to use the relatively stable &lt;code&gt;v1-train&lt;/code&gt; branch. This branch gets regular updates but tends to be better tested than &lt;code&gt;master&lt;/code&gt; which is often broken for not-quite-supported devices like the Nexus S.&lt;/p&gt;

&lt;p&gt;Although we are using the &lt;code&gt;v1-train&lt;/code&gt; we are going to use the &lt;code&gt;master&lt;/code&gt; branch of Gaia so we get the latest and greatest user interface. We&amp;#8217;ll change to this later.&lt;/p&gt;

&lt;h2 id='gecko_changes'&gt;Gecko changes&lt;/h2&gt;

&lt;p&gt;The branch of Gecko that &lt;code&gt;v1-train&lt;/code&gt; uses has some bugs on the Nexus S. To fix this we need to apply some patches. The first is &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=832653'&gt;bug 832653&lt;/a&gt;, video playback broken on Nexus S. The patches relevant to Gecko from this bug that need to be applied are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/attachment.cgi?id=734988'&gt;Fix graphic buffer crash&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following set of commands downloads these patches and applies them in a branch of the Gecko tree that the &lt;code&gt;config.sh&lt;/code&gt; step previously obtained:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s       $ cd gecko
nexus-s/gecko $ git checkout -b nexus-s m/v1-train
nexus-s/gecko $ curl -k -L https://bug832653.bugzilla.mozilla.org/attachment.cgi?id=734988 &amp;gt;p1.patch
nexus-s/gecko $ patch -p1 &amp;lt;p1.patch
nexus-s/gecko $ git commit -a -m &amp;quot;Nexus S patches&amp;quot;
nexus-s/gecko $ cd ..&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='gonk_changes'&gt;Gonk changes&lt;/h2&gt;

&lt;p&gt;Part of &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=832653'&gt;bug 832653&lt;/a&gt; makes a change to the low level Gonk layer of B2G. This is in the libstagefright video decoding libraries. The change is to prevent output buffer starvation which results in video decoding stopping after a few frames. The required patch is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/attachment.cgi?id=735002'&gt;Fix output buffer starvation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To apply this patch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s                 $ cd frameworks/base
nexus-s/frameworks/base $ git checkout -b nexus-s 
nexus-s/frameworks/base $ curl -k -L https://bugzilla.mozilla.org/attachment.cgi?id=735002 &amp;gt;p1.patch
nexus-s/frameworks/base $ patch -p1 &amp;lt;p1.patch
nexus-s/frameworks/base $ git commit -a -m &amp;quot;Nexus S patches&amp;quot;
nexus-s/frameworks/base $ cd ../..&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='gaia_changes'&gt;Gaia changes&lt;/h2&gt;

&lt;p&gt;There are Gaia changes required as part of &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=869289'&gt;bug 869289&lt;/a&gt; as well. This change prevents the error where videos are not listed if the thumbnail cannot be generated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://bug869289.bugzilla.mozilla.org/attachment.cgi?id=746196'&gt;List videos even if thumbnail generation fails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also want to be on the Gaia &lt;code&gt;master&lt;/code&gt; branch to get the latest and greatest code. The following comands switch to this branch and apply our patch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s      $ cd gaia
nexus-s/gaia $ git checkout -b nexus-s mozillaorg/master
nexus-s/gaia $ curl -k -L https://bug869289.bugzilla.mozilla.org/attachment.cgi?id=746196 &amp;gt;p1.patch
nexus-s/gaia $ patch -p1 &amp;lt;p1.patch
nexus-s/gaia $ git commit -a -m &amp;quot;Nexus S video app thumbnail fix&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is a bug related to video recording on the Nexus S. To fix this we need a patch from &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=832638'&gt;bug 832638&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/attachment.cgi?id=704241'&gt;Set video recording profile in camera app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To apply this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s/gaia $ curl -k -L https://bugzilla.mozilla.org/attachment.cgi?id=704241 &amp;gt;p2.patch
nexus-s/gaia $ patch -p1 &amp;lt;p2.patch
nexus-s/gaia $ git commit -a -m &amp;quot;Nexus S video recording fix&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='building'&gt;Building&lt;/h2&gt;

&lt;p&gt;Now that all the required changes have been made we can build:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s $ ./build.sh &lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='installing'&gt;Installing&lt;/h2&gt;

&lt;p&gt;Once the build is complete you should be able to flash the Nexus S with the results. Note that this completely wipes everything on your phone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s $ ./flash.sh&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The phone should reboot after this step with Firefox OS installed and prompting for information from the &amp;#8220;First Run&amp;#8221; app.&lt;/p&gt;

&lt;h2 id='new_zealand_changes'&gt;New Zealand changes&lt;/h2&gt;

&lt;p&gt;Some New Zealand sites don&amp;#8217;t detect Firefox OS and serve their mobile versions. This can be changed by adding overrides to &lt;code&gt;gaia/build/ua-override-prefs.js&lt;/code&gt;. I add the entries in &lt;a href='http://cd.pn/b2gnzuaoverride.txt'&gt;b2gnzuaoverride.txt&lt;/a&gt; to this file to get stuff.co.nz, mega.co.nz and trademe.co.nz serving the correct mobile site. Once added to this file, reinstall Gaia on the phone.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s $ ./flash.sh gaia&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='updating'&gt;Updating&lt;/h2&gt;

&lt;p&gt;To update the source to latest versions we need to &amp;#8216;rebase&amp;#8217; our changes on top of the most recent repository changes. The following steps will do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s $ git pull
nexus-s $ ./config.sh nexus-s
nexus-s $ cd gecko
nexus-s/gecko $ git rebase m/v1-train
nexus-s/gecko $ cd ../gaia
nexus-s/gaia  $ git rebase mozillaorg/master
nexus-s/gaia  $ cd ..
nexus-s $ ./build.sh&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may need to do some fixing up of merge conflicts if changes have occurred to the areas we&amp;#8217;ve patched.&lt;/p&gt;

&lt;p&gt;To flash the phone, overwriting everything on it, including all user data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s $ ./flash.sh&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To flash the phone, keeping (most of&amp;#8230;) your existing user data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nexus-s $ ./flash.sh system
nexus-s $ ./flash.sh gecko
nexus-s $ ./flash.sh gaia&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that flashing gaia might remove some of your installed application icons. You&amp;#8217;ll need to reinstall those apps to fix that.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Parts of this site temporarily down</title>
   <link href="http://bluishcoder.co.nz/2013/04/03/parts-of-this-site-temporarily-down.html"/>
   <updated>2013-04-03T14:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2013/04/03/parts-of-this-site-temporarily-down</id>
   <content type="html">&lt;p&gt;Unfortunately the server running this site had a hard drive issue which resulted in a number of corrupt files. You&amp;#8217;ll probably notice that some links to here result in a &amp;#8216;404&amp;#8217; error due to them being not found. I&amp;#8217;m slowly recovering the lost data and hope to have the files restored as soon as I can.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>An Introduction to using pointers in ATS</title>
   <link href="http://bluishcoder.co.nz/2013/01/25/an-introduction-to-pointers-in-ats.html"/>
   <updated>2013-01-25T18:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2013/01/25/an-introduction-to-pointers-in-ats</id>
   <content type="html">&lt;p&gt;The &lt;a href='http://www.ats-lang.org'&gt;ATS programming language&lt;/a&gt; was designed to enable safe systems programming. This requires dealing with pointers safely. In this post I intend to go through the basics of pointer handling in ATS and how this safety is achieved.&lt;/p&gt;

&lt;h2 id='raw_pointers'&gt;Raw Pointers&lt;/h2&gt;

&lt;p&gt;ATS has a basic pointer type called &lt;code&gt;ptr&lt;/code&gt;. This is a non-dependent type and is the equivalent to a &lt;code&gt;void*&lt;/code&gt; in the C programming language. It also has a dependently typed pointer type that is indexed over an &lt;code&gt;addr&lt;/code&gt; sort (sorts are the types of type indexes) that represents the address of the pointer. This allows the proof and type system to reason about pointer addresses. Pointer arithmetic can be done on values of these types but they can&amp;#8217;t be safely dereferenced. The following example shows some basic usage:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun malloc (s: size_t): ptr = &amp;quot;mac#malloc&amp;quot;
extern fun free (p: ptr):void = &amp;quot;mac#free&amp;quot;

implement main() = let
  val a = malloc(42);
in
  print (a); print_newline();
  print (a + 1); print_newline ();
  free(a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This program offers no compile time safety for dealing with the pointers. You can leave the &lt;code&gt;free&lt;/code&gt; call out and it will compile, run and leak memory. You can use unsafe functions to dereference the pointer to retrieve and store data at that location:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;staload &amp;quot;prelude/SATS/unsafe.sats&amp;quot;
staload _ = &amp;quot;prelude/DATS/unsafe.dats&amp;quot;

extern fun malloc (s: size_t): [l:addr | l &amp;gt; null] ptr l = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:addr | l &amp;gt; null} (p: ptr l):void = &amp;quot;mac#free&amp;quot;

implement main() = let
  val a = malloc(sizeof&amp;lt;int&amp;gt; * 2)
in
  ptrset&amp;lt;int&amp;gt; (a, 10);
  ptrset&amp;lt;int&amp;gt; (a + sizeof&amp;lt;int&amp;gt;, 20);
  print (ptrget&amp;lt;int&amp;gt; (a)); print_newline();
  print (ptrget&amp;lt;int&amp;gt; (a + sizeof&amp;lt;int&amp;gt;)); print_newline ();
  free(a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;ptrset&lt;/code&gt; and &lt;code&gt;ptrget&lt;/code&gt; are template functions in the &lt;code&gt;unsafe&lt;/code&gt; module that allow storing and retrieving values using raw pointers. No safety guarantees are available and it is assumed that the pointers are valid and the pointer arithmetic is done correctly. One slight change to this example is it uses the dependently typed variant of &lt;code&gt;ptr&lt;/code&gt; with the constraint that the index is greater than &lt;code&gt;null&lt;/code&gt;. &lt;code&gt;ptrset&lt;/code&gt; and &lt;code&gt;ptrget&lt;/code&gt; are defined to take a pointer that is non null so &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt; in this example had to be modified to use these dependent types to prove the pointer is non-null.&lt;/p&gt;

&lt;h2 id='at_views'&gt;At Views&lt;/h2&gt;

&lt;p&gt;ATS has a concept called &amp;#8216;views&amp;#8217; which is part of the proof system. Views are linear resources that exist at type checking time and are erased during compilation. They have no runtime overhead and can be used to prove aspects of a program. For pointer handling there exists a type of view commonly called an &amp;#8216;At View&amp;#8217; or &amp;#8216;@ view&amp;#8217; because of their syntax. An at-view that represents that a type &lt;code&gt;T&lt;/code&gt; is stored at a memory location &lt;code&gt;L&lt;/code&gt; is written as &lt;code&gt;T @ L&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An at-view is often returned when memory containing a value of a particular type is allocated. The functions to get and set this memory then take the at-view as a proof argument along with the raw pointer. This tells the type system that you have a proof that the raw pointer points to that particular type. An at-view is linear so must be destroyed. By requiring the deallocating function to consume the at-view as a proof argument it can prevent further access to that memory address. It no longer exists to be able to be passed to the get and set functions.&lt;/p&gt;

&lt;p&gt;Using this approach will result in compile time errors if the pointer is used incorrectly. The following demonstrates the approach:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;staload _ = &amp;quot;prelude/DATS/pointer.dats&amp;quot;

extern fun malloc (s: sizeof_t int): [l:agz] (int @ l | ptr l) = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:agz} (pf: int @ l | p: ptr l): void = &amp;quot;mac#free&amp;quot;

implement main() = let
  val (pf | a) = malloc (sizeof&amp;lt;int&amp;gt;)          // 1
in
  ptr_set_t&amp;lt;int&amp;gt; (pf | a, 10);                 // 2
  print (ptr_get_t (pf | a)); print_newline(); // 3
  free (pf | a)                                // 4
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example, &lt;code&gt;malloc&lt;/code&gt; is changed to return a proof as well as the raw pointer. In ATS syntax proof arguments are to the left of the pipe, &lt;code&gt;|&lt;/code&gt;, symbol while non-proof arguments are to the right. The proof here is an at-view indicating that the type &lt;code&gt;int&lt;/code&gt; is stored at memory address &lt;code&gt;l&lt;/code&gt; - the same memory address as the raw pointer returned. The &lt;code&gt;free&lt;/code&gt; function is changed to take the at-view as a proof argument. It is consumed by the &lt;code&gt;free&lt;/code&gt; call (the absence of a &lt;code&gt;!&lt;/code&gt; symbol as part of the argument type means it is consumed). The addresses in these definitions have been changed to be &lt;code&gt;agz&lt;/code&gt; which is short for &amp;#8216;address greater than zero&amp;#8217; and is equivalent to the &lt;code&gt;[l:addr | l &amp;gt; null]&lt;/code&gt; form shown previously.&lt;/p&gt;

&lt;p&gt;In line &lt;code&gt;1&lt;/code&gt; malloc is called passing it the size of an integer. The at-view is stored in the &lt;code&gt;pf&lt;/code&gt; variable and the raw pointer in &lt;code&gt;a&lt;/code&gt;. In line &lt;code&gt;2&lt;/code&gt; the standard prelude function &lt;code&gt;ptr_set_t&lt;/code&gt; is used to set the value at the pointer address to &lt;code&gt;10&lt;/code&gt;. This requires the passing of the at-view to prove that we have an integer stored at that memory address. &lt;code&gt;pf&lt;/code&gt; is of type &lt;code&gt;int @ l&lt;/code&gt; where &lt;code&gt;l&lt;/code&gt; is the same address as the index type of &lt;code&gt;a&lt;/code&gt;. Line &lt;code&gt;3&lt;/code&gt; obtains the value at that address using the prelude function &lt;code&gt;ptr_get_t&lt;/code&gt;. Again we need the proof to get it. Line &lt;code&gt;4&lt;/code&gt; calls &lt;code&gt;free&lt;/code&gt; and consumes the proof.&lt;/p&gt;

&lt;p&gt;This example is safer than the previous examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can&amp;#8217;t forget to call &lt;code&gt;free&lt;/code&gt; as we would be left with the linear at-view alive and it would fail to compile.&lt;/li&gt;

&lt;li&gt;We can&amp;#8217;t pass any random pointer to &lt;code&gt;ptr_get_t&lt;/code&gt; or &lt;code&gt;ptr_set_t&lt;/code&gt;. These functions require an at-view that has the same address in it&amp;#8217;s type index as the raw pointers type index.&lt;/li&gt;

&lt;li&gt;We can&amp;#8217;t &lt;code&gt;malloc&lt;/code&gt; memory less than the size of the data we are storing there. The definition of &lt;code&gt;malloc&lt;/code&gt; declares that its initial argument is of type &lt;code&gt;sizeof_t int&lt;/code&gt; which is an integer that is the actual value returned by &lt;code&gt;sizeof int&lt;/code&gt;. Any other value passed would be a compile error.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='implicit_atview_usage'&gt;Implicit at-view usage&lt;/h2&gt;

&lt;p&gt;The use of at-views, &lt;code&gt;ptr_get_t&lt;/code&gt; and &lt;code&gt;ptr_set_t&lt;/code&gt; tends to clutter code somewhat. ATS provides some syntax to dereference pointers that automatically look for valid at-view proofs in scope. The changes to the previous example to use this are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;implement main() = let
  val (pf | a) = malloc {int} (sizeof&amp;lt;int&amp;gt;)
in
  !a := 10;
  print (!a); print_newline();
  free (pf | a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;!&lt;/code&gt; operator is like the unary &lt;code&gt;*&lt;/code&gt; operator in the C programming language. It dereferences a pointer. It requires an at-view to be in scope that has the same address as its indexed type as the pointer&amp;#8217;s indexed type. In this case the variable &lt;code&gt;a&lt;/code&gt; uses address &lt;code&gt;l&lt;/code&gt; which matches the &lt;code&gt;int @ l&lt;/code&gt; type of the &lt;code&gt;pf&lt;/code&gt; variable. &lt;code&gt;:=&lt;/code&gt; is assignment. As &lt;code&gt;pf&lt;/code&gt; is in scope for both the assignment and the &lt;code&gt;print&lt;/code&gt; call the code typechecks. If &lt;code&gt;pf&lt;/code&gt; wasn&amp;#8217;t in scope the code would fail to compile.&lt;/p&gt;

&lt;h2 id='getting_pointers_to_variables'&gt;Getting pointers to variables&lt;/h2&gt;

&lt;p&gt;The unary &lt;code&gt;&amp;amp;&lt;/code&gt; operator can be used like in the C programming language to get a pointer to a variable. Given a variable containing an integer &lt;code&gt;a&lt;/code&gt;, then &lt;code&gt;&amp;amp;a&lt;/code&gt; is of type &lt;code&gt;ptr&lt;/code&gt;. Note that this is a raw pointer which you can&amp;#8217;t derefence without an at-view in scope of type &lt;code&gt;int @ l&lt;/code&gt;. To obtain an at-view from an existing variable on the stack you use the &lt;code&gt;view@&lt;/code&gt; function. The result of &lt;code&gt;view@&lt;/code&gt; on a variable of type &lt;code&gt;T&lt;/code&gt; is an at-view of type &lt;code&gt;T @ l&lt;/code&gt; where &lt;code&gt;l&lt;/code&gt; is the memory address of the variable.&lt;/p&gt;

&lt;p&gt;The following code has an &lt;code&gt;add_one&lt;/code&gt; function that increments an integer by one given a pointer to it. The body of &lt;code&gt;main&lt;/code&gt; has an integer, &lt;code&gt;a&lt;/code&gt;, on the stack and &lt;code&gt;view@&lt;/code&gt; is used to obtain the at-view allowing dereferencing a pointer to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn add_one {l:agz} (pf: !int @ l | p: ptr l): void = 
  ! p := !p + 1

implement main() = let
  var a: int = 0
in
  print (a); print_newline();
  add_one (view@ a | &amp;amp;a);
  print (a); print_newline();
end&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='pairs'&gt;Pairs&lt;/h2&gt;

&lt;p&gt;One of the earlier raw pointer examples in this post allocated a memory area containing two integers and used pointer arithmetic to access the second integer offset from the original pointer. So far the at-view usage examples here have only used single values stored at a memory address. To access consecutive memory locations we can use arrays. ATS doesn&amp;#8217;t have arrays built into the language, rather they are implemented using views, at-views and pointers.&lt;/p&gt;

&lt;p&gt;To demonstrate how this is implemented we&amp;#8217;ll construct a simple example of rolling our own types to safely access memory containing two integers. Then I&amp;#8217;ll show how to use the standard prelude array handling for the same problem and hopefully that will give an idea of how things work under the covers.&lt;/p&gt;

&lt;p&gt;If we have a memory area containing two integers that we need to access individually we will need at-views for both memory locations containing the integers. We could write a function that takes both at-views individually:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun malloc (n: size_t (sizeof(int)*2)):
            [l:agz] (int @ l, int @ (l+sizeof(int)) | ptr l) = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:agz} (pf1: int @ l, pf2: int @ (l+sizeof(int)) | p: ptr l):void = &amp;quot;mac#free&amp;quot;

fn set {l:agz} (pf1: !int @ l, pf2: !int @ (l+sizeof(int)) | p: ptr l): void = begin
  !p := 10;
  !(p+sizeof&amp;lt;int&amp;gt;) := 20
end

implement main() = let
  val (pf1, pf2 | a) = malloc(sizeof&amp;lt;int&amp;gt; * 2)
in
  set (pf1, pf2 | a);
  print (!a); print_newline();
  print (!(a+sizeof&amp;lt;int&amp;gt;)); print_newline ();
  free(pf1, pf2 | a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example, &lt;code&gt;malloc&lt;/code&gt; is defined to allocate a memory area containing two integers. It restricts the number of bytes it receives as an argument to match exactly that of the size of two integers. It returns a pointer and two at-views as proofs. The first being an &lt;code&gt;int @ l&lt;/code&gt; and the second being an &lt;code&gt;int @ (l+sizeof(int))&lt;/code&gt;. This provides a caller of malloc with at-views allowing access to the integers that can be stored in the returned memory.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;set&lt;/code&gt; requires these two proofs so it can set the value of both integers in the memory area. The first is done via a simple dereference of the pointer, &lt;code&gt;p&lt;/code&gt;. The second adds &lt;code&gt;sizeof&amp;lt;int&amp;gt;&lt;/code&gt; to that pointer and dereferences it to set the value. This succeeds because there is a proof in scope (the &lt;code&gt;pf2&lt;/code&gt; at-view) that is for the correct type, &lt;code&gt;int&lt;/code&gt; and the memory address of the value being set. A mistake in the pointer arithmetic would result in a compile error.&lt;/p&gt;

&lt;p&gt;Passing multiple proofs around like this is a chore. To make it easier we can wrap them in a &lt;code&gt;dataview&lt;/code&gt;. A &lt;code&gt;dataview&lt;/code&gt; is like a &lt;code&gt;datatype&lt;/code&gt; but creates a linear datastructure used in proofs. This is the same example with the at-views wrapped in a &lt;code&gt;dataview&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dataview pair_v (l:addr) = PAIR (l) of (int @ l, int @ (l + sizeof(int)))

extern fun malloc (n: size_t (sizeof(int)*2)): [l:agz] (pair_v l | ptr l) = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:agz} (pf: pair_v l | p: ptr l):void = &amp;quot;mac#free&amp;quot;

fn set {l:agz} (pf: !pair_v l | p: ptr l): void = let
  prval PAIR (pf1, pf2) = pf
in
  !p := 10;
  !(p+sizeof&amp;lt;int&amp;gt;) := 20;
  pf := PAIR (pf1, pf2)
end

fn show {l:agz} (pf: !pair_v l | p: ptr l): void = let
  prval PAIR (pf1, pf2) = pf
in
  print (!p); print_newline();
  print (!(p+sizeof&amp;lt;int&amp;gt;)); print_newline ();
  pf := PAIR (pf1, pf2)
end

implement main() = let
  val (pf | a) = malloc(sizeof&amp;lt;int&amp;gt; * 2)
in
  set (pf | a);
  show (pf | a);
  free(pf | a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;pair_v&lt;/code&gt; dataview has a single constructor, &lt;code&gt;PAIR&lt;/code&gt;, that takes two at-views as arguments, one for each integer held in the pair. &lt;code&gt;malloc&lt;/code&gt; now returns a &lt;code&gt;pair_v&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt; consumes it. For &lt;code&gt;set&lt;/code&gt; to be able to dereference the pointer it needs to have the at-views in scope, not bundled in the &lt;code&gt;pair_v&lt;/code&gt; instance. To get them in scope it uses pattern matching on the &lt;code&gt;PAIR&lt;/code&gt; constructor to obtain the two proofs and have them in scope. As a &lt;code&gt;dataview&lt;/code&gt; is a linear type this will consume the &lt;code&gt;pair_v&lt;/code&gt;. This is why at the end of the scope the &lt;code&gt;PAIR&lt;/code&gt; constructor is used to create the &lt;code&gt;pair_v&lt;/code&gt; again and reassign it to the &lt;code&gt;pf&lt;/code&gt; proof variable.&lt;/p&gt;

&lt;p&gt;This proof unpacking and repacking is a common idiom for dealing with at-views and other proofs that need to be in scope. These are type level operations and are erased at compile time so contain no run time overhead.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;show&lt;/code&gt; function does the same to access the proofs to enable it to print the values at the memory address. It&amp;#8217;s also possible to use proof functions to further encapsulate access to the pointers.&lt;/p&gt;

&lt;p&gt;A nice feature of the use of at-views is you can have an array of memory containing lots of values but when you pass pointers to functions requiring only portions of this array you can give it a specific at-view or proof for only the area it needs to manage. The function cannot access any other part of the array since it does not have a proof for it. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dataview pair_v (l:addr) = PAIR (l) of (int @ l, int @ (l + sizeof(int)))

extern fun malloc (n: size_t (sizeof(int)*2)): [l:agz] (pair_v l | ptr l) = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:agz} (pf: pair_v l | p: ptr l):void = &amp;quot;mac#free&amp;quot;

fn set1 {l:agz} (pf: !int @ l | p: ptr l): void = 
  !p := 10;

fn show1 {l:agz} (pf: !int @ l | p: ptr l): void = 
  (print (!p); print_newline())

implement main() = let
  val (pf | a) = malloc(sizeof&amp;lt;int&amp;gt; * 2)
  prval PAIR (pf1, pf2) = pf
in
  set1 (pf1 | a);
  show1 (pf1 | a);
  pf := PAIR (pf1, pf2);
  free(pf | a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Although &lt;code&gt;set1&lt;/code&gt; and &lt;code&gt;show1&lt;/code&gt; here get a pointer to the memory address containing two integers they can only access the single integer at the pointer it is given. This is because the at-view it takes only is for &lt;code&gt;int @ l&lt;/code&gt;. To access the integer following this it would need to somehow obtain the at-view for it and it cannot.&lt;/p&gt;

&lt;h2 id='arrays'&gt;Arrays&lt;/h2&gt;

&lt;p&gt;The ATS prelude has an &lt;code&gt;array_v&lt;/code&gt; view for dealing with arrays that are a memory area containing consecutive elements of the same type. The &lt;code&gt;dataview&lt;/code&gt; definition looks like (it is actually not defined like this, but operates the same as if it was):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dataview array_v ( a:viewt@ype+, int, addr) =
  | {n:int | n &amp;gt;= 0} {l:addr}
    array_v_cons (a, n+1, l) of (a @ l, array_v (a, n, l+sizeof a))
  | {l:addr} array_v_nil (a, 0, l)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An &lt;code&gt;array_v&lt;/code&gt; has three type indexes. They are the type of the item in the array, the number of items in the array, and the address of the first element. It has two constructors. &lt;code&gt;array_v_nil&lt;/code&gt; is an empty array. &lt;code&gt;array_v_cons&lt;/code&gt; has two arguments, the first being the at-view for the first item and the second being an &lt;code&gt;array_v&lt;/code&gt; of the rest of the array. This is the previous pair example using &lt;code&gt;array_v&lt;/code&gt; instead:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;staload &amp;quot;prelude/SATS/array.sats&amp;quot;

extern fun malloc (n: size_t (sizeof(int)*2)): [l:agz] (array_v (int, 2, l) | ptr l) = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:agz} (pf: array_v (int, 2, l) | p: ptr l):void = &amp;quot;mac#free&amp;quot;

fn set1 {l:agz} (pf: !int @ l | p: ptr l): void = 
  !p := 10;

fn show1 {l:agz} (pf: !int @ l | p: ptr l): void = 
  (print (!p); print_newline())

implement main() = let
  val (pf | a) = malloc(sizeof&amp;lt;int&amp;gt; * 2)
  prval (pf1, pf2) = array_v_uncons (pf)
in
  set1 (pf1 | a);
  show1 (pf1 | a);
  pf := array_v_cons (pf1, pf2);
  free(pf | a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are various other operations for dealing with packing and unpacking the at-views from the &lt;code&gt;array_v&lt;/code&gt; view in &lt;code&gt;prelude/SATS/array.sats&lt;/code&gt;. Due to the list like nature of the &lt;code&gt;array_v&lt;/code&gt; definition it&amp;#8217;s easy to write recursive routines that walk through the array providing only access to the single item currently being operated on.&lt;/p&gt;

&lt;h2 id='initialized_vs_uninitialized_memory'&gt;Initialized vs uninitialized memory&lt;/h2&gt;

&lt;p&gt;When using pointers you often have to deal with a pointer to memory that has not yet been initialized. This is common when first allocating the memory. ATS differentiates unitialized memory from initialized by appending a &lt;code&gt;?&lt;/code&gt; to the type. For example, an &lt;code&gt;int?&lt;/code&gt; is a integer that has not been initialized. A &lt;code&gt;int? @ l&lt;/code&gt; is an at-view for an uninitialized integer at memory address &lt;code&gt;l&lt;/code&gt;. When the variable is initialized the type changes to drop the &lt;code&gt;?&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is useful for defining functions that must have valid data. The following will fail to compile because the &lt;code&gt;show1&lt;/code&gt; function requires the memory to first have been set:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun malloc (n: sizeof_t int): [l:agz] (int? @ l | ptr l) = &amp;quot;mac#malloc&amp;quot;
extern fun free {l:agz} (pf: int? @ l | p: ptr l):void = &amp;quot;mac#free&amp;quot;

fn set1 {l:agz} (pf: !int? @ l &amp;gt;&amp;gt; int @ l | p: ptr l): void = 
  !p := 10;

fn show1 {l:agz} (pf: !int @ l | p: ptr l): void = 
  (print (!p); print_newline())

implement main() = let
  val (pf | a) = malloc(sizeof&amp;lt;int&amp;gt;)
in
//  set1 (pf | a);
  show1 (pf | a);
  free(pf | a)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Uncommenting the &lt;code&gt;set1&lt;/code&gt; call enables it to compile. The &lt;code&gt;set1&lt;/code&gt; definition declares that it requires an at-view for an uninitialized int and after calling the at-view becomes one for an initialized int. The syntax &lt;code&gt;T1 &amp;gt;&amp;gt; T2&lt;/code&gt; means that on calling a &lt;code&gt;T1&lt;/code&gt; is required but after calling it becomes a &lt;code&gt;T2&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;ATS provides access to pointers at the level of the C programming language but provides a type system, combined with proofs, that enable using this memory safely. This comes with no runtime overhead. There are many other ways of structuring memory access using ATS, beyond the simple examples here. ATS allows memory allocation on the stack, which is reclaimed when the stack frame exits, and prevents access to the memory after it is reclaimed, optional garbage collection, and other features which I haven&amp;#8217;t gone through.&lt;/p&gt;

&lt;p&gt;Some pointers to futher reading on this subject, and which helped with the writing of this post, are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.ats-lang.org/DOCUMENT/INTPROGINATS/HTML/c3217.html#views_for_pointers'&gt;Views for Memory Access through Pointers&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.ats-lang.org/DOCUMENT/INTPROGINATS/HTML/x3427.html'&gt;Linear Arrays&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.ats-lang.org/DOCUMENT/INTPROGINATS/HTML/x3550.html'&gt;Proof Functions for View Changes&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.ats-lang.org/PAPER/SPPSV-padl05.pdf'&gt;Sane Programming with Pointers through Stateful Views&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Inferno OS IRC client with persistent connections</title>
   <link href="http://bluishcoder.co.nz/2012/12/19/inferno-os-irc-client-with-persistent-connections.html"/>
   <updated>2012-12-19T20:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2012/12/19/inferno-os-irc-client-with-persistent-connections</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve written before about how &lt;a href='http://www.vitanuova.com/inferno/'&gt;Inferno&lt;/a&gt; makes it easy to &lt;a href='/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html'&gt;share resources across devices and networks&lt;/a&gt;. In this post I show how to use IRC from within Inferno and then how to run the IRC connection handling on a server and the GUI on a client machine. The server can stay connected giving a persistent IRC connection similar to how IRC proxies and bouncers are used.&lt;/p&gt;

&lt;p&gt;The IRC client I&amp;#8217;m using for Inferno is written by &lt;a href='http://www.ueber.net/who/mjl/inferno/'&gt;mjl&lt;/a&gt;. A large number of useful Inferno and Plan 9 utilities with source is available at &lt;a href='https://bitbucket.org/mjl/'&gt;mjl&amp;#8217;s bitbucket repository&lt;/a&gt;. The one that provides IRC capability is &lt;a href='https://bitbucket.org/mjl/ircfs'&gt;ircfs&lt;/a&gt;. This is written in a manner that exposes IRC connections as a file system using the 9p2000 protocol. The GUI communicates with IRC via the file system.&lt;/p&gt;

&lt;h2 id='building'&gt;Building&lt;/h2&gt;

&lt;p&gt;Building from within Inferno requires a couple of environment variables to be set. &lt;code&gt;ROOT&lt;/code&gt; is the path to the root of the Inferno system and &lt;code&gt;SYSHOST&lt;/code&gt; should be set to &amp;#8216;Inferno&amp;#8217;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cd ircfs
% ROOT=/
% SYSHOST=Inferno
% mk install
cd module ; mk install
mk: &amp;#39;install&amp;#39; is up to date
cd appl ; mk install
cd cmd ; mk install
rm -f /dis/testirc.dis &amp;amp;&amp;amp; cp testirc.dis /dis/testirc.dis
rm -f /dis/ircfs.dis &amp;amp;&amp;amp; cp ircfs.dis /dis/ircfs.dis
cd wm ; mk install
mk: &amp;#39;install&amp;#39; is up to date
cd lib ; mk install
mk: &amp;#39;install&amp;#39; is up to date
cd man ; mk install
mk: &amp;#39;install&amp;#39; is up to date&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This installs &lt;code&gt;ircfs&lt;/code&gt; into the standard Inferno application and command locations. It may not be desirable to clutter the existing system locations with additional programs like this. If you prefer you can create local directories to hold the installed programs and &lt;code&gt;bind&lt;/code&gt; this over the system directories using a union file system. &lt;code&gt;ircfs&lt;/code&gt; installs a useful &lt;code&gt;man&lt;/code&gt; page which is worth reading to find out all the options.&lt;/p&gt;

&lt;h2 id='running_ircfs'&gt;Running ircfs&lt;/h2&gt;

&lt;p&gt;When &lt;code&gt;ircfs&lt;/code&gt; is executed it creates a directory structure that contains the files that allow clients to send and receive data to the service. To run it we first create a directory underneath &lt;code&gt;/mnt/irc&lt;/code&gt; for the server we want to connect to, then run &lt;code&gt;ircfs&lt;/code&gt; passing this directory name:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mkdir -p /mnt/irc/freenode
% mount {ircfs freenode} /mnt/irc/freenode
% ls /mnt/irc/freenode
/mnt/irc/freenode/0
/mnt/irc/freenode/ctl
/mnt/irc/freenode/event
/mnt/irc/freenode/nick
/mnt/irc/freenode/pong
/mnt/irc/freenode/raw&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The example above shows the files that exist after running and mounting the &lt;code&gt;ircfs&lt;/code&gt; service. The &lt;code&gt;mount&lt;/code&gt; command uses the variant that runs and mounts a 9p service.&lt;/p&gt;

&lt;p&gt;The running &lt;code&gt;ircfs&lt;/code&gt; hasn&amp;#8217;t connected to any IRC server yet. Connections and controlling of the IRC server is managed via writing or reading from the files under &lt;code&gt;/mnt/irc/freenode&lt;/code&gt;. The protocol is explained in the &lt;code&gt;ircfs&lt;/code&gt; man page. For example, writing to &lt;code&gt;ctl&lt;/code&gt; allows us to connect to a server. Reading from &lt;code&gt;nick&lt;/code&gt; gives the current nickname used by the connected user.&lt;/p&gt;

&lt;p&gt;Ensure that &lt;code&gt;ndb/cs&lt;/code&gt; is running to allow network connections from Inferno before continuing.&lt;/p&gt;

&lt;h2 id='running_the_irc_gui'&gt;Running the IRC GUI&lt;/h2&gt;

&lt;p&gt;The GUI for &lt;code&gt;ircfs&lt;/code&gt; is run with the command &lt;code&gt;wm/irc&lt;/code&gt;, optionally passing the path to the &lt;code&gt;ircfs&lt;/code&gt; directory structure as an argument:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% wm/irc /mnt/irc/freenode&lt;/code&gt;&lt;/pre&gt;
&lt;a href='/images/wmirc1.png'&gt;&lt;img alt='Image of wm/irc running' src='/images/wmirc1.png' title='Image of wm/irc running' width='160' /&gt;&lt;/a&gt;
&lt;p&gt;On the left of the &lt;code&gt;wm/irc&lt;/code&gt; screen is a list of the servers and channels. Currently there is &lt;code&gt;status&lt;/code&gt; and &lt;code&gt;(freenode)&lt;/code&gt;. The &lt;code&gt;(freenode)&lt;/code&gt; window is for sending commands to the irc server once we&amp;#8217;re connected. To connect to &lt;code&gt;irc.freenode.net&lt;/code&gt; enter the following in the &lt;code&gt;(freenode)&lt;/code&gt; area:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/connect irc.freenode.net mynick&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The status messages from the server should now appear. The commands that &lt;code&gt;ircfs&lt;/code&gt; understands are documented in the &lt;code&gt;/ctl&lt;/code&gt; section of the ircfs man page. Standard IRC client commands like &lt;code&gt;/join&lt;/code&gt;, etc work and the channels will appear on the list in the left of the client window. The &lt;code&gt;ircfs&lt;/code&gt; server remains running and connected if the GUI is closed. Running the GUI again with the path to the &lt;code&gt;ircfs&lt;/code&gt; directory will display the existing channels connected and you can continue where you left off before it was closed.&lt;/p&gt;

&lt;h2 id='gui_commands'&gt;GUI commands&lt;/h2&gt;

&lt;p&gt;The GUI knows some special commands that can be passed to it using &lt;code&gt;/win&lt;/code&gt;. These are explained in the main page for &lt;code&gt;wm/irc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add&lt;/code&gt; can be used to add new &lt;code&gt;ircfs&lt;/code&gt; directories to a running GUI. If you start &lt;code&gt;wm/irc&lt;/code&gt; without passing it a directory for example you can type the following in the &lt;code&gt;status&lt;/code&gt; window to connect to one:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/win add /mnt/irc/freenode&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;del&lt;/code&gt; removes the current &lt;code&gt;ircfs&lt;/code&gt; directory so the GUI no longer displays informatation about it. You can use &lt;code&gt;add&lt;/code&gt; to get the GUI to redisplay it. Note that these two commands don&amp;#8217;t affect the actual IRC connection. That remains managed by &lt;code&gt;ircfs&lt;/code&gt;. It only affects what is displayed in the GUI:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/win del&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;windows&lt;/code&gt; command gives a list of all the windows for the current &lt;code&gt;ircfs&lt;/code&gt; connection and their control number. This number can be used to close and open channel windows in the GUI:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/win windows
open:
  (freenode)   (0)
  #inferno     (1)
not open:

/win close
/win windows
open:
  (freenode)   (0)
not open:
  #inferno     (1)

/win open 1
/win windows
open:
  (freenode)   (0)
  #inferno     (1)
not open:&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;away&lt;/code&gt; can be used to mark the user as away or back on all servers. &lt;code&gt;exit&lt;/code&gt; will exit the GUI but leave &lt;code&gt;ircfs&lt;/code&gt; connections intact.&lt;/p&gt;

&lt;h2 id='persistent_connections'&gt;Persistent connections&lt;/h2&gt;

&lt;p&gt;I prefer to have a persistent IRC connection on a server and connect to it from a client so I can catch up with channel logs and activity while I&amp;#8217;ve been away. This allows other users to leave me messages when I&amp;#8217;m disconnected. It also allows connecting using multiple devices and keeping my conversation active. This approach usually requires running IRSSI in a screen session on a server, or running an IRC proxy or bouncer.&lt;/p&gt;

&lt;p&gt;A similar approach can be done using &lt;code&gt;ircfs&lt;/code&gt; by running the &lt;code&gt;ircfs&lt;/code&gt; server on a remote machine and on the client mounting the &lt;code&gt;ircfs&lt;/code&gt; filesystem. The connection can be &lt;a href='/2012/12/18/authentication-and-encryption-in-inferno-os.html'&gt;encrypted and authenticated&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following is a simple setup. Install Inferno on the remote server and build and install &lt;code&gt;ircfs&lt;/code&gt; as described previously. Run &lt;code&gt;ircfs&lt;/code&gt; to run the server. In this example I also add a command line switch to log the IRC connection so I can have channel logs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mkdir -p /mnt/irc/freenode
; mount {ircfs -t -l /usr/myuser/irclogs freenode} /mnt/irc/freenode
; styxlisten net!*!16667 {export /mnt/irc}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On the client we mount this exported filesystem using encryption (replace &lt;code&gt;example.com&lt;/code&gt; with the hostname of the server):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mount -C sha1/rc4_256 net!example.com!16667 /mnt/irc
% ls /mnt/irc/freenode
/mnt/irc/freenode/0
/mnt/irc/freenode/ctl
/mnt/irc/freenode/event
/mnt/irc/freenode/nick
/mnt/irc/freenode/pong
/mnt/irc/freenode/raw&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The directory and files shown are those from the remote server. Running &lt;code&gt;wm/irc&lt;/code&gt; will now use the servers &lt;code&gt;ircfs&lt;/code&gt; files:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% wm/irc /mnt/irc/freenode&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can now connect to the irc.freenode.net server, join channels then close the IRC window and shut down the client. Next time you restart the client, &lt;code&gt;mount&lt;/code&gt; the remote filesystem again and continue where you left off.&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The man pages for &lt;code&gt;ircfs&lt;/code&gt; and &lt;code&gt;wm/irc&lt;/code&gt; have more detail on the commands and keys that can be used. There are other things that can be done with &lt;code&gt;ircfs&lt;/code&gt; other than GUI IRC programs. It&amp;#8217;s possible to write IRC bots and programs by utilising the control files and directories of an &lt;code&gt;ircfs&lt;/code&gt; session.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ircfs&lt;/code&gt; source is written in Limbo and is quite easy to follow. It&amp;#8217;s a good example of mapping an existing protocol onto Inferno&amp;#8217;s &amp;#8220;everything is a file&amp;#8221; metaphor and making use of the tools to share resources. One use of this is having Inferno on other devices, &lt;a href='/2012/06/11/building-inferno-os-for-android-phones.html'&gt;like a phone&lt;/a&gt;, so you can connect to IRC connections running on a local machine if you temporarily need to be mobile.&lt;/p&gt;</content>
 </entry>
 
 
</feed>
