A => Dockerfile +31 -0
@@ 1,31 @@
+FROM ubuntu:20.04
+
+ARG GIT_COMMIT 4e50c8f91d4a0c8dba14261c8b861a9bd6c6bb0c
+
+LABEL org.opencontainers.image.title="FUNET-NJE"
+LABEL org.opencontainers.image.description="FUNET-NJE"
+LABEL org.opencontainers.image.authors="projects@ajk.me"
+LABEL org.opencontainers.image.url="https://git.sr.ht/~ajk/funetnje-docker"
+
+RUN apt-get update && \
+ apt-get upgrade -y && \
+ apt-get install -y git gcc make
+
+COPY UnixNJE.patch /tmp
+
+RUN cd /tmp && \
+ git clone https://github.com/moshix/UnixNJE && \
+ cd UnixNJE && \
+ git checkout -q $GIT_COMMIT && \
+ git apply ../UnixNJE.patch && \
+ make && \
+ addgroup --gid 2224 funetnje && \
+ make install
+
+RUN adduser --gecos NJE --ingroup users --disabled-password nje && \
+ adduser nje funetnje && \
+ echo "mesg y" >> /home/nje/.profile
+
+COPY entrypoint.sh /docker-entrypoint.sh
+
+ENTRYPOINT ["/docker-entrypoint.sh"]
A => LICENSE +13 -0
@@ 1,13 @@
+Copyright (c) 2022, Andrew Kay
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
A => README.md +64 -0
@@ 1,64 @@
+# FUNET-NJE
+
+Moshix and friends have
+[updated FUNET-NJE for Linux](https://github.com/moshix/UnixNJE).
+However, it requires some specific configuration and doesn't compile on my Linux (_I use arch btw_).
+
+So, here is a [Docker image](https://hub.docker.com/r/ajk7/funetnje)!
+
+## Starting two NJE nodes
+
+You can find example configuration files for two nodes in the [`examples`](examples) folder. Docker
+will mount the files at `/etc/funetnje` in the container.
+
+The default NJE port is `175`. The example configuration expects `NODE1` port `175` to
+be exposed as `1751` by Docker and `NODE2` as `1752`.
+
+First, update [`funetnje.cf`](examples/node1/funetnje.cf) for both nodes:
+
+1. Update `IPADDRESS` to be the IP address of your computer
+2. Update `TCPNAME` for the line to be the IP address of your computer
+
+Then, start two NJE nodes:
+
+```
+docker run -it --rm --name nje_node1 --hostname node1 -v $(pwd)/examples/node1:/etc/funetnje -p 1751:175 funetnje:latest
+docker run -it --rm --name nje_node2 --hostname node2 -v $(pwd)/examples/node2:/etc/funetnje -p 1752:175 funetnje:latest
+```
+
+If successful, you should see the logs from the `funetnje` process appear.
+
+## Sending messages and files
+
+The image contains a `nje` user who is a member of the `funetnje` group.
+
+To log in to `NODE1`:
+
+```
+docker exec -it nje_node1 /bin/login -f nje
+```
+
+It is important to use `/bin/login` to ensure that a `utmp` record is created for the user, this
+allows the `funetnje` process to route messages to you.
+
+The `nje` `.profile` run at login sets `mesg y` allowing messages to be displayed.
+
+To send a message to `NODE2`:
+
+```
+send nje@node2 hello there!
+```
+
+To send a file to `NODE2`:
+
+```
+sendfile nje@node2 hello.txt
+```
+
+To receive the file on `NODE2`:
+
+```
+qrdr
+receive 0001
+cat hello.txt
+```
A => UnixNJE.patch +66 -0
@@ 1,66 @@
+diff --git a/Makefile b/Makefile
+index c03f41e..1461ae3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -198,7 +198,7 @@ INSTALL=install
+ # to successfully use UCP program.
+ NJEGRP=funetnje
+ # On some machines there may exist `send' already, choose another name.
+-SEND=tell
++SEND=send
+ PRINT=njeprint
+ # Assign directories
+ MANDIR= /usr/local/man
+@@ -368,38 +368,29 @@ install:
+ echo "To install actual control/config files do 'make install1' or 'make install2'"
+ @echo "Must propably be root for this also."
+ -mkdir ${LIBDIR}
+- $(INSTALL) -s -m 755 funetnje ${LIBDIR}/funetnje.x
+- mv ${LIBDIR}/funetnje.x ${LIBDIR}/funetnje
+- #$(INSTALL) -s -m 755 ndparse ${BINDIR} # Obsolete
++ $(INSTALL) -s -m 755 funetnje ${LIBDIR}/funetnje
+ $(INSTALL) -s -m 755 bitsend ${BINDIR}
+ $(INSTALL) -s -m 755 qrdr ${BINDIR}
+- #$(INSTALL) -s -m 755 bitcat ${BINDIR} # Obsolete
+ $(INSTALL) -s -g ${NJEGRP} -m 750 ucp ${ETCDIR}
+- $(INSTALL) -s -g ${NJEGRP} -m 755 sendfile ${BINDIR}
+- rm -f ${BINDIR}/${PRINT} ${BINDIR}/submit ${BINDIR}/punch
+- rm -f ${BINDIR}/sf ${BINDIR}/bitprt
+- ln ${BINDIR}/sendfile ${BINDIR}/sf
+- ln ${BINDIR}/sendfile ${BINDIR}/${PRINT}
+- ln ${BINDIR}/sendfile ${BINDIR}/bitprt
+- ln ${BINDIR}/sendfile ${BINDIR}/punch
+- ln ${BINDIR}/sendfile ${BINDIR}/submit
+- $(INSTALL) -s -g ${NJEGRP} -m 755 tell ${BINDIR}/${SEND}
+- # If you want to call 'send' with name 'tell'
+- # rm -f ${BINDIR}/tell
+- # ln ${BINDIR}/${SEND} ${BINDIR}/tell
+- $(INSTALL) -s -g ${NJEGRP} -m 755 ygone ${BINDIR}
++ $(INSTALL) -s -g ${NJEGRP} -m 2755 sendfile ${BINDIR}
++ $(INSTALL) -s -g ${NJEGRP} -m 2755 ${SEND} ${BINDIR}/${SEND}
++ $(INSTALL) -s -g ${NJEGRP} -m 2755 ygone ${BINDIR}
+ $(INSTALL) -s -g ${NJEGRP} -m 755 receive ${BINDIR}
+- $(INSTALL) -s -g ${NJEGRP} -m 750 bmail ${LIBDIR}
+- mkdir -p /var/spool/bitnet
+- chgrp ${NJEGRP} /var/spool/bitnet
+- chmod g+w /var/spool/bitnet
+- chmod g+s ${BINDIR}/sendfile ${BINDIR}/tell ${BINDIR}/ygone \
+- ${LIBDIR}/bmail
++ $(INSTALL) -s -g ${NJEGRP} -m 2750 bmail ${LIBDIR}
+ $(INSTALL) -s -m 755 transfer ${LIBDIR}/transfer
+ $(INSTALL) -s -m 755 njeroutes ${LIBDIR}/njeroutes
+ $(INSTALL) -s -m 755 namesfilter ${LIBDIR}/namesfilter
+ $(INSTALL) -s -g ${NJEGRP} -m 750 mailify ${LIBDIR}/mailify
+ $(INSTALL) -c -g ${NJEGRP} -m 750 sysin.sh ${LIBDIR}/sysin
++ ln -s ${BINDIR}/sendfile ${BINDIR}/sf
++ ln -s ${BINDIR}/sendfile ${BINDIR}/${PRINT}
++ ln -s ${BINDIR}/sendfile ${BINDIR}/bitprt
++ ln -s ${BINDIR}/sendfile ${BINDIR}/punch
++ ln -s ${BINDIR}/sendfile ${BINDIR}/submit
++ ln -s ${BINDIR}/${SEND} ${BINDIR}/tell
++ mkdir -p /var/spool/funetnje
++ chgrp ${NJEGRP} /var/spool/funetnje
++ chmod g+w /var/spool/funetnje
+
+ install1: route
+ @echo "MUST BE ROOT TO DO THIS!"
A => entrypoint.sh +16 -0
@@ 1,16 @@
+#!/bin/bash
+
+if [ $# -eq 0 ]; then
+ export PATH=$PATH:/usr/local/funetnje
+
+ echo "Rebuilding route table..."
+ njeroutes /etc/funetnje/route.header /etc/funetnje/route.routes /run/funetnje.route
+
+ echo "Starting NJE..."
+ funetnje &
+ FUNETNJE_PID=$!
+
+ tail -F /var/log/funetnje.log --pid=$FUNETNJE_PID 2>/dev/null
+else
+ exec "$@"
+fi
A => examples/node1/cmd-help.txt +1 -0
@@ 1,1 @@
+Put your command help here.
A => examples/node1/file-exit.cf +41 -0
@@ 1,41 @@
+# FILE-EXIT.CF -- Configure file handling on FUNET-NJE
+#
+# Rule for spool disposition path, defines also system default
+# user spool directory for those who don't have specially set
+# something else.
+# Possibilities: ~/bitspool -- real user's only! (~/ == users home)
+# /usr/path/path/ -- append 'touser' as subdir,
+# it is spool dir.
+# Valid for Exits and real users.
+# /usr/path/path -- explicite directory.
+# /dev/null -- explicite file (special case).
+# When directory isn't present, it is built from upmost present level
+# down to users bottommost level hmm...
+# Question about ownership of directory/files...
+# Real users: real protections, programs start with setuid() user.
+# Exit users: POSTMAST (exits start as root anyway.)
+# Exited reals: real protections, programs start with setuid() user.
+
+Spool-Dir: /var/spool/funetnje/
+Postmast-Dir: /var/spool/funetnje/POSTMAST
+
+# Now list of things to match and then what to do
+# To do keywords: DISCARD to /dev/null.
+# KEEP just so. Into default or given spool.
+# NOTIFY send an NJE message to someone.
+# RUN starts arbitary program with arbitary
+# arguments telling about file location
+# and its properties.
+# If fails, well..
+
+Exit-Table:
+
+# Args:
+# touser8 tonode8 fname8 ftype8 pun? class fruser8 frnode8 dist8 SpoolDir action ExtraArguments
+
+# ...
+
+#
+# Finally a 'catch them all' default handling case.
+#
+* * * * * * * * * default KEEP
A => examples/node1/funetnje.cf +20 -0
@@ 1,20 @@
+NAME NODE1
+IPADDRESS 0.0.0.0
+CMDMAILBOX UDP 127.0.0.1 175
+TABLE /run/funetnje.route
+QUEUE /var/spool/funetnje
+LOG /var/log/funetnje.log
+USEREXITS /etc/funetnje/file-exit.cf
+MSGEXITS /etc/funetnje/msg-exit.cf
+INFORM ROOT@NODE1
+LLEVEL 2
+DEFAULT-ROUTE NODE2
+
+LINE 0 NODE2
+ TYPE UNIX_TCP
+ TCPNAME 192.168.1.103
+ IPPORT 1752
+ TIMEOUT 10
+ BUFSIZE 4096
+ TCP-SIZE 8192
+ MAX-STREAMS 2
A => examples/node1/msg-exit.cf +34 -0
@@ 1,34 @@
+#
+# MSG-EXIT.CF for FUNET-NJE
+#
+# Some first ideas about patterns, et.al.:
+#
+# Actions: CMD: BUILTIN, RUN
+# MSG: BRCAST, DISCARD, RUN, (PIPE)
+# Argument tokens for 'RUN': TOUSER, TONODE, FRUSER, FRNODE, TEXT, ARGS
+# Arguments for 'BUILTIN': "HELP", "HARDCODED", "ERROR"/ERROR msg-string",
+# "ALIAS remap-pattern"
+# Patterns work as follows:
+# TO*KEN -- match (only) any of input words: TO TOK TOKE TOKEN
+# * -- match any token, (but not blank)
+# ** -- match any number of tokens, including nothing.
+# Remap-patterns work as follows:
+# $nn -- substitute nn:th text token into this place
+# ANYSTRING -- copy it verbatim
+#
+
+CmdHelpFile: /etc/funetnje/cmd-help.txt
+
+#$TOUSER $TONODE $FRUSER $FRNODE C pattern ACTION args
+. NODE1 * * C "HELP" BUILTIN HELP
+. NODE1 * * C "ECHO **" RUN /usr/local/bin/send -s $FRUSER@$FRNODE *CMD was '$TEXT'
+. NODE1 * * C "**" BUILTIN ERROR
+
+#$TOUSER $TONODE $FRUSER $FRNODE M ACTION args
+# "." == FRUSER is blank, that is from some 'SYSTEM'...
+VMNET * * * M DISCARD
+ECHO NODE1 . * M DISCARD
+ECHO NODE1 * * M RUN /usr/local/bin/send -u echo $FRUSER@$FRNODE *MSG was '$TEXT'
+
+# The default...
+* * * * M BRCAST
A => +1 -0
@@ 1,1 @@
ROUTE NODE1 LOCAL ASCII
A => examples/node1/route.routes +1 -0
@@ 1,1 @@
+ROUTE NODE2 NODE2
A => examples/node2/cmd-help.txt +1 -0
@@ 1,1 @@
+Put your command help here.
A => examples/node2/file-exit.cf +41 -0
@@ 1,41 @@
+# FILE-EXIT.CF -- Configure file handling on FUNET-NJE
+#
+# Rule for spool disposition path, defines also system default
+# user spool directory for those who don't have specially set
+# something else.
+# Possibilities: ~/bitspool -- real user's only! (~/ == users home)
+# /usr/path/path/ -- append 'touser' as subdir,
+# it is spool dir.
+# Valid for Exits and real users.
+# /usr/path/path -- explicite directory.
+# /dev/null -- explicite file (special case).
+# When directory isn't present, it is built from upmost present level
+# down to users bottommost level hmm...
+# Question about ownership of directory/files...
+# Real users: real protections, programs start with setuid() user.
+# Exit users: POSTMAST (exits start as root anyway.)
+# Exited reals: real protections, programs start with setuid() user.
+
+Spool-Dir: /var/spool/funetnje/
+Postmast-Dir: /var/spool/funetnje/POSTMAST
+
+# Now list of things to match and then what to do
+# To do keywords: DISCARD to /dev/null.
+# KEEP just so. Into default or given spool.
+# NOTIFY send an NJE message to someone.
+# RUN starts arbitary program with arbitary
+# arguments telling about file location
+# and its properties.
+# If fails, well..
+
+Exit-Table:
+
+# Args:
+# touser8 tonode8 fname8 ftype8 pun? class fruser8 frnode8 dist8 SpoolDir action ExtraArguments
+
+# ...
+
+#
+# Finally a 'catch them all' default handling case.
+#
+* * * * * * * * * default KEEP
A => examples/node2/funetnje.cf +20 -0
@@ 1,20 @@
+NAME NODE2
+IPADDRESS 0.0.0.0
+CMDMAILBOX UDP 127.0.0.1 175
+TABLE /run/funetnje.route
+QUEUE /var/spool/funetnje
+LOG /var/log/funetnje.log
+USEREXITS /etc/funetnje/file-exit.cf
+MSGEXITS /etc/funetnje/msg-exit.cf
+INFORM ROOT@NODE2
+LLEVEL 2
+DEFAULT-ROUTE NODE1
+
+LINE 0 NODE1
+ TYPE UNIX_TCP
+ TCPNAME 192.168.1.103
+ IPPORT 1751
+ TIMEOUT 10
+ BUFSIZE 4096
+ TCP-SIZE 8192
+ MAX-STREAMS 2
A => examples/node2/msg-exit.cf +34 -0
@@ 1,34 @@
+#
+# MSG-EXIT.CF for FUNET-NJE
+#
+# Some first ideas about patterns, et.al.:
+#
+# Actions: CMD: BUILTIN, RUN
+# MSG: BRCAST, DISCARD, RUN, (PIPE)
+# Argument tokens for 'RUN': TOUSER, TONODE, FRUSER, FRNODE, TEXT, ARGS
+# Arguments for 'BUILTIN': "HELP", "HARDCODED", "ERROR"/ERROR msg-string",
+# "ALIAS remap-pattern"
+# Patterns work as follows:
+# TO*KEN -- match (only) any of input words: TO TOK TOKE TOKEN
+# * -- match any token, (but not blank)
+# ** -- match any number of tokens, including nothing.
+# Remap-patterns work as follows:
+# $nn -- substitute nn:th text token into this place
+# ANYSTRING -- copy it verbatim
+#
+
+CmdHelpFile: /etc/funetnje/cmd-help.txt
+
+#$TOUSER $TONODE $FRUSER $FRNODE C pattern ACTION args
+. NODE2 * * C "HELP" BUILTIN HELP
+. NODE2 * * C "ECHO **" RUN /usr/local/bin/send -s $FRUSER@$FRNODE *CMD was '$TEXT'
+. NODE2 * * C "**" BUILTIN ERROR
+
+#$TOUSER $TONODE $FRUSER $FRNODE M ACTION args
+# "." == FRUSER is blank, that is from some 'SYSTEM'...
+VMNET * * * M DISCARD
+ECHO NODE2 . * M DISCARD
+ECHO NODE2 * * M RUN /usr/local/bin/send -u echo $FRUSER@$FRNODE *MSG was '$TEXT'
+
+# The default...
+* * * * M BRCAST
A => +1 -0
@@ 1,1 @@
ROUTE NODE2 LOCAL ASCII
A => examples/node2/route.routes +1 -0
@@ 1,1 @@
+ROUTE NODE1 NODE1