summary refs log tree commit diff
diff options
context:
space:
mode:
authorLain Iwakura <lain@lainmail.xyz>2026-01-04 04:01:15 +0300
committerLain Iwakura <lain@lainmail.xyz>2026-01-04 04:01:15 +0300
commitff4598371937c94db6b792ed42afa241b1e1f35c (patch)
tree1fba1edb95456b9385a65704b37f331a7fe3a3a7
parentSupport reading gzipped data in merge (diff)
downloadtorus-ff4598371937c94db6b792ed42afa241b1e1f35c.tar.gz
torus-ff4598371937c94db6b792ed42afa241b1e1f35c.zip
feat(main): linux patches
-rw-r--r--client.c9
-rwxr-xr-xdeploy.sh68
-rw-r--r--image.c2
-rw-r--r--server.c2
-rw-r--r--torusbac.pl78
5 files changed, 155 insertions, 4 deletions
diff --git a/client.c b/client.c
index be43641..b08f820 100644
--- a/client.c
+++ b/client.c
@@ -15,6 +15,7 @@
  */
 
 #define _XOPEN_SOURCE_EXTENDED
+#define _GNU_SOURCE
 
 #include <assert.h>
 #include <curses.h>
@@ -47,7 +48,7 @@ enum {
 	Del = 0x7F,
 };
 
