summaryrefslogtreecommitdiffstats
path: root/network/tnfsd
diff options
context:
space:
mode:
Diffstat (limited to 'network/tnfsd')
-rw-r--r--network/tnfsd/COPYING41
-rw-r--r--network/tnfsd/README48
-rw-r--r--network/tnfsd/doinst.sh22
-rw-r--r--network/tnfsd/git2tarxz.sh75
-rw-r--r--network/tnfsd/rc.tnfsd48
-rw-r--r--network/tnfsd/remove_broken_tcp_support.diff168
-rw-r--r--network/tnfsd/slack-desc19
-rw-r--r--network/tnfsd/tnfsd.1103
-rw-r--r--network/tnfsd/tnfsd.SlackBuild144
-rw-r--r--network/tnfsd/tnfsd.info10
-rw-r--r--network/tnfsd/tnfsd.rst95
11 files changed, 773 insertions, 0 deletions
diff --git a/network/tnfsd/COPYING b/network/tnfsd/COPYING
new file mode 100644
index 0000000000..e6bf05a125
--- /dev/null
+++ b/network/tnfsd/COPYING
@@ -0,0 +1,41 @@
+This information copied from the C sources.
+
+License for all tnfsd source files except strlcat.c and strlcpy.c:
+
+ The MIT License
+
+ Copyright (c) 2010 Dylan Smith
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+License for strlcat.c and strlcpy.c:
+
+ Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ Permission to use, copy, modify, and 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.
diff --git a/network/tnfsd/README b/network/tnfsd/README
new file mode 100644
index 0000000000..1bbf964283
--- /dev/null
+++ b/network/tnfsd/README
@@ -0,0 +1,48 @@
+tnfsd (trivial network filesystem server)
+
+TNFS is a simplified Internet file transfer protocol, designed for
+limited resource usage and ease of implementation on small systems,
+such as 8-bit computers. It's simpler than NFS, SMB, or FTP. It's
+similar to TFTP, but has features TFTP lacks.
+
+Since tnfsd has no access control other than file permissions, and
+since we generally don't want clients to have write access, this
+package uses a dedicated user/group for the daemon, and another group
+to control local write access to the shared directory.
+
+Before running this SlackBuild, you must create the tnfsd user and
+the tnfsd and tnfs-files groups. Use these commands:
+
+ groupadd -g 375 tnfsd
+ groupadd -g 376 tnfs-files
+ useradd -u 375 -d /var/tnfs -c "TNFS Daemon User" \
+ -M -g tnfsd tnfsd -s /bin/false
+
+After the package is installed, add any users you want to the tnfs-files
+group. These users will be able to create files in the /var/tnfs
+directory. Example:
+
+ usermod -a -G tnfs-files joeblow
+
+After the above command, the user joeblow will have to log out and
+back in, to join the new group. Once this is done, the user can
+copy files to /var/tnfs (or ~tnfs) and they will be visible to TNFS
+clients.
+
+TNFS uses UDP port 16384, so make sure you allow incoming traffic if
+you have firewall rules.
+
+This package includes the server and an init script for running
+tnfsd as a system daemon. To start tnfsd at boot, first edit
+/etc/rc.d/rc.tnfsd, read the comments, and change the default user and
+directory if needed. Then add this to /etc/rc.d/rc.local:
+
+ [ -x /etc/rc.d/rc.tnfsd ] && /etc/rc.d/rc.tnfsd start
+
+Depending on how you're using tnfsd, it might make more sense to start
+the service as needed, as an unprivileged user, instead of running it
+as a system daemon.
+
+Usage logging is a compile-time option. By default, it's enabled. If
+you find it too chatty, you can rebuild this with USAGELOG=no set in
+the environment.
diff --git a/network/tnfsd/doinst.sh b/network/tnfsd/doinst.sh
new file mode 100644
index 0000000000..c033d262ca
--- /dev/null
+++ b/network/tnfsd/doinst.sh
@@ -0,0 +1,22 @@
+config() {
+ NEW="$1"
+ OLD="$(dirname $NEW)/$(basename $NEW .new)"
+ if [ ! -r $OLD ]; then
+ mv $NEW $OLD
+ elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then
+ rm $NEW
+ fi
+}
+
+preserve_perms() {
+ NEW="$1"
+ OLD="$(dirname $NEW)/$(basename $NEW .new)"
+ if [ -e $OLD ]; then
+ cp -a $OLD ${NEW}.incoming
+ cat $NEW > ${NEW}.incoming
+ mv ${NEW}.incoming $NEW
+ fi
+ config $NEW
+}
+
+preserve_perms etc/rc.d/rc.tnfsd.new
diff --git a/network/tnfsd/git2tarxz.sh b/network/tnfsd/git2tarxz.sh
new file mode 100644
index 0000000000..751a3f6bc9
--- /dev/null
+++ b/network/tnfsd/git2tarxz.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# Create source tarball from git repo, with generated version number.
+
+# This is not a generic git2tarxz script, it's specific to tnfsd.
+# Upstream doesn't use tags for version bumps, so the version number
+# is extracted from main.c. Also, the repo contains a bunch of
+# other stuff unrelated to tnfs, which we don't include in our
+# tarball.
+
+# Takes one optional argument, which is the commit or tag to create a
+# tarball of. With no arg, HEAD is used.
+
+# Version number example: 0.0.1+20200227_ad7ec17
+
+# Notes:
+
+# Do not use this if you're packaging a release.
+
+# This script doesn't need to be run as root. It does need to be able
+# to write to the current directory it's run from.
+
+# Running this script twice for the same commit will NOT give identical
+# tarballs, even if the contents are identical. This is because tar
+# includes the current time in a newly-created tarball (plus there may
+# be other git-related reasons).
+
+# Once you've generated a tarball, you'll still need a place to host it.
+# Ask on the mailing list, if you don't have your own web server to
+# play with.
+
+## Config:
+PRGNAM=tnfsd
+CLONE_URL=https://github.com/FujiNetWIFI/spectranet/
+## End of config.
+
+set -e
+
+GITDIR=$( mktemp -dt $PRGNAM.git.XXXXXX )
+rm -rf $GITDIR
+git clone $CLONE_URL $GITDIR
+
+CWD="$( pwd )"
+cd $GITDIR
+
+if [ "$1" != "" ]; then
+ git reset --hard "$1" || exit 1
+fi
+
+GIT_SHA=$( git rev-parse --short HEAD )
+
+# the version hardcoded in main.c includes the date, so
+# don't use this.
+#DATE=$( git log --date=format:%Y%m%d --format=%cd | head -1 )
+#VERSION=${DATE}_${GIT_SHA}
+
+VERMAIN="$( grep 'const *char *\*version' tnfs/tnfsd/main.c | cut -d'"' -f2 )"
+VERSION=${VERMAIN}_${GIT_SHA}
+
+rm -rf .git
+find . -name .gitignore -print0 | xargs -0 rm -f
+
+rm -rf tnfs/tnfsd/{vscode_sample,bin/*}
+mv tnfs/*.{md,txt} tnfs/tnfsd
+
+cd "$CWD"
+rm -rf $PRGNAM-$VERSION $PRGNAM-$VERSION.tar.xz
+mv $GITDIR/tnfs/tnfsd $PRGNAM-$VERSION
+rm -rf $GITDIR
+tar cvfJ $PRGNAM-$VERSION.tar.xz $PRGNAM-$VERSION
+
+echo
+echo "Created tarball: $PRGNAM-$VERSION.tar.xz"
+echo "VERSION=\"$VERSION\""
+echo "MD5SUM=\"$( md5sum $PRGNAM-$VERSION.tar.xz | cut -d' ' -f1 )\""
diff --git a/network/tnfsd/rc.tnfsd b/network/tnfsd/rc.tnfsd
new file mode 100644
index 0000000000..392856115a
--- /dev/null
+++ b/network/tnfsd/rc.tnfsd
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# rc.tnfsd, part of SBo tnfsd build, by B. Watson. WTFPL.
+
+# To start tnfsd at boot, make this script executable, then add this code
+# to /etc/rc.d/rc.local:
+# [ -x /etc/rc.d/rc.tnfsd ] && /etc/rc.d/rc.tnfsd start
+
+# tnfsd will chroot to $TNFS_ROOT and set its user ID to $TNFS_USER,
+# and its group ID to $TNFS_USER's primary group. Since there's no
+# other form of access control, make sure the $TNFS_USER can't wrote
+# to $TNFS_ROOT, unless you want to allow everyone who can connect
+# to write/delete/overwrite everything in $TNFS_ROOT. By default,
+# /var/tnfs is owned by root:tnfs-files.
+
+TNFS_USER=tnfsd
+TNFS_ROOT=/var/tnfs
+
+# Log gets overwritten on startup (no rotation).
+TNFS_LOG=/var/log/tnfsd.log
+
+# If you don't need the log at all. But if tnfsd fails to start, you
+# won't see any error messages from it...
+#TNFS_LOG=/dev/null
+
+kill_tnfsd() {
+ /usr/bin/killall tnfsd && sleep 1
+}
+
+start_tnfsd() {
+ echo "Starting tnfsd."
+ kill_tnfsd &>/dev/null
+ /usr/bin/tnfsd "$TNFS_ROOT" -c "$TNFS_USER" >"$TNFS_LOG" </dev/null 2>&1 &
+}
+
+stop_tnfsd() {
+ echo "Stopping tnfsd."
+ kill_tnfsd
+}
+
+case "$1" in
+ ""|start) start_tnfsd ;;
+ stop) stop_tnfsd ;;
+ restart) stop_tnfsd ; start_tnfsd ;;
+ *) echo "Usage: $0 stop|start|restart" 1&>2; exit 1 ;;
+esac
+
+exit 0
diff --git a/network/tnfsd/remove_broken_tcp_support.diff b/network/tnfsd/remove_broken_tcp_support.diff
new file mode 100644
index 0000000000..010f04baf4
--- /dev/null
+++ b/network/tnfsd/remove_broken_tcp_support.diff
@@ -0,0 +1,168 @@
+diff -Naur tnfsd-23.0207.1_95c5b55/config.h tnfsd-23.0207.1_95c5b55.patched/config.h
+--- tnfsd-23.0207.1_95c5b55/config.h 2023-02-08 13:35:32.000000000 -0500
++++ tnfsd-23.0207.1_95c5b55.patched/config.h 2023-02-08 13:37:37.069280883 -0500
+@@ -28,7 +28,6 @@
+ #define MAX_DHND_PER_CONN 8 /* max open directories per client */
+ #define MAX_CLIENTS 4096 /* maximum number of UDP clients */
+ #define MAX_CLIENTS_PER_IP 4096 /* maximum number of UDP clients from single IP */
+-#define MAX_TCP_CONN 256 /* Maximum number of TCP clients */
+ #define SESSION_TIMEOUT 21600 /* Sessions are thrown out after no contact for this many seconds. 0 = no timeout */
+ #define TNFS_HEADERSZ 4 /* minimum header size */
+ #define TNFS_MAX_PAYLOAD (MAXMSGSZ - TNFS_HEADERSZ - 1) /* Maximum usuable payload in a UDP datagram (-1 for status byte) */
+diff -Naur tnfsd-23.0207.1_95c5b55/datagram.c tnfsd-23.0207.1_95c5b55.patched/datagram.c
+--- tnfsd-23.0207.1_95c5b55/datagram.c 2023-02-08 13:35:32.000000000 -0500
++++ tnfsd-23.0207.1_95c5b55.patched/datagram.c 2023-02-08 13:40:57.701262001 -0500
+@@ -50,7 +50,6 @@
+ #include "tnfs_file.h"
+
+ int sockfd; /* UDP global socket file descriptor */
+-int tcplistenfd; /* TCP listening socket file descriptor */
+
+ tnfs_cmdfunc dircmd[NUM_DIRCMDS] =
+ {&tnfs_opendir, &tnfs_readdir, &tnfs_closedir,
+@@ -141,23 +140,6 @@
+ if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
+ die("Unable to bind");
+
+- /* Create the TCP socket */
+- tcplistenfd = socket(AF_INET, SOCK_STREAM, 0);
+- if (tcplistenfd < 0)
+- {
+- die("Unable to create TCP socket");
+- }
+-
+- memset(&servaddr, 0, sizeof(servaddr));
+- servaddr.sin_family = AF_INET;
+- servaddr.sin_addr.s_addr = htons(INADDR_ANY);
+- servaddr.sin_port = htons(TNFSD_PORT);
+- if (bind(tcplistenfd, (struct sockaddr *)&servaddr,
+- sizeof(servaddr)) < 0)
+- {
+- die("Unable to bind TCP socket");
+- }
+- listen(tcplistenfd, 5);
+ }
+
+ void tnfs_mainloop()
+@@ -165,25 +147,13 @@
+ int readyfds, i;
+ fd_set fdset;
+ fd_set errfdset;
+- int tcpsocks[MAX_TCP_CONN];
+-
+- memset(&tcpsocks, 0, sizeof(tcpsocks));
+
+ while (1)
+ {
+ FD_ZERO(&fdset);
+
+- /* add UDP socket and TCP listen socket to fdset */
++ /* add UDP socket to fdset */
+ FD_SET(sockfd, &fdset);
+- FD_SET(tcplistenfd, &fdset);
+-
+- for (i = 0; i < MAX_TCP_CONN; i++)
+- {
+- if (tcpsocks[i])
+- {
+- FD_SET(tcpsocks[i], &fdset);
+- }
+- }
+
+ FD_COPY(&fdset, &errfdset);
+ if ((readyfds = select(FD_SETSIZE, &fdset, NULL, &errfdset, NULL)) != 0)
+@@ -199,55 +169,10 @@
+ {
+ tnfs_handle_udpmsg();
+ }
+- /* Incoming TCP connection? */
+- else if (FD_ISSET(tcplistenfd, &fdset))
+- {
+- tcp_accept(&tcpsocks[0]);
+- }
+- else
+- {
+- for (i = 0; i < MAX_TCP_CONN; i++)
+- {
+- if (tcpsocks[i])
+- {
+- if (FD_ISSET(tcpsocks[i], &fdset))
+- {
+- tnfs_handle_tcpmsg(tcpsocks[i]);
+- }
+- }
+- }
+- }
+ }
+ }
+ }
+
+-void tcp_accept(int *socklist)
+-{
+- int acc_fd, i;
+- struct sockaddr_in cli_addr;
+- socklen_t cli_len = sizeof(cli_addr);
+- int *fdptr;
+-
+- acc_fd = accept(tcplistenfd, (struct sockaddr *)&cli_addr, &cli_len);
+- if (acc_fd < 1)
+- {
+- fprintf(stderr, "WARNING: unable to accept TCP connection\n");
+- return;
+- }
+-
+- fdptr = socklist;
+- for (i = 0; i < MAX_TCP_CONN; i++)
+- {
+- if (*fdptr == 0)
+- {
+- *fdptr = acc_fd;
+- return;
+- }
+- }
+-
+- /* tell the client 'too many connections' */
+-}
+-
+ void tnfs_handle_udpmsg()
+ {
+ socklen_t len;
+@@ -273,15 +198,6 @@
+ *(rxbuf + rxbytes) = 0;
+ }
+
+-void tnfs_handle_tcpmsg(int cli_fd)
+-{
+- char buf[255];
+- int sz;
+-
+- sz = read(cli_fd, buf, sizeof(buf));
+- printf("DEBUG: rx of tcpmsg: %d bytes: %s\n", sz, buf);
+-}
+-
+ void tnfs_decode(struct sockaddr_in *cliaddr, int rxbytes, unsigned char *rxbuf)
+ {
+ Header hdr;
+diff -Naur tnfsd-23.0207.1_95c5b55/datagram.h tnfsd-23.0207.1_95c5b55.patched/datagram.h
+--- tnfsd-23.0207.1_95c5b55/datagram.h 2023-02-08 13:35:32.000000000 -0500
++++ tnfsd-23.0207.1_95c5b55.patched/datagram.h 2023-02-08 13:39:55.229267881 -0500
+@@ -51,8 +51,6 @@
+ void tnfs_sockinit();
+ void tnfs_mainloop();
+ void tnfs_handle_udpmsg();
+-void tcp_accept(int *fdlist);
+-void tnfs_handle_tcpmsg(int cli_fd);
+ void tnfs_decode(struct sockaddr_in *cliaddr,
+ int rxbytes, unsigned char *rxbuf);
+ void tnfs_invalidsession(Header *hdr);
+diff -Naur tnfsd-23.0207.1_95c5b55/tnfs.h tnfsd-23.0207.1_95c5b55.patched/tnfs.h
+--- tnfsd-23.0207.1_95c5b55/tnfs.h 2023-02-08 13:35:32.000000000 -0500
++++ tnfsd-23.0207.1_95c5b55.patched/tnfs.h 2023-02-08 13:40:15.637265960 -0500
+@@ -136,7 +136,6 @@
+ #endif
+ int lastmsgsz; /* last message's size inc. hdr */
+ uint8_t lastseqno; /* last sequence number */
+- uint8_t isTCP; /* uses the TCP transport */
+ } Session;
+
+ typedef struct _header
diff --git a/network/tnfsd/slack-desc b/network/tnfsd/slack-desc
new file mode 100644
index 0000000000..267872fd63
--- /dev/null
+++ b/network/tnfsd/slack-desc
@@ -0,0 +1,19 @@
+# HOW TO EDIT THIS FILE:
+# The "handy ruler" below makes it easier to edit a package description.
+# Line up the first '|' above the ':' following the base package name, and
+# the '|' on the right side marks the last column you can put a character in.
+# You must make exactly 11 lines for the formatting to be correct. It's also
+# customary to leave one space after the ':' except on otherwise blank lines.
+
+ |-----handy-ruler------------------------------------------------------|
+tnfsd: tnfsd (trivial network filesystem server)
+tnfsd:
+tnfsd: TNFS is a simplified Internet file transfer protocol, designed for
+tnfsd: simplicity and ease of implementation on small systems, such as 8-bit
+tnfsd: computers. It's simpler than NFS, SMB, or FTP. It's similar to TFTP,
+tnfsd: but has features TFTP lacks.
+tnfsd:
+tnfsd: TNFS uses UDP port 16384, so make sure you allow incoming traffic if
+tnfsd: you have firewall rules.
+tnfsd:
+tnfsd:
diff --git a/network/tnfsd/tnfsd.1 b/network/tnfsd/tnfsd.1
new file mode 100644
index 0000000000..b8f41d2ed7
--- /dev/null
+++ b/network/tnfsd/tnfsd.1
@@ -0,0 +1,103 @@
+.\" Man page generated from reStructuredText.
+.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.TH "TNFSD" 1 "2023-02-08" "23.0207.1_95c5b55" "SlackBuilds.org"
+.SH NAME
+tnfsd \- trivial network filesystem daemon
+.\" RST source for tnfsd(1) man page. Convert with:
+.
+.\" rst2man.py tnfsd.rst > tnfsd.1
+.
+.SH SYNOPSIS
+.sp
+tnfsd \fBdirectory\fP [\fB\-c\fP \fIusername\fP]
+.SH DESCRIPTION
+.sp
+TNFS is a simplified Internet file transfer protocol, designed for
+simplicity and ease of implementation on small systems, such as 8\-bit
+computers. It\(aqs simpler than NFS, SMB, or FTP. It\(aqs similar to TFTP,
+but has features TFTP lacks.
+.sp
+\fBtnfsd\fP is the server for the TNFS protocol. It listens for clients
+on UDP port 16384. In theory, the protocol supports TCP connections,
+but this hasn\(aqt been implemented yet.
+.sp
+The mandatory \fBdirectory\fP option is the root of the TNFS filesystem
+tree.
+.sp
+The \fB\-c\fP \fIusername\fP option requires \fBtnfsd\fP to be run as
+\fIroot\fP\&. If given, \fBtnfsd\fP will \fBchroot\fP(2) to the \fIdirectory\fP,
+then drop its root privileges and run as the \fIusername\fP user instead.
+.sp
+Even without \fBchroot\fP, \fBtnfsd\fP will not deliberately allow access
+to files outside the \fIdirectory\fP\&. The \fB\-c\fP option is a safety net,
+in case there\(aqs a bug in \fBtnfsd\fP that allows such access (currently,
+no such bug is known of).
+.sp
+Note that \fBtnfsd\fP can be started by a normal user, since it uses an
+unprivileged UDP port. The \fB\-c\fP option won\(aqt work in this case.
+.sp
+\fBtnfsd\fP logs various information to standard error. If compiled with
+\fI\-DUSAGE_LOG\fP, the log includes all mount, umount, and file transfer
+requests including the client IP addresses.
+.SH LIMITATIONS
+.sp
+\fBtnfsd\fP is designed to be simple, so the following list of
+limitations should not be read as complaints or feature requests.
+.sp
+There is no way to run multiple \fBtnfsd\fP instances on the same
+host, not even on a multi\-homed host. The default UDP port cannot
+be changed; neither can the IP address used for binding (which is
+\fI0.0.0.0\fP, aka \fIINADDR_ANY\fP). Also, there\(aqs no concept of virtual
+hosts. If you \fIreally\fP want to run multiple instances, use containers
+or virtual machines.
+.sp
+There\(aqs no way to limit which hosts may access \fBtnfsd\fP using any
+mechanism such as \fBtcpd\fP(8). Firewall rules may be used instead,
+e.g. \fBiptables\fP(8).
+.sp
+There isn\(aqt a way to share a directory read\-only with the current
+\fBtnfsd\fP implementation. However, filesystem permissions can be used
+to prevent the daemon from writing to the shared directory.
+.SH COPYRIGHT
+.sp
+See the file /usr/doc/tnfsd\-23.0207.1_95c5b55/COPYING for license information.
+.SH AUTHORS
+.sp
+tnfsd was written by Dylan Smith.
+.sp
+This man page written for the SlackBuilds.org project
+by B. Watson, and is licensed under the WTFPL.
+.SH SEE ALSO
+.sp
+\fBtnfs\-fuse\fP(1), \fBfujinet\-pc\fP(1)
+.sp
+/usr/doc/tnfsd\-23.0207.1_95c5b55/tnfs\-protocol.md
+.\" Generated by docutils manpage writer.
+.
diff --git a/network/tnfsd/tnfsd.SlackBuild b/network/tnfsd/tnfsd.SlackBuild
new file mode 100644
index 0000000000..cc841748c9
--- /dev/null
+++ b/network/tnfsd/tnfsd.SlackBuild
@@ -0,0 +1,144 @@
+#!/bin/bash
+
+# Slackware build script for tnfsd
+
+# Written by B. Watson (urchlay@slackware.uk)
+
+# Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
+
+# 20230208 bkw: update for v23.0207.1_95c5b55.
+# - this is a security update, see:
+# https://forums.atariage.com/topic/347648-tnfsd-directory-listing-vulnerability/
+# - use self-hosted source, with the non-tnfsd-related stuff removed.
+
+# 20220818 bkw: BUILD=2
+# - remove TCP support entirely. it's incomplete & thoroughly broken.
+# - mention UDP port 16384 in slack-desc.
+
+# Note to self: tnfs-perl/tnfsd.pl looks interesting, but it lacks
+# the ability to chroot and set a new user ID. Leave it out of
+# the package. The tnfs-fuseclient/ is empty except a README, and
+# tnfsd.test/ looks like an ancient version from 2010.
+
+cd $(dirname $0) ; CWD=$(pwd)
+
+PRGNAM=tnfsd
+VERSION=${VERSION:-23.0207.1_95c5b55}
+BUILD=${BUILD:-1}
+TAG=${TAG:-_SBo}
+PKGTYPE=${PKGTYPE:-tgz}
+
+if [ -z "$ARCH" ]; then
+ case "$( uname -m )" in
+ i?86) ARCH=i586 ;;
+ arm*) ARCH=arm ;;
+ *) ARCH=$( uname -m ) ;;
+ esac
+fi
+
+if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
+ echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
+ exit 0
+fi
+
+uid_gid_err() {
+ cat <<EOF
+Before running this SlackBuild, you must create the tnfsd user and
+the tnfsd and tnfs-files groups. Use these commands:
+
+ groupadd -g 375 tnfsd
+ groupadd -g 376 tnfs-files
+ useradd -u 375 -d /var/tnfs -c "TNFS Daemon User" \
+ -M -g tnfsd tnfsd -s /bin/false
+EOF
+ exit 1
+}
+
+chkgrp() {
+ getent group "$1" &>/dev/null || uid_gid_err
+}
+
+chkuser() {
+ getent passwd "$1" &>/dev/null || uid_gid_err
+}
+
+chkgrp tnfsd
+chkgrp tnfs-files
+chkuser tnfsd
+
+TMP=${TMP:-/tmp/SBo}
+PKG=$TMP/package-$PRGNAM
+OUTPUT=${OUTPUT:-/tmp}
+
+if [ "$ARCH" = "i586" ]; then
+ SLKCFLAGS="-O2 -march=i586 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=i686 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -fPIC"
+ LIBDIRSUFFIX="64"
+else
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
+fi
+
+set -e
+
+rm -rf $PKG
+mkdir -p $TMP $PKG $OUTPUT
+cd $TMP
+rm -rf $PRGNAM-$VERSION
+tar xvf $CWD/$PRGNAM-$VERSION.tar.xz
+cd $PRGNAM-$VERSION
+chown -R root:root .
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
+
+# 20220818 bkw: After messing with this for a while, I've discovered
+# that TCP *just doesn't work*. It'll listen and accept TCP
+# connections, but it never actually *does* anything with data
+# received via TCP (reads and discards it). Also, it never notices
+# when a TCP connection is closed, instead getting stuck in an
+# infinite loop eating 100% of one core... and logging massive
+# amounts of debug messages to stdout (like 2-3GB per minute). Since
+# it's non-functional anyway, this patch just dikes out TCP support
+# completely. So far as I know, there are no TNFS clients which use
+# TCP anyway.
+# 20230208 bkw: reworked this patch for the new source.
+patch -p1 < $CWD/remove_broken_tcp_support.diff
+
+[ "${USAGELOG:-yes}" = "yes" ] && SLKCFLAGS+=" -DUSAGELOG"
+sed -i "s,-Wall,& $SLKCFLAGS," Makefile
+mkdir -p bin
+make OS=LINUX
+
+PKGDOC=$PKG/usr/doc/$PRGNAM-$VERSION
+PKGBIN=$PKG/usr/bin
+PKGMAN1=$PKG/usr/man/man1
+PKGRCD=$PKG/etc/rc.d
+PKGVAR=$PKG/var/tnfs
+mkdir -p $PKGDOC $PKGBIN $PKGMAN1 $PKGRCD $PKGVAR
+install -s -m0755 bin/tnfsd $PKGBIN/tnfsd
+cp -a *.md *.txt $PKGDOC
+cat $CWD/$PRGNAM.SlackBuild > $PKGDOC/$PRGNAM.SlackBuild
+
+mkdir -p $PKGVAR
+chown root:tnfs-files $PKGVAR
+chmod 1775 $PKGVAR
+
+# upstream license only exists in C comments, so I included this:
+cat $CWD/COPYING > $PKGDOC/COPYING
+
+# man page written for this SlackBuild.
+gzip -9c < $CWD/$PRGNAM.1 > $PKGMAN1/$PRGNAM.1.gz
+
+install -oroot -groot -m0755 $CWD/rc.$PRGNAM $PKGRCD/rc.$PRGNAM.new
+
+mkdir -p $PKG/install
+cat $CWD/slack-desc > $PKG/install/slack-desc
+cat $CWD/doinst.sh > $PKG/install/doinst.sh
+
+cd $PKG
+/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE
diff --git a/network/tnfsd/tnfsd.info b/network/tnfsd/tnfsd.info
new file mode 100644
index 0000000000..a8cb27219e
--- /dev/null
+++ b/network/tnfsd/tnfsd.info
@@ -0,0 +1,10 @@
+PRGNAM="tnfsd"
+VERSION="23.0207.1_95c5b55"
+HOMEPAGE="https://github.com/FujiNetWIFI/spectranet/"
+DOWNLOAD="https://slackware.uk/~urchlay/src/tnfsd-23.0207.1_95c5b55.tar.xz"
+MD5SUM="667313c10c9d809e33ad58c6a59998b7"
+DOWNLOAD_x86_64=""
+MD5SUM_x86_64=""
+REQUIRES=""
+MAINTAINER="B. Watson"
+EMAIL="urchlay@slackware.uk"
diff --git a/network/tnfsd/tnfsd.rst b/network/tnfsd/tnfsd.rst
new file mode 100644
index 0000000000..23dcb6b28b
--- /dev/null
+++ b/network/tnfsd/tnfsd.rst
@@ -0,0 +1,95 @@
+.. RST source for tnfsd(1) man page. Convert with:
+.. rst2man.py tnfsd.rst > tnfsd.1
+
+.. |version| replace:: 23.0207.1_95c5b55
+.. |date| date::
+
+=====
+tnfsd
+=====
+
+---------------------------------
+trivial network filesystem daemon
+---------------------------------
+
+:Manual section: 1
+:Manual group: SlackBuilds.org
+:Date: |date|
+:Version: |version|
+
+SYNOPSIS
+========
+
+tnfsd **directory** [**-c** *username*]
+
+DESCRIPTION
+===========
+
+TNFS is a simplified Internet file transfer protocol, designed for
+simplicity and ease of implementation on small systems, such as 8-bit
+computers. It's simpler than NFS, SMB, or FTP. It's similar to TFTP,
+but has features TFTP lacks.
+
+**tnfsd** is the server for the TNFS protocol. It listens for clients
+on UDP port 16384. In theory, the protocol supports TCP connections,
+but this hasn't been implemented yet.
+
+The mandatory **directory** option is the root of the TNFS filesystem
+tree.
+
+The **-c** *username* option requires **tnfsd** to be run as
+*root*. If given, **tnfsd** will **chroot**\(2) to the *directory*,
+then drop its root privileges and run as the *username* user instead.
+
+Even without **chroot**, **tnfsd** will not deliberately allow access
+to files outside the *directory*. The **-c** option is a safety net,
+in case there's a bug in **tnfsd** that allows such access (currently,
+no such bug is known of).
+
+Note that **tnfsd** can be started by a normal user, since it uses an
+unprivileged UDP port. The **-c** option won't work in this case.
+
+**tnfsd** logs various information to standard error. If compiled with
+*-DUSAGE_LOG*, the log includes all mount, umount, and file transfer
+requests including the client IP addresses.
+
+LIMITATIONS
+===========
+
+**tnfsd** is designed to be simple, so the following list of
+limitations should not be read as complaints or feature requests.
+
+There is no way to run multiple **tnfsd** instances on the same
+host, not even on a multi-homed host. The default UDP port cannot
+be changed; neither can the IP address used for binding (which is
+*0.0.0.0*, aka *INADDR_ANY*). Also, there's no concept of virtual
+hosts. If you *really* want to run multiple instances, use containers
+or virtual machines.
+
+There's no way to limit which hosts may access **tnfsd** using any
+mechanism such as **tcpd**\(8). Firewall rules may be used instead,
+e.g. **iptables**\(8).
+
+There isn't a way to share a directory read-only with the current
+**tnfsd** implementation. However, filesystem permissions can be used
+to prevent the daemon from writing to the shared directory.
+
+COPYRIGHT
+=========
+
+See the file /usr/doc/tnfsd-|version|/COPYING for license information.
+
+AUTHORS
+=======
+
+tnfsd was written by Dylan Smith.
+
+This man page written for the SlackBuilds.org project
+by B. Watson, and is licensed under the WTFPL.
+
+SEE ALSO
+========
+
+**tnfs-fuse**\(1), **fujinet-pc**\(1)
+
+/usr/doc/tnfsd-|version|/tnfs-protocol.md