Plan 9 : The Infinity Notebook

 

Plan 9 is an Operating System (OS) from Bell Labs which is a successor to UNIX. It builds on the learnings from the previous Operating systems. Network computing and graphics is an integral part of the OS rather than an afterthought. It is modular and portable - it comes with a cross compiler. It is available, under MIT License, which anybody can use, learn and tweak.

Features

  • Everything is a file.
  • Singular Grid: All the computers running Plan 9 OS and connected together act like a singular grid. So there's no need for remote access solutions like VNC or RDP. This cool video shows a small glimpse of the possibilities.
  • Process Isolation: Processes run within their own namespaces and are isolated from each other. So you can run rio (the window manager) within rio. Applications like Browsers don't need complicated sandboxing. And a crashing program is unlikely to bring down the OS.
  • No DLL Hell: Binaries are always statically linked. So there's no DLL hell and there's no need for application bundles like Snap, Flatpak and Appimage.
  • Plumber: This allows user to define custom rules for disparate application interactions. e.g. opening a browser for HTTP URL or a mail client for mailto URL or a text editor for a file URL.
  • Rune: Unicode (UTF) character handling (multi-lingual support) is easily done via Rune API.
  • Threads and procs occupy a shared address space, communicating and synchronizing through channels and shared variables. A proc is a Plan 9 process that contains one or more cooperatively–scheduled threads.

 

Plan 9 Keybindings

Plan 9 OS user interface (UI) is mouse oriented. However, thanks to Common User Access (CUA) specification, we have come to expect keyboard shortcuts to work for certain repeated actions. e.g. Ctrl+x, Ctrl+c and Ctrl+v for cut, copy and paste respectively. This is an attempt to introduce the same in Plan 9.

riow allows you to use keyboard for window management. bar can be used to display date and time.

#!/bin/rc
</dev/kbdtap riow >/dev/kbdtap |[3] bar -p t
   

 

Rio : Window Manager

Developer Note: Rio considers everything between w->qh and w->nr as commands (delimited by \n) to be executed. w->q0 is the insertion point. w->q0 and w->q1 are the selection bounds. frame(3) is responsible for displaying the text.


 Rio supports basic auto-suggest via Ctrl+F. Here's an attempt to add a drop-down for the same.

 

Demo of undo and redo in Rio.



 Rio as a File Explorer and a simple Text Editor. Also, you can use PrtScn key for screenshots.


Location and command history with fuzzy search. The history files are saved under the user home directory.



 

Auto-complete using look /lib/words.

 


Remote control Rio window using rc. This is achieved by writing to wctl and cons files. This demonstrates why scripting on Plan 9 is so much more powerful than other platforms.


 

Demo of editing with multiple cursors.

 

Jump to quick bookmarks using Ctrl + [0-9]. Set using Ctrl + Shift + [0-9].

 



Rio respects your language. You can use the scripting language you are comfortable with to tailor your workflow.

 

 

Multiple edits in a narrowed region.

 

OSD controls for Treason video player.

 

Debug toolbar

Inspect variable


Debugging with Acid, the debugger. lbp(line) sets a breakpoint in the current file. lv(v) is used to query the variable value. These are custom functions available at sys/lib/acid/port.



Media mode for controlling the Zuke media player.


Code (Work in Progress)


Sound

/dev/audio provides a PCM sink which can be multiplexed for use by multiple programs using the mixfs(4) file server which binds over /dev/audio and provides a /dev/audio for each program.

 

Plumber

Running rules are in /mnt/plumb/rules. For permanent changes, modify /sys/lib/plumb/basic.

Some useful plumbing rules: treason (video player)

# video
type is text
data matches '[a-zA-Z¡-￿0-9_\-.,/]+'
data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(mp4|MP4|avi|mkv)'
arg isfile    $0
plumb to video
plumb start window -scroll treason $file 
   

 Use attribute 'debug=1' to display the command used by plumber after matching the rules.

  

Truetype Font

ttfrender output

Truetype fonts (TTF variable width font) work somewhat fine - you can notice some jarring. Just follow the manual (man truetypefs) and remember that /n/ttf is a virtual filesystem - don't expect to see any files listed there.

# ttfrender uses an actual TTF file - not the one served by truetypefs. It writes the output to the stdout
ttfrender -p 72 /lib/font/ttf/bold.ttf a.txt > a.bmp
 
# bold.ttf must exist in /lib/font/ttf/bold.ttf
truetypefs
font=/n/ttf/bold.ttf.16/font
acme -c 1 /lib/glass
   

 

Graphics

Showcasing simple geometrical shapes - lines, circle, ellipse and bezier curves.


  

Plotting

Plot interprets plotting instructions (see plot(7)) from the standard input, drawing the results in the window. Plot persists until a newline is typed in the window.

 

Sample plotting instructions

: Starts a comment
: Set up the co-ordinate system
ra 0 0 200 200

: Line
li 0 0 200 200

: Box
bo 10 10 20 20

: Circle
ci 40 40 30

: Move to 100,100 and write text
m  100 100
t  "Hello Plan9"