-static uint32_t log2(uint32_t n) {
+static uint32_t log2u(uint32_t n) {
 	assert(n > 0);
 	return 32 - __builtin_clz(n) - 1;
 }
@@ -198,10 +199,10 @@ static void serverMap(void) {
 			struct Meta meta = map.meta[y][x];
 
 			uint32_t count = 0;
-			if (meta.modifyCount && log2(map.max.modifyCount)) {
+			if (meta.modifyCount && log2u(map.max.modifyCount)) {
 				count = DIV_ROUND(
-					(ARRAY_LEN(MapCells) - 1) * log2(meta.modifyCount),
-					log2(map.max.modifyCount)
+					(ARRAY_LEN(MapCells) - 1) * log2u(meta.modifyCount),
+					log2u(map.max.modifyCount)
 				);
 			}
 			uint32_t time = 0;
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..0f92cad
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+set -e
+CHROOT_USER=torus
+CHROOT_GROUP=torus
+INSTALL_DIR=/opt/torus
+HOME_DIR=/home/torus
+SOCK_PATH=$HOME_DIR/torus.sock
+DATA_PATH=$HOME_DIR/torus.dat
+PID_PATH=/var/run/torus.pid
+if [ "$EUID" -ne 0 ]; then 
+    exit 1
+fi
+if ! id "$CHROOT_USER" &>/dev/null; then
+    useradd -r -m -s /bin/bash "$CHROOT_USER"
+fi
+passwd -d "$CHROOT_USER" 2>/dev/null || usermod -p "" "$CHROOT_USER"
+mkdir -p "$INSTALL_DIR"
+mkdir -p "$HOME_DIR"
+mkdir -p /var/www/ascii.town
+cp -f client server image merge meta "$INSTALL_DIR/"
+chmod +x "$INSTALL_DIR"/*
+if [ -f default8x16.psfu ]; then
+    mkdir -p "$HOME_DIR/usr/share/torus"
+    cp -f default8x16.psfu "$HOME_DIR/usr/share/torus/"
+fi
+if [ -f explore.html ] && [ -f index.html ]; then
+    cp -f explore.html index.html /var/www/ascii.town/
+    chown -R "$CHROOT_USER:$CHROOT_GROUP" /var/www/ascii.town
+fi
+chown -R "$CHROOT_USER:$CHROOT_GROUP" "$HOME_DIR"
+chown -R "$CHROOT_USER:$CHROOT_GROUP" "$INSTALL_DIR"
+cat > /etc/systemd/system/torus.service << EOF
+[Unit]
+Description=Torus ASCII Art Server
+After=network.target
+
+[Service]
+Type=forking
+User=$CHROOT_USER
+Group=$CHROOT_GROUP
+ExecStart=$INSTALL_DIR/server -d $DATA_PATH -p $PID_PATH -s $SOCK_PATH
+Restart=always
+RestartSec=10
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+if ! grep -q "Match User $CHROOT_USER" /etc/ssh/sshd_config; then
+    cat >> /etc/ssh/sshd_config << EOF
+
+Match User $CHROOT_USER
+	PasswordAuthentication yes
+	PermitEmptyPasswords yes
+	ForceCommand $INSTALL_DIR/client -s $SOCK_PATH
+	DisableForwarding yes
+	MaxSessions 1
+EOF
+else
+fi
+
+echo "--------------------------------"
+echo "passwd -d $CHROOT_USER"
+echo "systemctl restart sshd"
+echo "systemctl enable --now torus"
+echo "systemctl status torus"
\ No newline at end of file
diff --git a/image.c b/image.c
index 584eb4c..0977405 100644
--- a/image.c
+++ b/image.c
@@ -14,6 +14,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define _GNU_SOURCE
+
 #include <err.h>
 #include <fcntl.h>
 #include <stdbool.h>
diff --git a/server.c b/server.c
index 3c26f09..0d6e317 100644
--- a/server.c
+++ b/server.c
@@ -14,6 +14,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define _GNU_SOURCE
+
 #include <assert.h>
 #include <err.h>
 #include <errno.h>
diff --git a/torusbac.pl b/torusbac.pl
new file mode 100644
index 0000000..ac5f34a
--- /dev/null
+++ b/torusbac.pl
@@ -0,0 +1,78 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use POSIX qw(strftime);
+use File::Basename;
+
+my $DATA_FILE = '/home/torus/torus.dat';
+my $COPYPARTY_URL = '';
+my $COPYPARTY_PASS = '';
+my $BACKUP_DIR = '/tmp/torus_backups';
+
+$COPYPARTY_PASS = $ENV{COPYPARTY_PASS} if $ENV{COPYPARTY_PASS} && !$COPYPARTY_PASS;
+
+unless (-f $DATA_FILE) {
+    die "Data file not found: $DATA_FILE\n";
+}
+
+mkdir $BACKUP_DIR unless -d $BACKUP_DIR;
+
+my $timestamp = strftime('%Y.%m.%d.%H.%M', localtime);
+my $backup_file = "$BACKUP_DIR/torus.dat.$timestamp";
+my $meta_file = "$BACKUP_DIR/torus.csv.$timestamp";
+
+print "Creating backup: $backup_file\n";
+open my $data_in, '<', $DATA_FILE or die "Failed to open data file: $!\n";
+open my $backup_out, '>', $backup_file or die "Failed to create backup: $!\n";
+while (my $chunk = read($data_in, my $buf, 4096)) {
+    print $backup_out $buf;
+}
+close $data_in;
+close $backup_out;
+
+print "Creating metadata backup: $meta_file\n";
+open $data_in, '<', $DATA_FILE or die "Failed to open data file: $!\n";
+open my $meta_proc, '|-', "/opt/torus/meta > '$meta_file' 2>/dev/null" or die "Failed to open meta: $!\n";
+while (read($data_in, my $tile, 4096)) {
+    print $meta_proc $tile;
+}
+close $data_in;
+close $meta_proc;
+
+print "Compressing files...\n";
+system('gzip', '-9', '-f', $backup_file) == 0 or die "Failed to gzip backup\n";
+system('gzip', '-9', '-f', $meta_file) == 0 or die "Failed to gzip meta\n";
+
+$backup_file .= '.gz';
+$meta_file .= '.gz';
+
+my $url = $COPYPARTY_URL;
+$url .= '/' unless $url =~ m{/$};
+if ($COPYPARTY_PASS) {
+    $url .= "?pw=$COPYPARTY_PASS";
+}
+
+for my $file ($backup_file, $meta_file) {
+    my $basename = basename($file);
+    print "Uploading $basename to copyparty...\n";
+
+    my $cmd = "curl -X POST '$url' " .
+              "-F 'f=\@$file' ";
+
+    if ($COPYPARTY_PASS) {
+        $cmd .= "-H 'PW: $COPYPARTY_PASS' ";
+    }
+
+    $cmd .= "--silent --show-error --fail --max-time 600";
+
+    my $result = system($cmd);
+    if ($result == 0) {
+        print "Successfully uploaded $basename\n";
+        unlink $file or warn "Failed to delete $file: $!\n";
+    } else {
+        my $exit_code = $result >> 8;
+        warn "Failed to upload $basename (exit code: $exit_code)\n";
+    }
+}
+
+print "Backup completed\n";