The Inferno Internet Explorer Plug-in

John Bates, Vita Nuova.
December 2000.

Introduction

This document provides an overview of the first (preliminary) release of Vita Nuova's Internet Explorer plug-in. The plug-in is designed to allow the controlled execution of compiled Limbo programs (Dis modules) within Microsoft Internet Explorer using a secure Inferno sandbox. Dis modules may be referenced from within a web page and are automatically fetched and executed from the Internet. A module interacts with a user through the web page. Unsigned (untrusted) modules are run in a namespace that provides them with no access to the network (local or remote), or access to any of the local devices. A richer namespace may be composed for signed (trusted) modules.

The plug-in enables a web page to utilise the full range of Inferno authentication and security mechanisms to provide mutual authentication, message authentication and message encryption when connecting to any kind of service on the Internet, not just to other web pages. A network conversation can be secured against modification alone or against both modification and snooping. To secure against modification, a secure MD5 hash or SHA hash can be appended to each message. To secure against snooping, encryption of the complete conversation can be performed using RC4, IDEA or DES with either DES chain block coding (DESCBC) or electronic code book (DESECB).

If you are not already familiar with Inferno and Limbo you can use the online manual pages at Vita Nuova's web site to provide some of the background. Printed and bound manuals which describe all of the function and system calls available to Dis modules and a collection of papers, including Dennis Ritchie's "Limbo Reference Manual", are also available from the same site.

The Inferno Internet Explorer plug-in allows a Limbo program to run inside a web page when displayed by Microsoft Internet Explorer 4 or 5. The plug-in executes Dis within a sandbox in the Inferno Dis virtual machine which provides the execution environment for all programs running under the Inferno Operating System. In this preliminary release, only unsigned modules are handled and so an application has no access to the network and no access to devices on the local machine. The filespace visible to a program run by the plugin is the contents of a read-only KFS filesystem combined with a writeable RAM filesystem for temporary storage. We are currently working on a the security issues and the consequent relaxation of these restrictions. The second release of the plug-in will allow network connections and controlled access to other devices with the introduction of signed Dis modules.

Plug-in applications are compiled into Dis bytecode and can either be interpreted by the Dis virtual machine or compiled on-the-fly into native machine code. The application can be developed and debugged on any system that currently runs Inferno (including Linux, Solaris, Plan 9, Windows or native Inferno systems and, now, also including Internet Explorer itself).

A web page references the Dis executable which is fetched on demand from the Internet and stored in Internet Explorer's cache. The next time the page is viewed, unless it has been purged, the file will be retrieved from the local cache. The plug-in contains several builtin modules, which provide a variety of functionality including: file access, basic I/O, namespace manipulation, formatted output, exception handling, basic character and string manipulation, basic graphics facilities, image and font handling, rectangular geometric operations, a complete Tk implementation based on Ousterhout's Tcl/Tk, elementary functions of applied mathematics, a floating point environment and authentication and security related operations. The entire plug-in including a minimal filesystem and the complete Inferno Dis virtual machine is contained in a download which occupies 719 Kbytes.

Examples

Click here to see an example of an Inferno plug-in running in an Internet Explorer web page. The example shows a ticker-tape display which is the output of the Limbo program ticker.b. The compiled program, ticker.dis (1462 bytes in size), is automatically downloaded from the web page and run in the Inferno sandbox. The next time you visit the web page, unless files in the browser cache have been deleted, the page and the Dis module will be picked up locally and so no downloading will occur.

Click here to see a more interactive module. This is a port to Limbo of the Eliza and psychotherapist classic. The module runs an interactive session with the user in a text window on the web page. A scroll bar enables the browsing of earlier discussion.

Writing a Module

