Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2012-12-19

Inferno OS IRC client with persistent connections

I've written before about how Inferno makes it easy to share resources across devices and networks. 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.

The IRC client I'm using for Inferno is written by mjl. A large number of useful Inferno and Plan 9 utilities with source is available at mjl's bitbucket repository. The one that provides IRC capability is ircfs. 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.

Building

Building from within Inferno requires a couple of environment variables to be set. ROOT is the path to the root of the Inferno system and SYSHOST should be set to 'Inferno':

% cd ircfs
% ROOT=/
% SYSHOST=Inferno
% mk install
cd module ; mk install
mk: 'install' is up to date
cd appl ; mk install
cd cmd ; mk install
rm -f /dis/testirc.dis && cp testirc.dis /dis/testirc.dis
rm -f /dis/ircfs.dis && cp ircfs.dis /dis/ircfs.dis
cd wm ; mk install
mk: 'install' is up to date
cd lib ; mk install
mk: 'install' is up to date
cd man ; mk install
mk: 'install' is up to date

This installs ircfs 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 bind this over the system directories using a union file system. ircfs installs a useful man page which is worth reading to find out all the options.

Running ircfs

When ircfs 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 /mnt/irc for the server we want to connect to, then run ircfs passing this directory name:

% 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

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

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

Ensure that ndb/cs is running to allow network connections from Inferno before continuing.

Running the IRC GUI

The GUI for ircfs is run with the command wm/irc, optionally passing the path to the ircfs directory structure as an argument:

% wm/irc /mnt/irc/freenode

Image of wm/irc running

On the left of the wm/irc screen is a list of the servers and channels. Currently there is status and (freenode). The (freenode) window is for sending commands to the irc server once we're connected. To connect to irc.freenode.net enter the following in the (freenode) area:

/connect irc.freenode.net mynick

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

GUI commands

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

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

/win add /mnt/irc/freenode

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

/win del

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

/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:

away can be used to mark the user as away or back on all servers. exit will exit the GUI but leave ircfs connections intact.

Persistent connections

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've been away. This allows other users to leave me messages when I'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.

A similar approach can be done using ircfs by running the ircfs server on a remote machine and on the client mounting the ircfs filesystem. The connection can be encrypted and authenticated.

The following is a simple setup. Install Inferno on the remote server and build and install ircfs as described previously. Run ircfs 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:

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

On the client we mount this exported filesystem using encryption (replace example.com with the hostname of the server):

% 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

The directory and files shown are those from the remote server. Running wm/irc will now use the servers ircfs files:

% wm/irc /mnt/irc/freenode

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, mount the remote filesystem again and continue where you left off.

Conclusion

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

The ircfs source is written in Limbo and is quite easy to follow. It's a good example of mapping an existing protocol onto Inferno's "everything is a file" metaphor and making use of the tools to share resources. One use of this is having Inferno on other devices, like a phone, so you can connect to IRC connections running on a local machine if you temporarily need to be mobile.

Tags


This site is accessable over tor as hidden service mh7mkfvezts5j6yu.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-44/


Tags

Archives
Links