<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bluish Coder: inferno</title>
 <link href="http://bluishcoder.co.nz/tag/inferno/atom.xml" rel="self"/>
 <link href="http://bluishcoder.co.nz/"/>
 <updated>2020-07-10T16:25:05+12:00</updated>
 <id>http://bluishcoder.co.nz/</id>
 <author>
   <name>Bluishcoder</name>
   <email>admin@bluishcoder.co.nz</email>
 </author>

 
 <entry>
   <title>Bundling Inferno Applications</title>
   <link href="http://bluishcoder.co.nz/2016/08/12/bundling-inferno-applications.html"/>
   <updated>2016-08-12T18:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2016/08/12/bundling-inferno-applications</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://inferno-os.org/&quot;&gt;Inferno&lt;/a&gt; can run as a standalone OS or hosted in an existing OS. In the latter case an &lt;code&gt;emu&lt;/code&gt; executable runs and executes as a virtual operating system. An application written in &lt;a href=&quot;http://www.vitanuova.com/inferno/papers/limbo.html&quot;&gt;Limbo&lt;/a&gt; runs inside this virtual OS. When distributing such an application you can install Inferno on the target machine with the application compiled code inside the filesystem of Inferno. This will include a bunch of stuff that the application may not need since it includes all the utilities for the operating system. To distribute the minimal amount of dependencies to run the Limbo application you can create a cut down Inferno distribution that only includes the application dependencies and run that. Another option is to bundle the root filesystem into the executable leaving only that executable to be distributed.&lt;/p&gt;

&lt;h2&gt;Application specific Inferno&lt;/h2&gt;

&lt;p&gt;To create an application specific Inferno install we need to find out what the dependencies are for the application. Most of the following comes from &lt;a href=&quot;https://geektimes.ru/post/43180/&quot;&gt;powerman&#39;s post on the topic&lt;/a&gt; in Russian.&lt;/p&gt;

&lt;p&gt;When running &lt;code&gt;emu&lt;/code&gt; it runs a program &lt;code&gt;/dis/emuinit.dis&lt;/code&gt; to initialize the system and start the shell or other program. An application specific Inferno distribution would require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;emu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/dis/emuinit.dis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/dis/lib/emuinit.dis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Your application program files inside the Inferno directory structure somewhere.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Powerman&#39;s post goes into detail on how to do this with the following &quot;Hello World&quot; Limbo application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;implement HelloWorld;
include &quot;sys.m&quot;;
include &quot;draw.m&quot;;

HelloWorld: module
{
    init: fn(nil: ref Draw-&amp;gt;Context, nil: list of string);
};