To create a module that can be embedded in a web page you should follow the following sequence of steps:
Install the free Inferno download
You can fetch a free copy of Inferno for Nt, Linux, Plan 9 or Solaris from the Vita Nuova website. The download contains a complete development environment that can be used to edit, compile, debug and check your module before placing it in a web page.
Write the module in Limbo
Create your Limbo program using any editor and save it to a file with a .b suffix. The download contains many examples of Limbo programs, a set of manual pages that document the functions in each of the builtin modules, and some editing tools including the Acme development environment.
Compile the module
Use the Limbo compiler to compile your Limbo program to a portable Dis module. Dis modules conventionally have a .dis suffix.
Add an <OBJECT> tag to your web page
Refer to the Dis module with an OBJECT tag that you include in the HTML on your web page. The tag contains information that the browser can use to find and run the module.
Place the web page and Dis module on your web site
The Dis module should be placed on the web site so that it can be delivered by your web server when requested by a browser.
In this preliminary release the module will only run from Internet Explorer. We plan to announce soon a plug-in for Netscape navigator that will allow the same module to run, unaltered, from both popular browsers. More information anout the Limbo programming language and how to embed a Dis module in a web page are given later in this document.

Limbo

Plug-in modules are written in Limbo, a language that is instantly familiar to any C programmer. Limbo has the same expression syntax and flow control as C but in addition is strongly typed, provides automatic garbage collection, supports a restricted form of pointer and compiles into machine independent byte-code for execution on a virtual machine. Unlike C, Limbo is a concurrent programming language (and unlike Java, concurrency is built in to the language, applying the results of research done since the 1970s.)

A Limbo program is a set of one or more modules that communicate to perform a task. Programs are type-checked at compile time and further when modules are loaded.

Limbo has the numeric types byte (unsigned, 8bits), int (signed, 32 bits), big (signed, 64 bits) and real (IEEE long float, 64 bits) with the size and signedness the same on every virtual machine. Character constants are expressed as in C using single quotes and can include the same set of escapes such as `\n` but the characters are themselves Unicode and have type int. Limbo also provides a Unicode string type, arrays of arbitrary types, lists of arbitrary types, tuples, abstract data types (adts, which are like a C struct but may contain function members as well as data members), reference types and typed channels (chans) for passing objects between processes.

Statements and control flow in Limbo are similar to those in C. A statement is an expression followed by a semicolon, or a sequence of statements enclosed in braces. The similar control flow statements are:

if (expr) statement
if (expr) statement else statement
while (expr) statement
for (expr; expr; expr) statement
do statement while (expr) ;
return expr ;
exit ;
The exit statement terminates a process and frees its resources. There is also a case statement analogous to C's switch which also supports string and range tests. A break or continue followed by a label causes a break out of, or the next iteration of, the enclosing construct that is labeled with the same label. Comments begin with # and extend to the end of the line. There is no preprocessor, but an include statement can be used to include source code, usually module declaration files.

Limbo provides most of the C operators, but not ? : or the 'comma' (sequential execution) operator. Arrays and strings may be sliced, and passed around as first class types and strings may be concatenated with the + and += operators. The operator := combines the declaration of a variable and the assignment of a value to it. The type of the variable on the left of the := is given by the type of the expression on the right.

New processes are created with the spawn statement which creates a separate process by calling a specified function. The process has its own stack but shares memory with the process that spawned it. Synchronisation between processes is handled by channels. A channel may be passed as an argument to the spawned function and used to provide communication and synchronisation between the two processes. The operator <-= writes an expression to a channel; the operator =<- reads from a channel and assignes to a variable. Channels are unbuffered and so a writing process will block until another process reads from the same channel this provides convenient synchronisation.

A good introduction to Limbo programming can be found in Brian Kernighan's A Descent into Limbo on the Vita Nuova web site. A more complete treatment of the language is available in Dennis Ritchie's reference manual The Limbo Programming Language at the same location.

A module can be developed and tested using the free Inferno download available from the Vita Nuova website on Linux, Windows, Plan 9, FreeBSD and Solaris. The download contains the Limbo compiler and the source code for many Limbo modules ranging from familiar Unix utilities through to more complex applications such as the Charon web-browser. Indeed, it is possible (although not necessarily very useful) to run the Charon web browser as a module inside a plug-in window in an Internet Explorer web page!

