From 4812da3f2f3cd205225726f4742764e92b8a4bc0 Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Tue, 29 Jul 2025 18:06:12 +0200 Subject: [PATCH] proof of concept qotd server --- .gitignore | 2 ++ flake.lock | 27 ++++++++++++++++ flake.nix | 37 +++++++++++++++++++++ main.ua | 17 ++++++++++ main.uasm | 47 +++++++++++++++++++++++++++ nix/module.nix | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ nix/package.nix | 54 +++++++++++++++++++++++++++++++ quotes | 30 +++++++++++++++++ result | 1 + test | 0 10 files changed, 301 insertions(+) create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 main.ua create mode 100644 main.uasm create mode 100644 nix/module.nix create mode 100644 nix/package.nix create mode 100644 quotes create mode 120000 result create mode 100644 test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96dd39d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.uasm +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..8a9da88 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1753694789, + "narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "dc9637876d0dcc8c9e5e22986b857632effeb727", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e061171 --- /dev/null +++ b/flake.nix @@ -0,0 +1,37 @@ +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = { self, nixpkgs }: + let + inherit (nixpkgs) lib; + + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + forAllSystems = f: lib.genAttrs systems (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in f system pkgs); + in { + devShells = forAllSystems (system: pkgs: { + default = pkgs.mkShell { + nativeBuildInputs = [ + pkgs.uiua + ]; + }; + }); + + packages = forAllSystems (system: pkgs: { + default = pkgs.callPackage ./nix/package.nix {}; + }); + + overlays.default = final: prev: { + qotd = self.packages.${prev.system}.default; + }; + + nixosModules.default = ./nix/module.nix; + }; +} diff --git a/main.ua b/main.ua new file mode 100644 index 0000000..4633cfd --- /dev/null +++ b/main.ua @@ -0,0 +1,17 @@ +# find qotd + +&fras &var "QOTD_QUOTES_PATH" +⊜□¬ ⦷"\n\n---\n\n". +°□⊡⊸(⌊×⚂⧻) +q ← + +# continuously wait for connection + +# &tcpl "127.0.0.1:0017" +# &p "listening on localhost:10017" +# ⍢( +# ⍜&tcpa(&w q). +# )1 +# &cl + +&pf q diff --git a/main.uasm b/main.uasm new file mode 100644 index 0000000..7a3ae45 --- /dev/null +++ b/main.uasm @@ -0,0 +1,47 @@ +"quotes" +["f_read_all_str",1] +"\n\n---\n\n" +["SPLIT_BY",[[1,1,["BOX",6]]],5] +[["DUP",11],["LEN",7],["RAND",8],["MUL",9],["FLOOR",10]] +["PICK",12] +["UN_BOX",13] +{"bind_global":[0,15]} +"127.0.0.1:10017" +["tcp_listen",16] +"listening on localhost:10017" +["print",17] +["DO",[[1,1,[["DUP",19],["tcp_accept",20],{"copy_to_under":[1,20]},{"call_global":[0,[0,1]]},["write",21],{"pop_under":[1,20]},["close",20]]],[0,1,[[],[1],{"flags":"SORTED_UP | SORTED_DOWN"}]]],18] +["close",23] + +BINDINGS +const null + +FUNCTIONS + +SPANS +"main.ua" [3,1,13,13] [3,6,18,18] +"main.ua" [4,19,53,46] [4,20,54,47] +"main.ua" [4,5,37,32] [4,6,40,33] +"main.ua" [4,3,34,30] [4,4,36,31] +"main.ua" [4,1,28,28] [4,2,31,29] +"main.ua" [4,2,31,29] [4,3,34,30] +"main.ua" [5,9,75,56] [5,10,78,57] +"main.ua" [5,8,72,55] [5,9,75,56] +"main.ua" [5,7,70,54] [5,8,72,55] +"main.ua" [5,6,67,53] [5,7,70,54] +"main.ua" [5,4,63,51] [5,5,66,52] +"main.ua" [5,3,60,50] [5,4,63,51] +"main.ua" [5,2,57,49] [5,3,60,50] +"main.ua" [5,1,55,48] [5,2,57,49] +"main.ua" [6,1,80,59] [6,2,81,60] +"main.ua" [10,1,123,100] [10,6,128,105] +"main.ua" [11,1,147,124] [11,3,149,126] +"main.ua" [12,1,181,158] [12,2,184,159] +"main.ua" [13,15,202,175] [13,16,203,176] +"main.ua" [13,4,191,164] [13,9,196,169] +"main.ua" [13,10,197,170] [13,12,199,172] +"main.ua" [13,3,188,163] [13,4,191,164] +"main.ua" [15,1,207,180] [15,4,210,183] + +FILES +main.ua: "# find qotd\n\n&fras \"quotes\"\n⊜□¬ ⦷\"\\n\\n---\\n\\n\".\n°□⊡⊸(⌊×⚂⧻)\nq ←\n\n# continuously wait for connection\n\n&tcpl \"127.0.0.1:10017\"\n&p \"listening on localhost:10017\"\n⍢(\n ⍜&tcpa(&w q).\n)1\n&cl\n" diff --git a/nix/module.nix b/nix/module.nix new file mode 100644 index 0000000..5099721 --- /dev/null +++ b/nix/module.nix @@ -0,0 +1,86 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.services.qotd; +in +{ + options.services.qotd = { + enable = lib.mkEnableOption "Enable qotd"; + + package = lib.mkPackageOption pkgs "qotd" { }; + + quotes = lib.mkOption { + description = ""; + type = lib.types.listOf lib.types.str; + default = []; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services."qotd@" = { + description = "qotd"; + environment.QOTD_QUOTES_PATH = lib.pipe cfg.quotes [ + # (map (x: x + "\n")) + (lib.concatStringsSep "\n\n---\n\n") + (pkgs.writeText "qotd-db.txt") + ]; + serviceConfig = { + Type = "simple"; + ExecStart = "${lib.getExe pkgs.uiua} run ${cfg.package}/bin/.main.uasm"; + + User = "qotd"; + DynamicUser = true; + + PrivateUsers = true; + PrivateNetwork = false; + + StandardOutput = "socket"; + + # IPAddressDeny = + # lib.optionals (lib.elem cfg.settings.mysql.host [ null "localhost" "127.0.0.1" ]) [ "any" ]; + + # RestrictAddressFamilies = [ "AF_UNIX" ] + # ++ (lib.optionals (cfg.settings.mysql.host != null) [ "AF_INET" "AF_INET6" ]); + + # AmbientCapabilities = [ "" ]; + # CapabilityBoundingSet = [ "" ]; + # DeviceAllow = [ "" ]; + # LockPersonality = true; + # MemoryDenyWriteExecute = true; + # NoNewPrivileges = true; + # PrivateDevices = true; + # PrivateMounts = true; + # PrivateTmp = "yes"; + # ProcSubset = "pid"; + # ProtectClock = true; + # ProtectControlGroups = true; + # ProtectHome = true; + # ProtectHostname = true; + # ProtectKernelLogs = true; + # ProtectKernelModules = true; + # ProtectKernelTunables = true; + # ProtectProc = "invisible"; + # ProtectSystem = "strict"; + # RemoveIPC = true; + # UMask = "0777"; + # RestrictNamespaces = true; + # RestrictRealtime = true; + # RestrictSUIDSGID = true; + # SystemCallArchitectures = "native"; + # SocketBindDeny = [ "any" ]; + # SystemCallFilter = [ + # "@system-service" + # "~@privileged" + # "~@resources" + # ]; + }; + }; + + systemd.sockets."qotd" = { + wantedBy = [ "sockets.target" ]; + socketConfig = { + ListenStream = 17; + Accept = "yes"; + }; + }; + }; +} diff --git a/nix/package.nix b/nix/package.nix new file mode 100644 index 0000000..00fbfb0 --- /dev/null +++ b/nix/package.nix @@ -0,0 +1,54 @@ +{ + lib +, uiua +, stdenvNoCC +, runtimeShell +}: + +stdenvNoCC.mkDerivation { + pname = "qotd"; + version = "unstable"; + + src = builtins.filterSource (path: type: let + baseName = baseNameOf (toString path); + in !(lib.any (b: b) [ + (!(lib.cleanSourceFilter path type)) + (type == "directory" && lib.elem baseName [ + ".direnv" + ".git" + ".jj" + "target" + "result" + ]) + (type == "regular" && lib.elem baseName [ + "flake.nix" + "flake.lock" + "default.nix" + "module.nix" + ".envrc" + ]) + (type == "regular" && lib.hasSuffix ".uasm" baseName) + ])) ./..; + + nativeBuildInputs = [ uiua ]; + + buildPhase = '' + runHook preBuild + uiua build --output .main.uasm main.ua + runHook postBuild + ''; + + wrapper = '' + #!${runtimeShell} + "${uiua}"/bin/uiua run ${placeholder "out"}/bin/.main.uasm + ''; + + passAsFile = [ "wrapper" ]; + + installPhase = '' + runHook preInstall + install -Dm444 .main.uasm -t "$out"/bin + install -Dm555 "$wrapperPath" "$out"/bin/qotd + runHook postInstall + ''; +} diff --git a/quotes b/quotes new file mode 100644 index 0000000..332e06f --- /dev/null +++ b/quotes @@ -0,0 +1,30 @@ +hello this is a quote + +--- + +this is also a quote + +--- + +new +quote +of +the +day! + +--- + +nice good stuff + +--- + +im writing +a + +novel here + +witness it + +--- + +neat \ No newline at end of file diff --git a/result b/result new file mode 120000 index 0000000..8887b83 --- /dev/null +++ b/result @@ -0,0 +1 @@ +/nix/store/s5d4lav4mz1j2mv7zjdc5bkrvsi0f6rs-qotd-unstable \ No newline at end of file diff --git a/test b/test new file mode 100644 index 0000000..e69de29