: Polygon
pol {
  160.00 100.00  151.96 120.00  130.00 134.64  100.00 140.00
  70.00 134.64   48.04 120.00   40.00 100.00   48.04 80.00
  70.00 65.36    100.00 60.00   130.00 65.36   151.96 80.00
  160.00 100.00
}
   

 

The graph command takes data points and generates the plot commands as output. To generate a visual graph, the pipeline looks like:

cat data.txt | graph | plot
 
graph < data.txt | plot
 
echo "1 1
2 4
3 9
4 16
5 25" | graph | plot    
 

 

The fplot command provides a simpler alternative for certain mathematical functions.

fplot 'sin(x)'
 


mapdemo draws maps on various projections using plot. Note: Do read /lib/map/README.

  

Mail

Handy scripts to verify Gmail configuration. Replace the bold text with appropriate values. Password is an app password that you can create here.

Read the Official docs for setup. Use mail or acme for better user experience.

Receive Mail (IMAP)

#!/bin/rc
auth/factotum -g 'proto=pass server=imap.gmail.com service=imap user=<gmail address> !password=IMAP_PASS'

# Add to trusted servers - IMAP
# echo 'x509 sha256=xxxx' >>/sys/lib/tls/mail

upas/fs -f /imaps/imap.gmail.com/<gmail address>
# Access a different label/folder
# upas/fs -f /imaps/imap.gmail.com/<gmail address>/[Gmail]/Spam

ls /mail/fs/mbox
 

 

Since upas presents mail box as a folder, you can use shell commands to view and delete mails (cat and rm respectively).

ls /mail/fs/mbox/ | awk '
/[0-9]+$/ {
    base = $0
    "basename " base | getline id

    file = base "/from"
    getline from < file
    close(file)

    file = base "/subject"
    getline subj < file
    close(file)

    printf "E%-3s %-20s  %s\n", substr(id, 0, 3), substr(from, 0, 20), subj
}'
 

  

Send Mail (SMTP) 

#!/bin/rc
auth/factotum -g 'proto=pass server=smtp.gmail.com service=smtp user=<gmail address> !password=SMTP_PASS'

# Add to trusted servers - SMTP
# echo 'x509 sha256=xxxx' >>/sys/lib/tls/smtp

# Send mail
echo test | upas/smtp -a -u <gmail address> net!smtp.gmail.com!587 <gmail address> <to email address>
 

Use upasname=<gmail address> mail -s Subject receiver@domain.com to send an email. This activates the hold mode. Use Ctrl+D to finish.

For attachments, use -a option or  attach:  header in the mail body. For inline display, use -A option or  include:  header in the mail body.

For scripting operations, use upas/marshal directly echo body | upasname=<gmail address> upas/marshal -s Subject receiver@domain.com 

The send mail pipeline:

mail > upas/marshal (generate proper message format) > upas/send (apply rules) > /mail/lib/qmail (filter [vf] + queue [runq] in /mail/queue/$user/) > /mail/lib/remotemail > /bin/upas/smtp
 

 

HTML Emails


 
Upas makes Mime parts of a mail available as separate numbered folders (usually 1 for text and 2 for HTML etc.) under the main message folder. e.g. /mail/fs/mbox/$1/2/body . Use plumbing rules to open the same using the browser. 

# open html email with web browser
type    is    text
data    matches    'E(.*)'
data    set    /mail/fs/mbox/$1/2/body.html
plumb    to    web
plumb client window $browser $0
 

 

Switch Mailbox

While using mail, you can switch to a different mailbox using mb command. 

:mb /imaps/imap.gmail.com/<gmail address>
 
:mb /imaps/imap.gmail.com/<gmail address>/[Gmail]/Spam
 

While using upas/fs, you can manage multiple mailboxes using open command. Each mailbox appears as a separate folder under /mail/fs while the current mailbox also appears as /mail/fs/mbox.

echo open /imaps/imap.gmail.com/<gmail address> > /mail/fs/ctl
 
echo open /imaps/imap.gmail.com/<gmail address>/[Gmail]/Spam > /mail/fs/ctl
 

   

Newsgroups

newt is a simple client for reading NNTP (Network News Transport Protocol) Newsgroups. A sample session:

nntpfs news.gmane.io
newt -f gmane.emacs.devel
help  # List available commands
q        # Exit

 

Notifications

Use aux/statusmsg to track progress and completion of a long running task.
fn notify {
    scr=`{awk '{print $4, $5}' /dev/screen}
    w=200
    h=60
    ws=$scr(1)
    hs=$scr(2)
    minx=`{echo $ws - $w | bc}
    warg=`{echo -w  $minx,0,$ws,$h}
    aux/statusmsg $warg $1
}
 

 

Troubleshooting

Killing process

In Plan 9, the command to kill a process is kill <procname> | rc. Also, ensure you clean up any service files in /srv directory.

Program hanging on plumbing

If a program is hanging while sending a plumb message, check if ls /mnt is working. If it's hanging too, you can unmount /mnt and restart plumber. 

Stale mounts

access() check will pass for even a stale mount. Hence, you must use open() to verify

  

References

Comments

Popular posts from this blog

Emacs: Binary File Viewer

HTML Renderer (Emacs)