Embedding Modules in a Web Page

Modules are written in Limbo and then compiled with the Limbo compiler to produce machine independent Dis bytecode. Modules can be run on any installation of Inferno, and from a web page without recompilation - the Dis module is completely portable between any of the Windows Nt, Linux, Solaris, Internet Explorer, Plan 9 or other Inferno platforms. To host a module in a web page, the HTML on the web page must contain at least the following components:
The ticker page contains the following <OBJECT> and <PARAM> tags:
<OBJECT
    classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
    codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
    width=500 height=80
>
<PARAM name="init" value="ticker.dis">
<PARAM name="file1" value="ticker.dis http://www.vitanuova.com/inferno/pi/ticker/ticker.dis">
</OBJECT>
The <OBJECT> tag contains a classid attribute that gives the class ID that is unique to the Inferno plug-in and width and height attributes for the size of the area (in pixels) on the web page that the plug-in will occupy. All three of these attributes are required. The Inferno Internet Explorer plug-in is always uniquely identified by the class ID: C0316421-4BE6-11d3-A893-004095E0A888

To ensure that the Inferno plug-in is installed an <OBJECT> tag should also contain a codebase attribute:

codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
The URL in the codebase attribute gives the location of a CAB file containing the plug-in. The codebase attribute can also contain version information.
codebase="http://www.vitanuova.com/plugin/ieplugin.cab#Version=1,0,0,1"
If the plug-in has not yet been installed, or if it has been installed but the installed version is earlier than the version specified in the codebase attribute the plug-in will be downloaded and installed from the given URL. If an <OBJECT> tag contains a codebase attribute in which all the version digits are minus one:
codebase="http://www.vitanuova.com/plugin/ieplugin.cab#Version=-1,-1,-1,-1"
the plug-in will be downloaded from the given URL if its release date is later than the installation date on the computer. If the plug-in has already been installed and the release date is the same as or earlier than the installation date, only an HTTP header transaction will occur. This technique insures that the latest version of the plug-in is installed, but at the cost and delay of an Internet access to date stamps each time the plug-in is used. If you omit the version information altogether, the browser simply checks for the presence of the plug-in.

In practice it is probably best to include the codebase attribute in each <OBJECT> tag without version information to ensure that the user has the plug-in, even if not necessarily the latest version.

Additionally, hspace and vspace attributes can be used to define a margin, in pixels, around the visible area and a title text string may be supplied that Internet Explorer will use to identify the space occupied by the browser when the cursor hovers above it:

<OBJECT
    classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
    codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
    width=500 height=80
    vspace=50 hspace=50
    title="Inferno Ticker"
>
<PARAM name="init" value="ticker.dis">
<PARAM name="file1" value="ticker.dis http://www.vitanuova.com/inferno/pi/ticker/ticker.dis">
</OBJECT>
In this example ticker.dis is executed by the plug-in once it has been downloaded from the Vita Nuova website and if the plug-in has not been installed it will be retrieved from the same web site.

How the Browser Initialises a Module

When the browser discovers the <OBJECT> tag in a web page it examines it to find a classid attribute. It uses the class ID to check the Windows registry to find the location of the plug-in in the Windows filesystem. If the plug-in has been installed it loads it and initialises it. If there is no corresponding entry in the registry for the class ID it uses the codebase attribute to download a CAB format file from the Internet. The CAB file contains the plug-in and instructions to the browser that enable it to install it. The browser will confirm that the user wishes to install the plug-in before following the instructions. Once installed, the plug-in is loaded and initialised. On initialisation, the plug-in invokes the Dis module emuinit.dis found in the plug-in installation directory:
...\Program Files\Vita Nuova\Inferno\Plug-in
In turn, this module constructs a namespace by opening the file plugin.kfs which contains an initial filesystem image and mounting it (read-only) at the root of the, initially empty, namespace. It then creates a small RAM filesystem and binds this over the top of the empty directory /usr/internet as writeable and creates a new subdirectory /usr/internet/tmp which it then binds over the top of the /tmp directory. The startup module changes directory to /usr/internet which will become the home directory of the downloaded plug-in module. As a result, files created by a plug-in module in its home directory or /tmp will appear in the RAM filesystem and files in the KFS filesystem will be readable but not writeable to the module.

