ircII is a free, open-source Unix IRC and ICB client written in C. Initially released in the late 1980s, it is the oldest IRC client still maintained. Wikipedia.
This limited emulation of ircII in WebAssembly demonstrates the use of POSIX standard and similar libraries such as ncurses within the Emscripten environment.
Advantages of this technology can be found if ncurses' output, which is accessible via Emscripten's Standard I/O API, could work inline with Progressive Web Applications (PWAs) and relay screen dimensions dynamically. Further, both ircII and ncurses compile sizes are fairly large meaning optimisations to reduce compile output is needed.
Furthermore, help files and other extended parts of this emulation such as DCC may not work, however, makes the client fun to tinker with as it functions as a working IRC client.
Important Note: This build of ircII depends on ncurses for Emscripten, see jamesbiv/ncurses-emscripten to compile and build your own copy or you can use what's stored in the build/ directory. Further, be sure to have the absolute path of the build/ directory handy to replace the areas marked PATH_TO_NCURSES throughout the below compilation process.
It's recommended to create a separate directory to build this project in. For example ircii-emscripten/.
~$ wget http://ircii.warped.com/ircii-20190117.tar.gz
~$ wget https://raw.githubusercontent.com/jamesbiv/ircii-emscripten/master/ircii-20190117_emscripten.patch
~$ wget https://raw.githubusercontent.com/jamesbiv/ircii-emscripten/master/irc_shell.html
~$ tar -zxvf ircii-20190117.tar.gz
Note: Because this is a source tree level patch make sure the patch is in the directory before the installed directory. For example, if the directory for ircii is /home/user/ircii-emscripten/ircii-20190117 then make sure the patch is located at /home/user/ircii-emscripten/ircii-20190117_emscripten.patch.
~$ patch -p0 < ircii-20190117_emscripten.patch
~$ cd ircii-20190117
~$ nano -w ./configure
Comment out the following line of code using # to reflect the following:
Line 696 #with_openssl
Save and close nano
Note: Be sure to replace PATH_TO_NCURSES with the absolute path to the ncurses for emscripten build/ directory.
~$ export CPPFLAGS='-IPATH_TO_NCURSES/include'
~$ export LDFLAGS='-LPATH_TO_NCURSES/lib'
~$ emconfigure ./configure
~$ nano -w ./Makefile
Line 81 Remove -lssl -lcrypto from LIBS = ...
Note: Be sure to replace PATH_TO_NCURSES with the absolute path to the ncurses for emscripten build/ directory.
Line 320 Add (append) -IPATH_TO_NCURSES/include to the end of INCLUDES = -I ...
Save and close nano
~$ nano -w ./defs.h
Change the following segments to reflect the following:
Line 44 /* #undef HAVE_GETNAMEINFO */
To
Line 44 #define HAVE_GETNAMEINFO 1
Change
Line 119 #define HAVE_SYS_FCNTL_H 1
To
Line 119 /* #undef HAVE_SYS_FCNTL_H */
Change
Note: NON_BLOCKING_CONNECTS should be declared but it's best to check it anyway.
Line 180 /* #undef NON_BLOCKING_CONNECTS */
To
Line 180 #define NON_BLOCKING_CONNECTS 1
Change
Line 221 #define USE_OPENSSL 1
To
Line 221 /* #undef USE_OPENSSL */
Save and close nano
~$ emmake make irc
~$ cp irc ../irc.bc
~$ cd ..
Note: Be certain to include the terminfo database files with --preload-file. You can just include the file(s) that you need or include them all but you'll save about 3MB if you strip them down to the ones you just need, in this case we're using xterm-new.
Note: Be sure to replace PATH_TO_NCURSES with the absolute path to the ncurses for emscripten build/ directory.
emcc -o irc.html irc.bc -O3 -g2 --preload-file PATH_TO_NCURSES/share/terminfo@/home/web_user/.terminfo -s WASM=1 -s FORCE_FILESYSTEM=1 --shell-file ./irc_shell.html -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s EMTERPRETIFY_WHITELIST='["_main", "_irc_io"]' -s TOTAL_MEMORY=32Mb --no-heap-copy -s ASSERTIONS=1
Xterm.js is a great library that emulates a terminal very quickly and works well with ncurses.
You'll need to download a copy from xtermjs/xterm.js or you can use the .min versions that I have uploaded on the demo site.
In order to connect to a working IRC server you’ll need to use something like WebSockify. Ideally WebSocket support for IRCD would be great but for now this does the job fine.
Note: I suggest if you're using WebSockify filter the incoming port from the public as some IRC networks / servers may have proxy protection and will ban you from their server(s) if discovered.
Please see http://68.183.3.42/ircii-emscripten/irc.html for a working demo.
IrcII for Emscripten was a fun project and opens up many possibilities and areas for improvement. Should a future project arise from this patch level I believe forking and customising the current ircii build would be the best scenario.
Also, since Emscripten relies on WebSockets to handle communications disabling OpenSSL at a C level is required. TLS/SSL communications are evoked using wss:// as the WebSocket connection string.
Further, since Emscripten's WebSockets use binary protocol this also needs to be enabled on the service acting as the server.