init(nil: ref Draw-&amp;gt;Context, nil: list of string)
{
    sys := load Sys Sys-&amp;gt;PATH;
    sys-&amp;gt;print(&quot;Hello World!\n&quot;);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this in a &lt;code&gt;helloworld.b&lt;/code&gt; file, compiling it produces &lt;code&gt;helloworld.dis&lt;/code&gt;. This contains the compiled bytecode for the &lt;a href=&quot;http://www.vitanuova.com/inferno/papers/dis.html&quot;&gt;Dis virtual machine&lt;/a&gt;. &lt;a href=&quot;http://www.vitanuova.com/inferno/man/1/disdep.html&quot;&gt;disdep&lt;/a&gt; will list the dependencies that it requires:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; limbo helloworld.b
; ./helloworld
Hello World!
; disdep helloworld.dis
; disdep /dis/emuinit.dis
/dis/lib/arg.dis
/dis/sh.dis
/dis/lib/bufio.dis
/dis/lib/env.dis
/dis/lib/readdir.dis
/dis/lib/filepat.dis
/dis/lib/string.dis
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This shows the &lt;code&gt;helloworld&lt;/code&gt; has no dependencies outside of what&#39;s already built into &lt;code&gt;emu&lt;/code&gt; and &lt;code&gt;emuinit.dis&lt;/code&gt; contains a few. Creating a directory layout with just these files and &lt;code&gt;emu&lt;/code&gt; should be enough to run &lt;code&gt;helloworld&lt;/code&gt;. In the following example &lt;code&gt;foo&lt;/code&gt; is the directory containing the full Inferno distribution where &lt;code&gt;helloworld.b&lt;/code&gt; was compiled.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir -p hw/dis/lib
$ cd hw
$ cp ../foo/Linux/386/bin/emu .
$ cp ../foo/dis/emuinit.dis dis/
$ cp ../foo/dis/lib/arg.dis dis/lib/
$ cp ../foo/dis/lib/bufio.dis dis/lib/
$ cp ../foo/dis/lib/env.dis dis/lib/
$ cp ../foo/dis/lib/readdir.dis dis/lib/
$ cp ../foo/dis/lib/filepat.dis dis/lib/
$ cp ../foo/dis/lib/string.dis dis/lib/
$ cp ../foo/dis/sh.dis dis/
$ cp ../foo/usr/inferno/helloworld.dis .
$ ./emu -r. helloworld
Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some of these dependencies aren&#39;t needed, for example &lt;code&gt;sh.dis&lt;/code&gt; as we don&#39;t run the shell. See &lt;a href=&quot;https://geektimes.ru/post/43180/&quot;&gt;Powerman&#39;s post&lt;/a&gt; for a more extensive example that has dependencies.&lt;/p&gt;

&lt;h2&gt;Bundling application into emu&lt;/h2&gt;

&lt;p&gt;Instead of distributing a directory of files as in the previous example it&#39;s possible to bundle a root filesystem inside the &lt;code&gt;emu&lt;/code&gt; program. This allows distributing just a single executable that runs the Limbo application. The steps to do this involve finding the dependencies of the program as above and creating a &lt;a href=&quot;http://man.cat-v.org/inferno/10/conf&quot;&gt;kernel configuration file&lt;/a&gt; that lists them.&lt;/p&gt;

&lt;p&gt;The file &lt;code&gt;/emu/Linux/emu&lt;/code&gt; is the kernel configuration file for the Linux Inferno VM. It has a &lt;code&gt;root&lt;/code&gt; section which defines the root filesystem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root
        /dev    /
        /fd     /
        /prog   /
        /prof   /
        /net    /
        /net.alt        /
        /chan   /
        /nvfs   /
        /env    /
#       /dis
#       /n
#       /icons
#       /osinit.dis
#       /dis/emuinit.dis
#       /dis/lib/auth.dis
#       /dis/lib/ssl.dis
#       /n/local /
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The actual filesystem as located by the &lt;code&gt;-r&lt;/code&gt; command line argument to &lt;code&gt;emu&lt;/code&gt; is overlayed on top of this. Copying this file and adding our dependencies will bundle them into a custom build executable. This is what the &lt;code&gt;root&lt;/code&gt; section of our &lt;code&gt;helloworld&lt;/code&gt; looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root
        /dev    /
        /fd     /
        /prog   /
        /prof   /
        /net    /
        /net.alt        /
        /chan   /
        /nvfs   /
        /env    /
        /dis
        /dis/emuinit.dis /usr/chris/helloworld.dis
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here we make &lt;code&gt;helloworld.dis&lt;/code&gt; appear in the root filesystem as &lt;code&gt;/dis/emuinit.dis&lt;/code&gt;, which is the first program run as the system comes up. Note that this file must use tabs, not spaces, for the entries. An executable can be compiled with this bundled root filesystem with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd emu/Linux
$ ...create helloworld configuration file...
$ mk CONF=helloworld
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This produces an executable &lt;code&gt;o.helloworld&lt;/code&gt; which when run will execute the &lt;code&gt;helloworld.dis&lt;/code&gt; embedded inside it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./o.helloworld
Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When stripped the executable is about 1.5MB. This executable links to the X11 libraries. For a headless system you can remove the dependancy by using the &lt;code&gt;emu-g&lt;/code&gt; kernel configuration file as a base. This removes the drivers that use X11 and prevents linking against the X11 libraries. The resulting executable when stripped is now 700K.&lt;/p&gt;

&lt;p&gt;The executable produced by this process has some dynamic dependencies - libc, etc - that most glibc applications have. It should be possible to use &lt;a href=&quot;https://www.musl-libc.org/&quot;&gt;musl-libc&lt;/a&gt; to produce a static binary and I&#39;ll cover this in another post.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Using Inferno OS on Linux</title>
   <link href="http://bluishcoder.co.nz/2014/12/31/using-inferno-os-on-linux.html"/>
   <updated>2014-12-31T15:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2014/12/31/using-inferno-os-on-linux</id>
   <content type="html">&lt;p&gt;It&#39;s the end of the year and I&#39;m going through some of the patches I have for projects and putting them online so I have a record of them. I&#39;m working through things I did on &lt;a href=&quot;http://inferno-os.org/&quot;&gt;Inferno OS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Source respositories&lt;/h2&gt;

&lt;p&gt;The official Inferno source is hosted in a &lt;a href=&quot;https://code.google.com/p/inferno-os/&quot;&gt;mercurial repository&lt;/a&gt; on Google Code. There is also a repository containing a snapshot of this with &lt;a href=&quot;https://bitbucket.org/floren/inferno/wiki/Home&quot;&gt;changes to get Inferno building on Android systems&lt;/a&gt; on bitbucket. Finally there is a &lt;a href=&quot;http://inferno-os.org/inferno/downloads.html&quot;&gt;tarball containing a snapshot&lt;/a&gt; which includes fonts required by Inferno that are not stored in the mercurial repository.&lt;/p&gt;

&lt;p&gt;I carry a couple of custom patches to Inferno and I also have &lt;a href=&quot;http://bluishcoder.co.nz/2012/06/11/building-inferno-os-for-android-phones.html&quot;&gt;changes to the Android port&lt;/a&gt; that I keep in a &lt;a href=&quot;http://bluishcoder.co.nz/inferno/inferno.patch&quot;&gt;patch file&lt;/a&gt;. When working on these I find it useful to be able to diff between the current Inferno source and the Hellaphone source to see what changes were made.&lt;/p&gt;

&lt;p&gt;I&#39;ve cleaned these up and put the patches in a github repository with a conversion of the mercurial repositories to git. The Hellaphone code is a branch of the repository makeing it easy to cherry pick and diff between that and the main source. I&#39;ve put this in &lt;a href=&quot;https://github.com/doublec/inferno&quot;&gt;github.com/doublec/inferno&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are four main branches in that repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;20100120&lt;/code&gt; - Snapshot with the additional fonts&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hellaphone&lt;/code&gt; - Hellaphone Android port&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inferno&lt;/code&gt; - Direct import of the Inferno mercurial repository&lt;/li&gt;
&lt;li&gt;&lt;code&gt;master&lt;/code&gt; - Everything needed for building inferno on Linux. It is a recent working version of the &lt;code&gt;inferno&lt;/code&gt;

&lt;pre&gt;&lt;code&gt;branch with the additional fonts from the `20100120` branch and any additional work in progress patches
to work around existing issues.
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I use &lt;code&gt;master&lt;/code&gt; for running Inferno on desktop and &lt;code&gt;hellaphone&lt;/code&gt; for phone development. The &lt;a href=&quot;https://github.com/doublec/inferno/blob/master/README.md&quot;&gt;README on master&lt;/a&gt; explains how to build and the &lt;a href=&quot;https://github.com/doublec/inferno/blob/hellaphone/README.md&quot;&gt;README on hellaphone&lt;/a&gt; has the steps to get it running on a phone.&lt;/p&gt;

&lt;h2&gt;Building on Linux&lt;/h2&gt;

&lt;p&gt;Building Inferno on Linux with the official source involves downloading an archive containing a snapshot of the source with the addition of some font files that are licensed differently. You then do a mercurial update to get the latest source code. Something like the following performs the build:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ wget http://www.vitanuova.com/dist/4e/inferno-20100120.tgz
$ tar xvf inferno-20100120.tgz
$ cd inferno
$ hg pull -u
$ ...edit mkconfig so entries are set below...
ROOT=/path/to/inferno
SYSHOST=Linux
OBJTYPE=386
$ export PATH=$PATH:`pwd`/Linux/386/bin
$ ./makemk.sh
$ mk nuke
$ mk install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Building using my github repository requires:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/doublec/inferno
$ cd inferno
$ sh Mkdirs
$ .. edit `mkconfig` to so the following entries are set to these values...
ROOT=/root/of/the/inferno/git/clone
SYSHOST=Linux
OBJTYPE=386
$ export PATH=$PATH:`pwd`/Linux/386/bin
$ ./makemk.sh
$ mk nuke
$ mk install
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Running Inferno&lt;/h2&gt;

&lt;p&gt;I use a shell script to run Inferno. The contents look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export PATH=$PATH:~/inferno/Linux/386/bin
export EMU=&quot;-r/home/$USER/inferno -c1 -g1920x1008&quot;
exec emu $* /dis/sh.dis -a -c &quot;wm/wm wm/logon -u $USER&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This starts Inferno using the same username as on the Linux system and with the desktop size set to 1920x1008. The JIT is enabled (the &lt;code&gt;-c1&lt;/code&gt; flag does this). For this to work I need to have a &lt;code&gt;/usr/chris&lt;/code&gt; directory in the Inferno file system with some default files. This can be created by copying the existing &lt;code&gt;/usr/inferno&lt;/code&gt; directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd inferno
$ cp -r usr/inferno usr/chris
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The patches in my &lt;code&gt;master&lt;/code&gt; branch add a &lt;code&gt;-F&lt;/code&gt; command line switch to the &lt;code&gt;emu&lt;/code&gt; command to use full screen in X11. This is useful when using a window manager that doesn&#39;t allow switching to and from full screen. On Ubuntu I often run Inferno full screen in a workspace that I can switch back and forth to get between Linux and Inferno. This can be run with the above shell script (assuming it is named &lt;code&gt;inferno&lt;/code&gt; and on the path):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ inferno -F
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Accessing the host filesystem and commands&lt;/h2&gt;

&lt;p&gt;Often I want to access the host filesystem from within Inferno. This can be done using &lt;code&gt;bind&lt;/code&gt; with a special path syntax to represent the host system. I like to keep the path on Inferno the same as the path on Linux so when running host commands the paths in error messages match up. This makes it easier to click on error messages and load the file in Inferno text editors. I map &lt;code&gt;/home&lt;/code&gt; as follows (&#39;;&#39; represents an Inferno shell prompt):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mkdir /home
; bind &#39;#U*/home&#39; /home
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now all the directories and files under &lt;code&gt;/home&lt;/code&gt; in Linux are available under &lt;code&gt;/home&lt;/code&gt; in Inferno.&lt;/p&gt;

&lt;p&gt;The Inferno &lt;code&gt;os&lt;/code&gt; command is used to run host programs from within Inferno. To run &lt;code&gt;git&lt;/code&gt; for example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; os -d /home/username/inferno git status
...output of git...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that I had to pass the &lt;code&gt;-d&lt;/code&gt; switch and to give the path on the host filesystem that will be the current working directory for the command. I can even do Firefox builds from within Inferno:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; cd /home/username/firefox
; os -d /home/username/firefox ./mach build
...firefox building...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Any errors in source files that appear can be shown in the Inferno acme editor as I&#39;ve mapped &lt;code&gt;/home&lt;/code&gt; to be the same on Inferno as on the host.&lt;/p&gt;

&lt;h2&gt;VNC in Inferno&lt;/h2&gt;

&lt;p&gt;Sometimes I need to run graphical host commands from within Inferno. Mechiel Lukkien has a large number of &lt;a href=&quot;https://bitbucket.org/mjl&quot;&gt;useful Inferno programs&lt;/a&gt; written in Limbo. One of these is a &lt;a href=&quot;https://bitbucket.org/mjl/vnc&quot;&gt;vnc client&lt;/a&gt;. From a source clone of this project it can be installed in Inferno with something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; cd vnc
; SYSROOT=Inferno
; ROOT=
; mk install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Start a VNC server from the Linux side:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ vncpasswd
...set password...
$ vncserver :1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Connect to it from the Inferno side:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; vncv tcp!127.0.0.1!5901
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can run Firefox and other useful programs from within Inferno. Inferno has its own web browser, Charon, but it&#39;s nice to be able to use a full browser, terminals, etc to do Linux things from within Inferno when needed. &lt;code&gt;vncv&lt;/code&gt; isn&#39;t feature complete - it doesn&#39;t do modifier keys unfortunately, but is still a useful tool.&lt;/p&gt;

&lt;p&gt;Mechiel Lukkien has many other useful libraries worth exploring. There is an &lt;code&gt;ssh&lt;/code&gt; implementation, a mercurial client, and an interesting &#39;irc filesystem&#39; which &lt;a href=&quot;http://bluishcoder.co.nz/2012/12/19/inferno-os-irc-client-with-persistent-connections.html&quot;&gt;I&#39;ve written about before&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Other tips&lt;/h2&gt;

&lt;p&gt;Acme is one of the editors available in Inferno. It&#39;s also available on other operating systems and Russ Cox has a &lt;a href=&quot;http://research.swtch.com/acme&quot;&gt;Tour of Acme&lt;/a&gt; video which explains its features. Most of these work in the Inferno port too.&lt;/p&gt;

&lt;p&gt;Pete Elmore has an introduction to &lt;a href=&quot;http://debu.gs/entries/inferno-part-1-shell&quot;&gt;the Inferno shell&lt;/a&gt; and &lt;a href=&quot;http://debu.gs/tags/inferno&quot;&gt;other Inferno posts&lt;/a&gt;. The shell has a way of passing data from one shell command to another. For example, &lt;code&gt;du&lt;/code&gt; can recursively list all files in the current directory and subdirectories:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; du -an
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To pass this list to &lt;code&gt;grep&lt;/code&gt; to find the text &#39;ASSERT&#39; within these files:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; grep -n ASSERT `{du -an}
filename.h:100: ASSERT(1)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Limbo&lt;/h2&gt;

&lt;p&gt;Limbo is the programming language used in Inferno. It is a typed programming language with support for concurrency using channels and lightweight threads. The book &lt;a href=&quot;http://doc.cat-v.org/inferno/books/inferno_programming_with_limbo/Inferno_Programming_With_Limbo.pdf&quot;&gt;Inferno Programming with Limbo&lt;/a&gt; is available as a PDF and also makes for a good introduction to Inferno itself. The line between Inferno as an OS and Inferno as a language runtime is a bit blurry at times.&lt;/p&gt;

&lt;h2&gt;Why Inferno?&lt;/h2&gt;

&lt;p&gt;Inferno has some interesting ideas with regards to distributing computing power and provides a way to explore some ideas that were in the &lt;a href=&quot;http://plan9.bell-labs.com/plan9/&quot;&gt;Plan 9 OS&lt;/a&gt; but useable on multple platforms. My post on &lt;a href=&quot;http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html&quot;&gt;sharing computer and phone resources&lt;/a&gt; gives some examples of ways it could be used. Its lightweight threads and concurrency make for useful programming system for server based tasks.&lt;/p&gt;

&lt;p&gt;Inferno is a small hackable OS for learning about operating systems. For more on this the book &lt;a href=&quot;http://www.amazon.com/Principles-Operating-Systems-Applications-Advanced/dp/1418837695&quot;&gt;Principles of Operating Systems&lt;/a&gt; by Brian Stuart covers Inferno and Linux. One aspect I was interested in exploring was porting parts of the OS from C to the &lt;a href=&quot;http://www.ats-lang.org/&quot;&gt;ATS programming language&lt;/a&gt; in a similar manner to what I describe in my &lt;a href=&quot;http://bluishcoder.co.nz/2014/04/11/preventing-heartbleed-bugs-with-safe-languages.html&quot;&gt;preventing heartbleed bugs with safer programming languages&lt;/a&gt; post.&lt;/p&gt;

&lt;p&gt;More on Inferno is available at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://inferno-os.org/&quot;&gt;Official Inferno OS website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://groups.google.com/forum/#!forum/inferno-os&quot;&gt;Inferno Google Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#inferno&lt;/code&gt; on irc.freenode.net&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.reddit.com/r/inferno&quot;&gt;/r/inferno subreddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.gemusehaken.org/ipwl/&quot;&gt;Inferno Programming with Limbo resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.gemusehaken.org/ipwl/irp-inferno.pdf&quot;&gt;Building distributed applications with Inferno and Limbo&lt;/a&gt; (PDF)&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <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=&quot;http://www.vitanuova.com/inferno/&quot;&gt;Inferno OS&lt;/a&gt; ships with a version of the &lt;a href=&quot;http://acme.cat-v.org/&quot;&gt;acme&lt;/a&gt; text editor. I&#39;ve tried to use acme on and off for a bit and it never stuck. I&#39;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=&quot;http://research.swtch.com/acme&quot;&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=&quot;http://sam.cat-v.org/&quot;&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=&quot;http://research.swtch.com/acme&quot;&gt;A Tour of Acme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/4th_edition/papers/acme/&quot;&gt;Acme: A User Interface for Programmers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://man.cat-v.org/inferno/1/acme&quot;&gt;Acme man page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/bell_labs/sam_lang_tutorial/&quot;&gt;A Tutorial for the Sam Command Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/4th_edition/papers/sam/&quot;&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=&quot;http://double.co.nz/creatures/&quot;&gt;Creatures Developer Resource&lt;/a&gt; website, recovering from &lt;a href=&quot;http://bluishcoder.co.nz/2013/04/03/parts-of-this-site-temporarily-down.html&quot;&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 &#39;#U*&#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 &#39;html?$&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From the &lt;a href=&quot;http://doc.cat-v.org/plan_9/4th_edition/papers/sam/&quot;&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 &#39;html?$&#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&#39;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=&quot;http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os.html&quot;&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=&quot;http://www.vitanuova.com/inferno/&quot;&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=&quot;http://www.vitanuova.com/inferno/man/1/cpu.html&quot;&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&#39;ll need to set up &lt;a href=&quot;http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os.html&quot;&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=&quot;http://www.vitanuova.com/inferno/man/8/svc.html&quot;&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=&quot;http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html&quot;&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&#39;s one of the few applications that doesn&#39;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&#39;s fairly slow over low bandwidth connections. For local connections it&#39;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&#39;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=&quot;http://www.vitanuova.com/inferno/man/4/acme.html&quot;&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 &quot;Hello&quot;.&lt;/p&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&#39;ve written before about how &lt;a href=&quot;http://www.vitanuova.com/inferno/&quot;&gt;Inferno&lt;/a&gt; makes it easy to &lt;a href=&quot;http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html&quot;&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&#39;m using for Inferno is written by &lt;a href=&quot;http://www.ueber.net/who/mjl/inferno/&quot;&gt;mjl&lt;/a&gt;. A large number of useful Inferno and Plan 9 utilities with source is available at &lt;a href=&quot;https://bitbucket.org/mjl/&quot;&gt;mjl&#39;s bitbucket repository&lt;/a&gt;. The one that provides IRC capability is &lt;a href=&quot;https://bitbucket.org/mjl/ircfs&quot;&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&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 &#39;Inferno&#39;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cd ircfs
% ROOT=/
% SYSHOST=Inferno
% mk install
cd module ; mk install
mk: &#39;install&#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: &#39;install&#39; is up to date
cd lib ; mk install
mk: &#39;install&#39; is up to date
cd man ; mk install
mk: &#39;install&#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&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&#39;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&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;p&gt;&lt;a href=&#39;http://bluishcoder.co.nz/images/wmirc1.png&#39;&gt;&lt;img src=&#39;http://bluishcoder.co.nz/images/wmirc1.png&#39; width=&#39;160&#39; alt=&#39;Image of wm/irc running&#39; title=&#39;Image of wm/irc running&#39;&gt;&lt;/a&gt;&lt;/p&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&#39;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&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&#39;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&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&#39;ve been away. This allows other users to leave me messages when I&#39;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=&quot;http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os.html&quot;&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&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&#39;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&#39;s a good example of mapping an existing protocol onto Inferno&#39;s &quot;everything is a file&quot; metaphor and making use of the tools to share resources. One use of this is having Inferno on other devices, &lt;a href=&quot;http://bluishcoder.co.nz/2012/06/11/building-inferno-os-for-android-phones.html&quot;&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>
 
 <entry>
   <title>Authentication and Encryption in Inferno OS</title>
   <link href="http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os.html"/>
   <updated>2012-12-18T20:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2012/12/18/authentication-and-encryption-in-inferno-os</id>
   <content type="html">&lt;p&gt;In my post about &lt;a href=&quot;http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html&quot;&gt;sharing resources in Inferno&lt;/a&gt; I used the &lt;code&gt;-A&lt;/code&gt; command line switch to commands to disable authentication. This allowed anyone to make connections and the data was passed across them unencrypted. This post explains how to set up an Inferno system to use authentication and to encrypt connections.&lt;/p&gt;

&lt;h2&gt;Signing Server&lt;/h2&gt;

&lt;p&gt;For authentication to work each machine that wishes to communicate securely must have a certificate signed by a common signing authority. That signing authority should be a separate machine with the sole task of running the signing processes.&lt;/p&gt;

&lt;p&gt;The signing server needs to have a public and private key used for signing certificates. To generate these keys run the command &lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/createsignerkey.html&quot;&gt;auth/createsignerkey&lt;/a&gt; from within the Inferno shell. The command takes a &lt;code&gt;name&lt;/code&gt; argument which is the name that will appear as the signer name in the certificates generated by the server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; auth/createsignerkey example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This command creates a &lt;code&gt;/keydb/signerkey&lt;/code&gt; file containing the keys. It&#39;s important to note that if this file is regenerated then any existing certificates issued by the server will be invalidated as the private key will have been lost. Keep this file safe!&lt;/p&gt;

&lt;p&gt;The act of authentication involves checking that the signing server and the user know a shared secret. The secrets are kept in the &lt;code&gt;/keydb/keys&lt;/code&gt; file. The file, which starts off empty, is protected by a password. Run the &lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/svc.html&quot;&gt;svc/auth&lt;/a&gt; program to start the services which manage this file. You will need to provide the password, or create one if none exists:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; svc/auth
Key: ...enter password/passphrase...
Confirm key: ...confirm password/passphrase...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each user to be authenticated must be set up on the signer by running the &lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/changelogin.html&quot;&gt;auth/changelogin&lt;/a&gt; command. This prompts for a password and an expiry date for the user. The expiry date is used as the maximum valid date for the certificates created for that user. At least one user must exist. Create a user on the signer for the current user on the signing machine (This might be &lt;code&gt;inferno&lt;/code&gt; or your host username, depending on your setup). You need to run &lt;code&gt;auth/changelogin&lt;/code&gt; for each remote or local user to be authenticated. That user can then run &lt;a href=&quot;http://www.vitanuova.com/inferno/man/1/passwd.html&quot;&gt;passwd&lt;/a&gt; command  at a later time to change the password.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; auth/changelogin myuser
new account
secret: ...enter password/passphrase... 
confirm: ...confirm password/passphrase...
expires [DDMMYYYY/permanent, return = 17122013]: ...enter expiry date or confirm default...
change written
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Obtaining a client certificate&lt;/h2&gt;

&lt;p&gt;A client of authenticated Inferno services needs to have a certificate obtained from the signing server. The request for this certificate is done using &lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/getauthinfo.html&quot;&gt;getauthinfo&lt;/a&gt;.  There is a also a &lt;code&gt;wm/getauthinfo&lt;/code&gt; variant that uses the Inferno GUI to prompt for required data. Other that that it is functionally the same as &lt;code&gt;getauthinfo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;keyname&lt;/code&gt; argument to &lt;code&gt;getauthinfo&lt;/code&gt; should either be &lt;code&gt;default&lt;/code&gt; or of the form &lt;code&gt;net!example.com&lt;/code&gt; where &#39;example.com&#39; is the hostname of the server with the resources being accessed. This must exactly match the name given to &lt;code&gt;bind&lt;/code&gt; or &lt;code&gt;mount&lt;/code&gt; when accessing the service. This is how those commands know to find the certificate file. The &lt;code&gt;default&lt;/code&gt; keyname is used by file servers as the default certificate file for incoming connections.&lt;/p&gt;

&lt;p&gt;When running &lt;code&gt;getauthinfo&lt;/code&gt; you are prompted for the signing server to be used, the username on the signing server that you wish to get the certificate for, a password for that username (which was created with &lt;code&gt;auth/changelogin&lt;/code&gt; previously, and whether you want to save the certificates in a file. If you answer &lt;code&gt;yes&lt;/code&gt; to &#39;save in file?&#39; then an actual physical file is created in the users &lt;code&gt;/usr/username/keyring&lt;/code&gt; directory. If &#39;no&#39; is answered then a fileserver is started on the client which serves a secure temporary file bound over the name in the given directory. This is removed when the file is unbound or Inferno is stopped.&lt;/p&gt;

&lt;p&gt;For the following example I create a &lt;code&gt;default&lt;/code&gt; file on a new server so it can act as a file server to remote clients. I&#39;m using &lt;code&gt;file.example.com&lt;/code&gt; as the hostname for this file server and example.com as the hostname for the signing server - replace this with the actual servers name. In these examples I assume that &lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/cs.html&quot;&gt;ndb/cs&lt;/a&gt; has been run to provide network services:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; getauthinfo default
use signer [$SIGNER]: example.com
remote user name [myuser]: ...enter username...
password: ...enter a password....
save in file [yes]: yes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On a client machine that wants to access resources on the file server run &lt;code&gt;getauthinfo&lt;/code&gt;, but using the &lt;code&gt;net!hostname&lt;/code&gt; form of the keyname, so &lt;code&gt;bind&lt;/code&gt; and &lt;code&gt;mount&lt;/code&gt; can find it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; getauthinfo net!file.example.com
use signer [$SIGNER]: example.com
remote user name [myuser]: ...enter username...
password: ...enter password for user...
save in file [yes]: yes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The request for certificates only needs to be done once, assuming &#39;save in file?&#39; was set to &#39;yes&#39;. The certificate information is valid until the expiry date set for the user.&lt;/p&gt;

&lt;h2&gt;Initiating secure connections&lt;/h2&gt;

&lt;p&gt;Both server and client can now connect securely now that they have certificates provided by the common signing server. An example from my &lt;a href=&quot;http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html&quot;&gt;previous post on sharing resources&lt;/a&gt; was sharing a directory. On the file server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; listen &#39;tcp!*!8000&#39; { export &#39;/usr/myuser&#39; &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This no longer has the &lt;code&gt;-A&lt;/code&gt; switch to disable authentication. To connect from the client:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mount &#39;tcp!file.example.com!8000&#39; /mnt/remote
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This command will actually fail with a message saying it couldn&#39;t find &#39;keyring/default&#39; if we haven&#39;t generated a default certificate. This is because our connection string includes a port and our &lt;code&gt;getauthinfo&lt;/code&gt; previously did not. Our &lt;code&gt;getauthinfo&lt;/code&gt; used &#39;net!file.example.com&#39; but we&#39;re connecting to &#39;net!file.example.com!8000&#39;. The default for &lt;code&gt;mount&lt;/code&gt; is to look for a file with the name exactly as specified with the host portion of the connection string and falling back to &#39;default&#39;.&lt;/p&gt;

&lt;p&gt;We can solve this by generating a &lt;code&gt;default&lt;/code&gt; file with &lt;code&gt;getauthinfo&lt;/code&gt;, or one for &lt;code&gt;net!file.example.com!8000&lt;/code&gt; which includes the port, or specifying the exact file on the &lt;code&gt;mount&lt;/code&gt; command line by using the &lt;code&gt;-k&lt;/code&gt; switch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mount -k &#39;net!file.example.com&#39; &#39;tcp!file.example.com!8000&#39; /mnt/remote
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These &lt;code&gt;mount examples&lt;/code&gt; will authenticate using the certificates but will not encrypt the session. To encrypt as well as authenticate use the &lt;code&gt;-C&lt;/code&gt; switch to &lt;code&gt;mount&lt;/code&gt; to set the hashing and encryption algorithm to use. See &lt;a href=&quot;http://www.vitanuova.com/inferno/man/3/ssl.html&quot;&gt;the ssl documentation&lt;/a&gt; for the supported algorithms. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mount -C sha1/rc4_256 &#39;tcp!file.example.com!8000&#39; /mnt/remote
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All the examples in my previous post can now be done with authenticated and encrypted sessions.&lt;/p&gt;

&lt;h2&gt;Conclusion and additional notes&lt;/h2&gt;

&lt;p&gt;The examples in this post show explicitly passing the hostname of the signing server in places. The file &lt;code&gt;/lib/ndb/local&lt;/code&gt; contains information for default servers. Changing the &lt;code&gt;SIGNER&lt;/code&gt; key to the signing servers hostname will avoid the need of always specifying this information.&lt;/p&gt;

&lt;p&gt;The signing server should have the sole task of running &lt;code&gt;svc/auth&lt;/code&gt;. It shouldn&#39;t be used for other tasks. Doing so results in issues where parts of &lt;code&gt;svc/auth&lt;/code&gt; exit when a client fails to authenticate resulting in the signing server no longer handling authentication. This is briefly warned about in &lt;a href=&quot;http://www.vitanuova.com/inferno/man/4/keyfs.html&quot;&gt;svc/keyfs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Keyfs should be started only on the machine acting as authentication server (signer), before a listener is started for signer(8). Note that signer and keyfs must share the name space. Furthermore, no other application except the console should see that name space.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://article.gmane.org/gmane.os.inferno.general/5550&quot;&gt;This mailing list post&lt;/a&gt; writes more about this. This is why I use a separate file server to export the path in the &lt;code&gt;listen&lt;/code&gt; statement in the examples here.&lt;/p&gt;

&lt;p&gt;The following sources have additional information and examples on using authentication and encryption in Inferno. In particular the &lt;code&gt;man&lt;/code&gt; pages for the commands have a lot of detail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/inferno/4th_edition/release_notes/install&quot;&gt;Installing the Inferno Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://debu.gs/entries/inferno-part-2-let-s-make-a-cluster&quot;&gt;Inferno Part 2: Let&#39;s Make a Cluster!&lt;/a&gt; by Peter Elmore.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/4/keysrv.html&quot;&gt;keysrv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/1/passwd.html&quot;&gt;auth/passwd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/4/keyfs.html&quot;&gt;keyfs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/signer.html&quot;&gt;signer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/svc.html&quot;&gt;svc/auth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/changelogin.html&quot;&gt;auth/changelogin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/8/getauthinfo.html&quot;&gt;getauthinfo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/man/4/keyfs.html&quot;&gt;svc/keyfs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Sharing computer and phone resources using Inferno OS</title>
   <link href="http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os.html"/>
   <updated>2012-11-07T01:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2012/11/07/sharing-computer-and-phone-resources-using-inferno-os</id>
   <content type="html">&lt;p&gt;I posted previously about running the &lt;a href=&quot;http://www.vitanuova.com/inferno/&quot;&gt;Inferno operating system&lt;/a&gt; on an &lt;a href=&quot;http://bluishcoder.co.nz/2012/06/11/building-inferno-os-for-android-phones.html&quot;&gt;Android phone&lt;/a&gt;. Inferno on a phone device interests me because of the approaches it takes on distributing resources across machines. By having such a system on multiple machines and devices it should be possible to use features of the phone on a desktop system (like SMS messaging, copying photos back and forth, etc) or use features of servers on the phone (cloud file storage for example).&lt;/p&gt;

&lt;p&gt;In this post I&#39;ll go over some simple examples of how to share resources using Inferno on a desktop machine and a remote server. I&#39;ll then show how an Inferno based phone can shares its resources. I use the hosted version of Inferno for these examples where Inferno runs as a user process under an existing operating system.&lt;/p&gt;

&lt;h2&gt;Building Inferno&lt;/h2&gt;

&lt;p&gt;To build Inferno under Linux you need to obtain the &lt;a href=&quot;http://www.vitanuova.com/dist/4e/inferno-20100120.tgz&quot;&gt;inferno-20100120.tgz&lt;/a&gt; file from the &lt;a href=&quot;http://www.vitanuova.com/inferno/downloads.html&quot;&gt;Inferno download page&lt;/a&gt;. This file contains a snapshot of the mercurial based source code repository and the binary font files used by the system. Once unpacked it needs to be updated to the latest source code version using mercurial commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ wget http://www.vitanuova.com/dist/4e/inferno-20100120.tgz
$ tar zxvf inferno-20100120.tgz
$ cd inferno
$ hg pull -u
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once the update is complete you will need to edit the &lt;code&gt;mkconfig&lt;/code&gt; file so that the following settings are changed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ROOT=/root/of/the/inferno/directory
SYSHOST=Linux
OBJTYPE=386
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ensure that &lt;code&gt;ROOT&lt;/code&gt; matches the directory location where the Inferno source code was unpacked. To build, set your PATH to the &lt;code&gt;Linux/386/bin&lt;/code&gt; subdirectory of the unpacked Inferno source and run the following commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export PATH=$PATH:~/src/inferno/Linux/386/bin
$ ./makemk.sh
$ mk nuke
$ mk install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The result is an &lt;code&gt;emu&lt;/code&gt; executable living in &lt;code&gt;Linux/386/bin&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Running Inferno&lt;/h2&gt;

&lt;p&gt;You can run Inferno and interact directly with a shell using &lt;code&gt;emu&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emu
; ls
...file listing...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is how I run Inferno on a headless server. On a machine with a display you can run a GUI:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emu -g1024x768
; wm/wm
...window system appears...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;-g&lt;/code&gt; command line option sets the size of the Inferno OS host window.&lt;/p&gt;

&lt;h2&gt;Namespaces&lt;/h2&gt;

&lt;p&gt;Inferno has a concept  called a &lt;code&gt;namespace&lt;/code&gt; which is a hierarchical collection of files or resources. Every process running in Inferno has its own local namespace. By modifying this namespace for each process you can grant or deny access to particular resources.&lt;/p&gt;

&lt;p&gt;Some commands that manipulate the namespace are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bind&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unmount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;export&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;These commands will be used in the examples following to show how to share and access resources from local and remote machines.&lt;/p&gt;

&lt;h2&gt;Sharing directories and files&lt;/h2&gt;

&lt;p&gt;Bind attaches, moves or hides local resources. The simplest case is binding an existing directory to a new location. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mkdir /tmp/myappl
; bind /appl /tmp/myappl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes the directory &lt;code&gt;/appl&lt;/code&gt;, which contains the source for some of the Inferno OS commands, to the location &lt;code&gt;/tmp/myappl&lt;/code&gt;. the current shell and all its child processes can see the /tmp/myappl directory. Processes that aren&#39;t children of the current shell cannot.&lt;/p&gt;

&lt;p&gt;Binding over an existing directory hides that directory until it is unbound (using &lt;code&gt;unmount&lt;/code&gt;). It&#39;s possible to bind over an existing directory such that the source directory is overlaid with the existing directory. You can choose whether files in the source directory or the destination directory have precedence if there are duplicate names. This is known as a union filesystem.&lt;/p&gt;

&lt;p&gt;An example of union filesystem usage is replacing the PATH environment variables in other operating systems. The &lt;code&gt;/dis&lt;/code&gt; directory on Inferno holds the executable Inferno OS commands. Instead of maintaining PATH environment variables for users to manage order of lookup for locally built commands and global OS commands you instead manage it via union directories using &lt;code&gt;bind&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If there is a directory in the user&#39;s home directory called &lt;code&gt;dis&lt;/code&gt;, you can allow commands located there to be looked up first by doing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; bind -b /usr/myname/dis /dis
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;if you want files in the global &lt;code&gt;dis&lt;/code&gt; directory to have precedence:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; bind -a /usr/myname/dis /dis
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can stack as many directories as desired. The &lt;code&gt;-a&lt;/code&gt; command line argument means add &#39;after&#39; the union directory. the &lt;code&gt;-b&lt;/code&gt; command line argument means add &#39;before&#39; the union directory.&lt;/p&gt;

&lt;h2&gt;Binding the host filesystem&lt;/h2&gt;

&lt;p&gt;When running Inferno as a user process on an existing host operating system you can bind to directories that exist on the host. The  special &lt;a href=&quot;http://man.cat-v.org/plan_9/3/intro&quot;&gt;kernel device path&lt;/a&gt;, &#39;#U&#39;, is for the host file system:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; bind &#39;#U*&#39; /tmp/z
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the directory &lt;code&gt;/tmp/z&lt;/code&gt; is mapped to the root of the host. You can map any host path, not just the root:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; bind &#39;#U*/home&#39; /tmp/z
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can be used to mount a users host filesystem home directory to be used as their Inferno home directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; bind &#39;#U*/home&#39; /usr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I start Inferno with the home directory shared and logged into the Inferno system as my host username using a shell script which runs the equivalent of:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export PATH=$PATH:/src/inferno/Linux/386/bin
$ export EMU=&quot;-r/home/$USER/src/inferno -c1 -g1920x1008&quot;
$ exec emu $* /dis/sh.dis -a -c &quot;bind &#39;#U*/home&#39; /usr; wm/wm wm/logon -u $USER&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For this to work you&#39;ll need to ensure you have the directories and files Inferno expects to find in the home directory. The files from the Inferno &lt;code&gt;/usr/inferno&lt;/code&gt; directory can be copied for this purpose.&lt;/p&gt;

&lt;h2&gt;Accessing remote files&lt;/h2&gt;

&lt;p&gt;Note: One important point to note in the following examples is that the &lt;code&gt;-A&lt;/code&gt; switch used in both the &lt;code&gt;listen&lt;/code&gt; and &lt;code&gt;mount&lt;/code&gt; commands &lt;em&gt;disables authentication&lt;/em&gt;. All the &lt;em&gt;data is being sent unencrypted&lt;/em&gt; and no login information was used to connect. Don&#39;t do this for real systems, I&#39;m only doing this to show the basic commands. It&#39;s possible and recommended to set up &lt;a href=&quot;http://debu.gs/entries/inferno-part-2-let-s-make-a-cluster&quot;&gt;authentication and encryption&lt;/a&gt; for real world usage. Once done this can replace the use of sftp on Inferno systems. Just export and bind the filesystems needed and all access is authenticated and all data encrypted.&lt;/p&gt;

&lt;p&gt;To access a resource on another machine (or another instance of hosted Inferno OS on the same machine) you can run the &lt;code&gt;listen&lt;/code&gt; command on the remote machine, exporting the namespace you want the client machine to be able to bind:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emu
; ndb/cs
; ndb/dns
; listen -A &#39;tcp!*!8000&#39; { export &#39;#U*/home/myuser&#39; &amp;amp; }
;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;ndb/cs&lt;/code&gt; and &lt;code&gt;ndb/dns&lt;/code&gt; commands start the network services used for DNS lookup and other features. the &lt;code&gt;listen&lt;/code&gt; command starts a listener on port 8000 exporting the &lt;code&gt;myuser&lt;/code&gt; home directory from the host filesystem. I picked &lt;code&gt;8000&lt;/code&gt; as an arbitary port number - any one is fine. A client machine can now connect to this using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emu
; ndb/cs
; ndb/dns
; mkdir /tmp/myuser
; mount -A &#39;tcp!remote.example.com!8000&#39; /tmp/myuser
; cd /tmp/myuser
; ls
...remote file listing...
; unmount /tmp/myuser
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Replace &#39;remote.example.com&#39; with the IP address or domain name of the remote machine. The mounted directory works like a local directory from the point of view of the client. You can get directory listings, copy files, edit files, etc.&lt;/p&gt;

&lt;h2&gt;Accessing remote resources&lt;/h2&gt;

&lt;p&gt;This accessing of remote resources isn&#39;t just limited to files. You can export other kernel devices. You can remotely list and debug running processes on a remote machine by exporting and mounting &lt;code&gt;/prog&lt;/code&gt;. On the remote machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; listen -A &#39;tcp!*!8000&#39; { export /prog &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On the client machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mkdir /tmp/debug
; mount -A &#39;tcp!remote.example.com!8000&#39; /tmp/debug
; ls /tmp/debug
...list of processes on remote machine...
; unmount /tmp/debug
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Accessing remote networks&lt;/h2&gt;

&lt;p&gt;Another interesting example is mounting a remote machines &lt;code&gt;/net&lt;/code&gt; directory over the top of the existing clients &lt;code&gt;/net&lt;/code&gt; directory. The result of this is all network access made via the shell and its children will use the remote machine&#39;s network. This effectively creates a network tunnel that is encrypted and authenticated (if you don&#39;t use the &lt;code&gt;-A&lt;/code&gt; switch and setup the authentication system).&lt;/p&gt;

&lt;p&gt;To demonstrate this lets assume the client machine can&#39;t accept incoming connections due to NAT. The remote machine however is unrestricted. On the remote machine run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; listen -A &#39;tcp!*!8000&#39; { export /net &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On the client machine we connect outwards as before - outbound connections aren&#39;t restricted:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; webgrab http://automation.whatismyip.com/n09230945.asp
; cat n09230945.asp
...public facing ip address of client machine...
; mount -A &#39;tcp!remote.example.com!8000&#39; /net
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This &lt;code&gt;mount&lt;/code&gt; usage binds the remote &lt;code&gt;/net&lt;/code&gt; onto our own &lt;code&gt;/net&lt;/code&gt;. Any future network requests from this shell on the client machine will come from the remote:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; webgrab http://automation.whatismyip.com/n09230945.asp
; cat n09230945.asp
...ip address of remote machine...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can even expose resources on the client machine. The following is run on the client:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; listen -A &#39;tcp!*!8001&#39; { export / &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On a third machine, that has no access to the client at all, but can access the remote machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; mkdir /tmp/client
; mount -A &#39;tcp!remote.example.com!8001&#39; /tmp/client
; ls /tmp/client
...client file listing...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&#39;ll note that we&#39;re connecting to port 8001 on the remote machine. This is where the listen is attached to due to us mapping the remotes &lt;code&gt;/net&lt;/code&gt; directory on the client. But it&#39;s the client&#39;s root directory that was exported so that&#39;s what the third machine gets access to. No incoming connections are made to the client itself.&lt;/p&gt;

&lt;h2&gt;Sharing phone resources&lt;/h2&gt;

&lt;p&gt;For this example you&#39;ll need to have Inferno running on an Android phone. This can be done by installing &lt;a href=&quot;https://bitbucket.org/floren/inferno/wiki/Home&quot;&gt;Hellaphone&lt;/a&gt; or following my instructions on &lt;a href=&quot;http://bluishcoder.co.nz/2012/06/11/building-inferno-os-for-android-phones.html&quot;&gt;building and installing Inferno on a Nexus S&lt;/a&gt; using Mozilla&#39;s Boot to Gecko as a base.&lt;/p&gt;

&lt;p&gt;SMS messages can be sent on the phone by writing to the &#39;/phone/sms&#39; file. The following would send a simple text message to number +6412345678 (an invalid New Zealand number):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; echo send 6412345678 &#39;hello&#39; &amp;gt;/phone/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By exporting &lt;code&gt;/phone&lt;/code&gt; and mounting it on a desktop system we can control the sending of SMS messages from there. On the phone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; ndb/cs
; ndb/dns
; listen -A &#39;tcp!*!8000&#39; { export /phone &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On the desktop machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; ndb/cs
; ndb/dns
; mkdir /tmp/phone
; mount -A &#39;tcp!ip.address.of.phone!8000&#39; /tmp/phone
; echo send 6412345678 &#39;hello&#39; &amp;gt;/tmp/phone/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#39;s also possible to detect ringing, answer calls, read received SMS messages, etc.&lt;/p&gt;

&lt;p&gt;Unfortunately things are a bit more complex in the real world. My phone carrier doesn&#39;t allow inbound connections to the phone. They also seem to prevent outbound connections on some ports. Highly annoying. To fix this I installed OpenSSH on the phone using &lt;a href=&quot;http://dan.drown.org/android/&quot;&gt;opkg&lt;/a&gt;. Using OpenSSH I created a tunnel to my remote server which I could then map &lt;code&gt;/net&lt;/code&gt; in a similar manner to what I&#39;ve described previously.&lt;/p&gt;

&lt;p&gt;On my remote server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emu
; ndb/cs
; ndb/dns
; listen -A &#39;tcp!*!8000&#39; { export /net &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On the phone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# ssh -N myuser@remote.example.com -L 8000:127.0.0.1:8000 &amp;amp;
# emu-g
; ndb/cs
; ndb/dns
; mount -A &#39;tcp!127.0.0.1!8000&#39; /net
; listen -A &#39;tcp!*!8001&#39; { export /phone &amp;amp; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On my desktop:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;; ndb/cs
; ndb/dns
; mount -A &#39;tcp!remote.example.com!8001&#39; /tmp/phone
; echo send 6412345678 &#39;hello&#39; &amp;gt;/tmp/phone/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The routing through the remote server is the same as my previous example. There&#39;s probably a way of avoiding the OpenSSH tunnelling by using another port but I didn&#39;t spend time investigating exactly what the carrier was doing.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Inferno makes it quite easy to share resources amongst devices. The idea of having a phone which can attach to other machines to access files and export phone functionality to other machines to more conveniently write SMS messages and emails appeals to me. It&#39;ll be interesting to see how far this can be pushed and what ideas people come up with in this area. Hopefully more development will go into Inferno on the phone and some of these ideas can be explored.&lt;/p&gt;

&lt;p&gt;Remember that the examples above that used the &lt;code&gt;-A&lt;/code&gt; switch to &lt;code&gt;mount&lt;/code&gt; and &lt;code&gt;listen&lt;/code&gt; used unencrypted and unauthenticated sessions. This is useful for quick testing but for actual usage &lt;code&gt;-A&lt;/code&gt; should be avoided. Setting up authentication is described at &lt;a href=&quot;http://debu.gs/entries/inferno-part-2-let-s-make-a-cluster&quot;&gt;Pete Elmore&#39;s post on clusters&lt;/a&gt;. The &lt;a href=&quot;http://doc.cat-v.org/inferno/4th_edition/release_notes/install&quot;&gt;4th edition release notes&lt;/a&gt; also has information on this.&lt;/p&gt;

&lt;p&gt;Other useful Inferno resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://debu.gs/tags/inferno&quot;&gt;Peter Elmore&#39;s Inferno Posts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ueber.net/who/mjl/inferno/getting-started.html&quot;&gt;Getting Started with Inferno&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bitbucket.org/mjl/&quot;&gt;Useful Limbo programs&lt;/a&gt;, including an IRC file system and client.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://media.defcon.org/dc-20/presentations/Floren/DEFCON-20-Floren-Hellaphone.pdf&quot;&gt;Hellaphone DEFCON 20 slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://research.swtch.com/acme&quot;&gt;A Tour of ACME&lt;/a&gt;. A screencast of using the ACME editor used in Inferno and Plan 9 (and other systems).&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Building Inferno OS for Android Phones</title>
   <link href="http://bluishcoder.co.nz/2012/06/11/building-inferno-os-for-android-phones.html"/>
   <updated>2012-06-11T12:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2012/06/11/building-inferno-os-for-android-phones</id>
   <content type="html">&lt;p&gt;Updated 2014-12-29 - I&#39;ve moved the patch files to github and provided &lt;a href=&quot;https://github.com/doublec/inferno/blob/hellaphone/README.md&quot;&gt;updated build instructions&lt;/a&gt; there. Other than those build instruction updates most of this post is still valid.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.vitanuova.com/inferno/&quot;&gt;Inferno&lt;/a&gt; is a small operating system that can be built to run on Host operating systems as a user process or natively on bare hardware. Inferno uses ideas from the &lt;a href=&quot;http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs&quot;&gt;Plan 9&lt;/a&gt; operating system and has some interesting features. These include the Plan 9 system of representing resources as files using the &lt;a href=&quot;http://en.wikipedia.org/wiki/9P&quot;&gt;9P&lt;/a&gt; protocol.&lt;/p&gt;

&lt;p&gt;Last year source and binaries were released to &lt;a href=&quot;https://bitbucket.org/floren/inferno/wiki/Home&quot;&gt;run the hosted version of Inferno on an Android phone&lt;/a&gt;. A  &lt;a href=&quot;http://www.youtube.com/watch?v=dF_-jQc53jw&quot;&gt;YouTube video of it running is here&lt;/a&gt;. The binaries and installation are quite tightly tied to a specific android revision. It involves replacing the init.rc file on the phone to enable dual booting of Android or Inferno. Replacing this file in versions of Android different to that which the replacement was based on won&#39;t work. For example the version used is from a Gingerbread device and won&#39;t work on an Ice Cream Sandwich device. I set about building from source so I could run Inferno on my Nexus S alongside &lt;a href=&quot;http://bluishcoder.co.nz/2012/03/20/building-and-running-b2g-on-nexus-s.html&quot;&gt;Boot To Gecko&lt;/a&gt;. I used B2G as the base instead of Android as B2G is easier to build and it&#39;s interesting to compare the two operating system approaches on the phone.&lt;/p&gt;

&lt;p&gt;Warning: These steps flash data to your phone and may result in having to re-flash the original OS. Make backups first! B2G and Inferno are experimental operating systems running on the phone. They may not make for a great Phone experience at this early stage in their development.&lt;/p&gt;

&lt;p&gt;This first step is to build the B2G system. This is pretty well covered on the &lt;a href=&quot;https://developer.mozilla.org/en/Mozilla/Boot_to_Gecko/Building_and_installing_Boot_to_Gecko&quot;&gt;Mozilla Developer Network&lt;/a&gt;. Basic steps to build for the Nexus S (with the phone connected to the PC):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/mozilla-b2g/B2G
$ cd B2G
$ ./config.sh nexus-s
$ ./build.sh
$ export B2G_ROOT=`pwd`
$ cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to flash B2G to your phone you can run the following command with the phone connected (this will delete everything on your phone and is not needed if you want to just try Inferno on your rooted Android phone):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd B2G
$ ./flash.sh &amp;amp;&amp;amp; ./flash.sh gaia
$ cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&#39;ll use the B2G tools to build Inferno and &#39;adb&#39; to copy it to the device and start it.&lt;/p&gt;

&lt;p&gt;The most recent port of Inferno that runs on Android is available in a &lt;a href=&quot;https://bitbucket.org/floren/inferno&quot;&gt;mercurial repository hosted on bitbucket&lt;/a&gt;. This should be cloned and the PATH modified to use the Linux version of the Inferno build tools which we also need to build. Unfortunately the repository modifications to get Android builds working has broken Linux builds slightly so the first build attempt will fail and then we manually build the features we need. The location of the build needs to be in &lt;code&gt;/data/inferno&lt;/code&gt; to match the directory it will be in on the device.&lt;/p&gt;

&lt;p&gt;To build the Linux tools after cloning, edit the &lt;code&gt;mkconfig&lt;/code&gt; file to have the following settings (change the existing ones set to Android/ARM):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SYSHOST=Linux
OBJTYPE=386
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we build:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd /data
$ hg clone https://bitbucket.org/floren/inferno
$ cd inferno
$ vim mkconfig    # Change SYSHOST and OBJTYPE as above
$ ./makemk.sh
$ export PATH=$PATH:/data/inferno/Linux/386/bin
$ mk nuke
$ mk install      # This will error out, ignore the error and continue
$ cd lib9 &amp;amp;&amp;amp; mk install &amp;amp;&amp;amp; cd ..
$ cd libmath &amp;amp;&amp;amp; mk install &amp;amp;&amp;amp; cd ..
$ cd utils/iyacc &amp;amp;&amp;amp; mk install &amp;amp;&amp;amp; cd ../..
$ cd limbo &amp;amp;&amp;amp; mk install &amp;amp;&amp;amp; cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that the Linux tools are built we can build the Android version. This requires an ARM C compiler compatible with Android. I use the one built during the B2G build process which is accessed via a wrapper shell script called &lt;a href=&quot;http://plausible.org/andy/agcc&quot;&gt;agcc&lt;/a&gt;. This &lt;code&gt;agcc&lt;/code&gt; script is based on using the Android SDK. A patch to have this work with the B2G toolset is &lt;a href=&quot;http://bluishcoder.co.nz/inferno/agcc.patch&quot;&gt;available here&lt;/a&gt;. This assumes B2G&#39;s &lt;code&gt;gcc&lt;/code&gt; is in your PATH. The example below sets this and you&#39;ll need to change it to where you cloned B2G. You should also adjust the instructions to put &lt;code&gt;agcc&lt;/code&gt; somewhere in your path. I use a &lt;code&gt;bin&lt;/code&gt; subdirectory off my home directory.&lt;/p&gt;

&lt;p&gt;I was unable to get the prebuilt audio binaries working that are provided with the Inferno for Android port. There were also some changes I needed to do to &lt;a href=&quot;http://article.gmane.org/gmane.os.inferno.general/5490&quot;&gt;get it working on ICS&lt;/a&gt;. Patches to disable the audio, compile on ICS, and get events working are in &lt;a href=&quot;http://bluishcoder.co.nz/inferno/inferno.patch&quot;&gt;inferno.patch&lt;/a&gt; which is applied in the commands below.&lt;/p&gt;

&lt;p&gt;Edit the &lt;code&gt;mkconfig&lt;/code&gt; file to have the following settings (change the existing ones from Linux/386 that we set earlier):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SYSHOST=Android
OBJTYPE=arm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install &lt;code&gt;agc&lt;/code&gt; modified to use B2G:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd ~/bin
$ curl http://plausible.org/andy/agcc &amp;gt;agcc
$ chmod +x agcc
$ curl http://www.bluishcoder.co.nz/inferno/agcc.patch | patch -p0
$ export PATH=$PATH:$B2G_ROOT/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is an issue with building using the B2G toolchain regarding &lt;code&gt;stdlib.h&lt;/code&gt;. To prevent a compile error around the use of &lt;code&gt;wchar_t&lt;/code&gt; I modified &lt;code&gt;$B2G_ROOT/bionic/libc/include/stdlib.h&lt;/code&gt; line 167 to change &lt;code&gt;#if 1&lt;/code&gt; to &lt;code&gt;#ifndef INFERNO&lt;/code&gt; to prevent the &lt;code&gt;wchar_t&lt;/code&gt; usage of &lt;code&gt;mblen&lt;/code&gt; and friends from being used.&lt;/p&gt;

&lt;p&gt;Build Android Inferno:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd /data/inferno
$ vim mkconfig     # Make SYSHOST/OBJTYPE changes for Android
$ curl http://www.bluishcoder.co.nz/inferno/inferno.patch | patch -p1
$ vim $B2G_ROOT/bionic/libc/include/stdlib.h   # Change to line 167 described above
$ mk nuke
$ mk install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Inferno for the device is now built. I use a B2G device to test but it will run on a rooted Android phone as well. To install run the &lt;code&gt;parallel-push.sh&lt;/code&gt; script with the device connected. This copies everything to &lt;code&gt;/data/inferno&lt;/code&gt; on the phone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./parallel-push.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Booting the phone will still boot into the main OS (B2G or Android). Inferno can be manually run using &lt;code&gt;adb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ adb shell
# stop b2g     # &#39;stop zygote&#39; on Android
# cd /data/inferno/Android/arm/bin
# ./emu-g
;; wm/wm &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From the running &lt;code&gt;emu-g&lt;/code&gt; shell you can run any Inferno commands. The device interface to access phone functions is documented in &lt;a href=&quot;https://bitbucket.org/floren/inferno/src/75008e7031e1/README.android&quot;&gt;README.android&lt;/a&gt;. For example, to turn the phone on and enable GSM data on New Zealand&#39;s Vodafone network:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;;; echo on &amp;gt; /phone/ctl
;; echo net on gsm www.vodafone.net.nz &#39;&#39; &#39;&#39; &amp;gt; /phone/ctl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Photos of the main phone screen and tetris running on the phone are below:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://bluishcoder.co.nz/images/inferno1.jpg&quot;&gt;&lt;img src=&quot;http://bluishcoder.co.nz/images/inferno1_small.jpg&quot;&gt;&lt;/a&gt;
&lt;a href=&quot;http://bluishcoder.co.nz/images/inferno2.jpg&quot;&gt;&lt;img src=&quot;http://bluishcoder.co.nz/images/inferno2_small.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To switch from Inferno back to the main OS, kill the running &lt;code&gt;emu-g&lt;/code&gt; process and start &lt;code&gt;b2g&lt;/code&gt; or &lt;code&gt;zygote&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# kill 1234    # where 1234 = process id of emu-g
# start b2g    # &#39;start zygote&#39; for Android
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are a bunch of issues with the existing port unfortunately. The &#39;hardware&#39; capacitive keys don&#39;t work. I work around this by tweaking &lt;code&gt;/etc/buttonserver.cfg&lt;/code&gt; to use the down volume key to bring up the keyboard so I can at least type. The touch screen seems to be out by a few pixels. Sound doesn&#39;t work due to disabling it in my patch applied above to get things compiling. I did test receiving and making a call though using direct device access and that worked.&lt;/p&gt;

&lt;p&gt;Inferno is an interesting operating system and with its distributed features and Limbo programming language there might be some different approaches that could be taken to integrate phones with desktop devices to share computing resources. The existing port has some bitrot and the steps to build, as can be seen above, are quite manual but it can be streamlined. Dual booting B2G (or Android) with Inferno shouldn&#39;t be too difficult. It&#39;d be nice to see continued work on Inferno for Android to experiment with distributed applications on mobile devices.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