The startup code then binds the Inferno server registry into /chan, the prog filesystem into /prog and the console devices and graphics draw device into /dev before calling sys->pctl(Sys->NODEVS, nil) to ensure that a plug-in module has no further access to devices. This basic namespace is the sandbox in which a plug-in Dis module will run.

Once the namespace has been constructed, the files named for downloading in the HTML file are requested from the plug-in and are placed in the home directory (/usr/internet). The plug-in recognises <PARAM> tags with the consecutive names: file1, file2, ... filen. The first word of the value attribute of these tags determines the name the file will be given, once downloaded. The rest of the value attribute string is a URL giving the Internet location of the file to download.

The <PARAM> tag with name init has a value string that determines the Dis module to invoke at startup. The first word in the string is assumed to be the name of a Dis module to invoke, the remainder of the string is passed to the module as an argument list. A web page is likely to contain at least one <PARAM> tag to name the Dis file that needs to be downloaded and executed. In the ticker example the following tags were required:

<PARAM name="init" value="ticker.dis">
<PARAM name="file1" value="ticker.dis http://www.vitanuova.com/inferno/pi/ticker/ticker.dis">
In that example, only one file was downloaded from the internet and the same file was executed by the virtual machine once the sandbox had been constructed by the plug-in.

Fetching Files

Most web pages that include a Dis module are likely to download at least one file from the Internet - the module to run. The web page containing the ticker module was an example of such a page, only a single file was downloaded - ticker.dis. A look at the source code for ticker.b shows that it accesses a font file, unicode.8.font:
FONTPATH : con "/fonts/pelm/unicode.8.font";
...
font := Font.open(disp, FONTPATH);
and loads two modules:
sys = load Sys Sys->PATH;
draw = load Draw Draw->PATH;
The font file is included in the plugin.kfs filesystem that the startup code mounts as read-only when constructing the sandbox, the complete set of fonts being:
/fonts/pelm/unicode.8.font
/fonts/lucidasans/unicode.8.font
/fonts/lucidasans/unicode.7.font
The Sys and Draw modules are builtin to the plug-in. Detail of the builtin modules are given elsewhere in this document.

An example of a web page that uses the plug-in and downloads more than one file is the polyhedra example on the Vita Nuova web site. The polyhedra example downloads three files: the polyhedra Dis module, a polyhedra database and a shell script to manipulate the namespace before starting the polyhedra module. The polyhedra database is 361 Kbytes in size and may take a little while to download depending upon the speed of your Internet connection. The HTML page for the polyhedra example contains the following code:

<PARAM name="init" value="pi/wm sh polywrap">
<PARAM name="file1" value="tmp/polyhedra http://www.vitanuova.com/inferno/pi/polyhedra/polyhedra">
<PARAM name="file2" value="polywrap http://www.vitanuova.com/inferno/pi/polyhedra/polywrap">
<PARAM name="file3" value="polyhedra.dis http://www.vitanuova.com/inferno/pi/polyhedra/polyhedra.dis">
The init parameter arranges that the wm window manager invokes the inferno shell, sh, which in turn runs the shell script, polywrap, which looks like this:
#!/dis/sh

# Wrapper for polyhedra, which looks for its data file in /lib

bind -a tmp /lib
polyhedra.dis
The polyhedra module expects to find its database in the directory /lib, it is downloaded to a writeable directory (in this case tmp) which is then bound over the top of the /lib before polyhedra is started.

Starting the Module

The module that is started by the plug-in has /usr/internet as its current directory. The init <PARAM> tag contains the name of the module that the plug-in will run. The first word is assumed to be the name of a Dis module that must either be found in the current directory or else in the /dis directory. Files and modules loaded from the Internet are placed in the current directory unless given a relative path in their file <PARAM> tag. The second and subsequent words in the init <PARAM> tag are passed to the command as arguments.

If the HTML on the web page contains a compile <PARAM> tag with a value of 1:

<PARAM name="compile" value="1">
The plug-in will invoke a JIT compiler to compile each Dis module to native x86 code before running it, otherwise the default behaviour is for the code to be interpreted by the virtual machine. A compiled module will run faster than an interpreted module. You can force a module to invoke the JIT compiler by compiling it from Limbo with the -c flag to the Limbo compiler:
limbo -c module.b
You can prevent a module from invoking the JIT compiler, even if the compile <PARAM> tag has been given a value of 1 in the web page, by compiling it from Limbo with the -C flag to the Limbo compiler:
limbo -C module.b
Once started, a module can load other modules with the load statement and launch new threads of execution with the spawn statement.

Builtin Modules

Certain modules are built in to the plug-in. Although they function as if loaded from Dis files they are actually implemented in C, inside the Inferno kernel. Such modules are known as builtin modules. The plug-in contains a set of builtin modules. The modules are accessed, as for ordinary modules, through a module reference to them obtained by loading them with a load statement:
ref = load Mod Mod->PATH
For example,
sys = load Sys Sys->PATH;
math = load Math Math->PATH;
draw = load Draw Draw->PATH;
The complete set of builtin modules is:
Sys
Inferno system calls are provided by the built-in module declared by sys.m. It contains the fundamental system data structures and interfaces. There are currently 39 calls, providing: file access; basic I/O; name space manipulation; formatted output for Limbo; exception handling; and basic character and string manipulation. See sys-intro(2).
Draw
The Draw module provides basic graphics facilities, defining drawing contexts, images, character fonts, and rectangular geometric operations. See the Tk module and Prefab module for higher level operations, such as windows and menu handling. See draw-intro(2).
Tk
The Tk module provides primitives for building user interfaces, based on Ousterhout's Tcl/TK. The interface to the toolkit itself is primarily the passing of strings to and from the elements of the toolkit using the cmd function; Section 9 of the Inferno manual contains information about the syntax of those strings. See also tk(2).
Prefab
The Prefab module contains components for building graphics objects suitable for Interactive Television (ITV) applications using infrared remote controls. Using the Draw module's operations for simple text and images the toolkit can group individual items, treat those groups as units, and then activate the items on command. See prefab-intro(2), prefab-compound(2), prefab-element(2), prefab-environ(2), prefab-style(2).
Math
Inferno's math(2) module and the Limbo compiler provide the fundamental floating point environment and ``elementary functions'' of applied mathematics.
Srv
The Srv module provides an interface to the the Internet name resolution services of the host operating system, in this case, Windows.
Keyring
This module contains a mixed set of functions that variously:
The builtin modules provide enough functionality to perform many useful tasks. Most applications are likely to make use of the Sys module. Applications that write directly to the display may use the services of the Draw module. Modules that interact with the user through the Tk interface will need to use the Tk module.

Environment Wrappers

Some modules require direct access to the display. Such modules establish their own connection to the display and write directly on the display using the services of the Draw module. Other console-style modules, may simply expect to read from standard input and write to standard output. Another kind of module may use the services of Tk, or expect to be running under the Inferno window manager Wm. To accomodate all these different kinds of module, the plug-in KFS filesystem, plugin.kfs contains some module wrappers that enable a program to operate under these different environments. The Hello World examples in this document illustrate the use of these wrappers.

The wrapper pi/text provides an environment that supports an Inferno Tk console application. A module running under this wrapper can read and write from standard input and output and is displayed in a window with a Tk scroll bar to allow the review of earlier interaction.

The wrapper pi/wm provides an environment that supports an Inferno Tk application that expects to run under the Inferno Wm window manager, and provides an implementation of wmlib(2), with certain default behaviours.

An application started with pi/wm will be given a window sized to match the plug-in area in the web page. It will not have a titlebar and so cannot be moved or minimised. If it needs the full functionality of Wm it should be started under the control of the program wm/wm which is included in the plugin.kfs KFS filesystem.

Hello World Examples

These examples, although not particularly useful, illustrate some of the mechanisms for producing output with a plug-in module. They include applications that write directly to the display using the Draw module, output to a scrollable console window, and use the Tk sub-system. An example is also given of using the an Inferno shell script to control output. A shell script can be embedded in an HTML page and interpreted by the Inferno shell.

Drawing to the Display

The most direct method to produce output from a plug-in module is to draw directly to the display. The Limbo code in the file hellod.b uses the Draw module to display the text Hello World to the screen:
implement Hello;

include "sys.m";
include "draw.m";
 
Hello: module
{
	init: fn(ctxt: ref Draw->Context, argv: list of string);
};

init(nil: ref Draw->Context, nil: list of string)
{
	draw := load Draw Draw->PATH;
	Display, Font, Image, Black: import draw;
	disp := draw->Display.allocate(nil);
	image := disp.image;
	hue := disp.color(Black);
	font := Font.open(disp, "*default*");
	image.text((5,5), hue, (0,0), font, "Hello World");
	<- chan of int; # wait forever
}
The receive from a new chan of int on the last line will never complete and prevents the program from exiting. The program, hellod.b is compiled with the Limbo compiler to produce hellod.dis using:
limbo hellod.b
The resulting Dis module occupies 348 bytes. The HTML fragment used to launch this module would look like this:
<OBJECT
	classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
	codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
	width=500 height=80
>
<PARAM name="init" value="hellod.dis">
<PARAM name="file1" value="hellod.dis http://www.vitanuova.com/inferno/pidoc/intro/hellod.dis">
</OBJECT>
Click here to download and run this module (size 348 bytes).

Writing to Standard Output

A simpler way to display the same text and demonstrating the use of the pi/text wrapper is demonstrated by helloc.b. This uses the print function from the Sys module to write the string "Hello World" to standard output. Invoking the module with the pi/text wrapper arranges that it will be run in a console window and that standard output will appear in that window. The Eliza example, shown earlier, uses standard input and output and so employs this wrapper for the same effect.
implement Hello;

include "sys.m";
include "draw.m";
 
Hello: module
{
	init: fn(ctxt: ref Draw->Context, argv: list of string);
};

init(nil: ref Draw->Context, nil: list of string)
{
	sys := load Sys Sys->PATH;
	sys->print("Hello World\n");
	<- chan of int;
}
In this example, the print function from the Sys module is used to put the message "Hello World" to standard output and the receive from a channel on the last line stops the program from exiting, as before. The program, helloc.b, is compiled with the Limbo compiler:
limbo helloc.b
to produce the output helloc.dis which has size 120 bytes. The HTML fragment used to launch helloc.dis needs to use the text wrapper pi/text and so would look like this:
<OBJECT
	classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
	codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
	width=500 height=80
>
<PARAM name="init" value="pi/text helloc.dis">
<PARAM name="file1" value="helloc.dis http://www.vitanuova.com/inferno/pidoc/intro/helloc.dis">
</OBJECT>
Click here to download and run this module (size 120 bytes).

Using Limbo/Tk

The Limbo code in the file hellow.b uses Tk and the pi/wm wrapper to display a Hello World button in an area on the web page.
implement Hello;

include "sys.m";
include "draw.m";
include "tk.m";
include "wmlib.m";
 
Hello: module
{
	init: fn(ctxt: ref Draw->Context, argv: list of string);
};

init(ctxt: ref Draw->Context, nil: list of string)
{
	wmlib := load Wmlib Wmlib->PATH;
	wmlib->init();
	(top, nil) := wmlib->titlebar(ctxt.screen, nil, nil, 0);
	cmds := array[] of {
		"button .b -text {Hello World}",
		"pack .b",
		"update"
	};
	wmlib->tkcmds(top, cmds);
	<- chan of int;
}
In this example, the titlebar function from the Wmlib module gives us a Tk Toplevel, sized for the web page display area, to which we can apply Tk commands. The function tkcmds, conveniently, takes an array of such commands which are applied in sequence. The program, hellow.b, is compiled with the Limbo compiler:
limbo hellow.b
to produce the output hellow.dis which has size 291 bytes. The HTML fragment used to launch hellow.dis needs to use the Wm wrapper pi/wm and so would look like this:
<OBJECT
	classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
	codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
	width=200 height=50
>
<PARAM name="init" value="pi/wm hellow.dis">
<PARAM name="file1" value="hellow.dis http://www.vitanuova.com/inferno/pidoc/intro/hellow.dis">
</OBJECT>
Click here to download and run this module (size 291 bytes).

Using Echo

The module echo.dis is part of the plug-in KFS filesystem, plugin.kfs and can be invoked from a web page without downloading any Dis modules like so:
<OBJECT
	classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
	codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
	width=500 height=80
>
<PARAM name="init" value="pi/text echo hello world">
</OBJECT>
Click here to download and run this module.

Using the Inferno Shell

A script for the Inferno shell can be embedded in a web page. See the Vita Nuova manual pages for more information about shell(1) commands, and for a paper that describes the Inferno shell.
<OBJECT
	classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
	codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
	width=500 height=80
>
<PARAM name="init" value="pi/wm sh -c '
load tk
winid=${tk window Hello}
tk $winid button .b -text {Hello World}
tk $winid pack .b
tk $winid update
sleep 10
'  ">
</OBJECT>
Click here to download and run this script.

A second example illustrates the use of shell flow control and pipes in a web page script.

<OBJECT
	classid="clsid:C0316421-4BE6-11d3-A893-004095E0A888"
	codebase="http://www.vitanuova.com/plugin/ieplugin.cab"
	width=500 height=80
>
<PARAM name="init" value="pi/text sh -c '
	{
		for i in (H e l l o) { echo -n $i}
		echo '' World''
	} | xd -c
	cat
'  ">
</OBJECT>
Click here to download and run this script.

The examples give some idea of the various ways that code can be executed from a web page inside the Inferno sandbox. Other examples can be found on the Vita Nuova web site

Security

This preliminary release of the Inferno plug-in has no support for signed modules, all modules are assumed to be unsigned. Unsigned modules are run in a very restricted sandbox which allows no access to the network, either locally or remotely, and prevents the user from attaching any devices to the namespace. Consequently, a module can add nothing new to the namespace in which it finds itself when it is initialised by the plug-in. All services, that allow a module to affect the world outside of its sandbox are made available through the namespace (including networking, and file storage). Security in Inferno is enforced by restricting the namespace of a module.

The initial namespace consists of the contents of the read-only filesystem that it mounts from the file plugin.kfs and the initially empty RAM file system that is mounted in the modules home directory (/usr/internet) and in the temporary directory, /tmp.

The next release of the plug-in will support signed modules.

Limitations

The preliminary release of the plug-in has no support for unsigned modules and so prevents modules from accessing any resources outside of the, very restricted, sandbox. In particular, this means that a module can perform no networking and has no access to file storage other than to a RAM filesystem which disappears when the web page is closed.

We are aware of some unwanted control characters in the output and some unusual interpretation of control and movement keys when using the text wrapper with Internet Explorer version 5, particularly annoying is the operation of the backspace key - we are working on this problem.

Debugging

The Inferno download, available from the Vita Nuova web site allows debugging a Dis module before placing it in a web page. It includes a graphical debugger that runs on all Inferno host platforms. When running the module under Internet Explorer the F8 function key can be pressed to show the last few lines of console output which can be used to help understand why a module has failed to run.

Finally

We hope you can use the plug-in to develop some interesting web page applications. We would love to hear about any unusual applications that you develop, and also about any problems that you encounter. Feel free to email us at:
support@vitanuova.com
Please remember that this version of the plug-in is a preliminary release and is likely to require some further modification before it becomes completely stable.